Added status changing information

This commit is contained in:
Patrick Fic
2020-02-06 16:33:23 -08:00
parent f00ae5335f
commit d422edcb0e
15 changed files with 176 additions and 18 deletions

View File

@@ -420,6 +420,37 @@
</folder_node>
</children>
</folder_node>
<folder_node>
<name>bodyshop</name>
<children>
<folder_node>
<name>errors</name>
<children>
<concept_node>
<name>loading</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
</children>
</folder_node>
<folder_node>
<name>documents</name>
<children>
@@ -1069,6 +1100,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>changestatus</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>convert</name>
<definition_loaded>false</definition_loaded>

View File

@@ -28,14 +28,15 @@ const mapDispatchToProps = dispatch => ({
export default connect(
mapStateToProps,
mapDispatchToProps
)(({ checkUserSession, currentUser }) => {
)(({ checkUserSession, currentUser, setBodyshop }) => {
useEffect(() => {
checkUserSession();
return () => {};
}, [checkUserSession]);
if (false)
i18next.changeLanguage("en_US", (err, t) => {
if (currentUser && currentUser.language)
i18next.changeLanguage(currentUser.language, (err, t) => {
if (err)
return console.log("Error encountered when changing languages.", err);
});

View File

@@ -1,26 +1,41 @@
import {
Avatar,
Badge,
Button,
Checkbox,
Descriptions,
Dropdown,
Icon,
Menu,
notification,
PageHeader,
Tag,
Badge
Tag
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import Moment from "react-moment";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import CarImage from "../../assets/car.svg";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
export default function JobsDetailHeader({
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
export default connect(
mapStateToProps,
null
)(function JobsDetailHeader({
job,
mutationConvertJob,
refetch,
handleSubmit,
scheduleModalState
scheduleModalState,
bodyshop,
updateJobStatus
}) {
const { t } = useTranslation();
const setscheduleModalVisible = scheduleModalState[1];
@@ -60,7 +75,26 @@ export default function JobsDetailHeader({
</div>
);
const statusmenu = (
<Menu
onClick={e => {
updateJobStatus({
variables: { jobId: job.id, status: e.key }
}).then(r => refetch());
}}
>
{bodyshop.md_ro_statuses.statuses.map(item => (
<Menu.Item key={item}>{item}</Menu.Item>
))}
</Menu>
);
const menuExtra = [
<Dropdown overlay={statusmenu} key="changestatus">
<Button>
{t("jobs.actions.changestatus")} <Icon type="down" />
</Button>
</Dropdown>,
<Badge key="schedule" count={job.appointments_aggregate.aggregate.count}>
<Button
//TODO: Enabled logic based on status.
@@ -138,4 +172,4 @@ export default function JobsDetailHeader({
</Descriptions>
</PageHeader>
);
}
});

View File

@@ -19,6 +19,7 @@ export const QUERY_BODYSHOP = gql`
state_tax_id
updated_at
zip_post
region_config
}
}
`;

View File

@@ -321,3 +321,13 @@ export const INSERT_NEW_JOB = gql`
}
}
`;
export const UPDATE_JOB_STATUS = gql`
mutation UPDATE_JOB_STATUS($jobId: uuid!, $status: String!) {
update_jobs(where: { id: { _eq: $jobId } }, _set: { status: $status }) {
returning {
id
}
}
}
`;

View File

@@ -24,7 +24,8 @@ export default function JobsDetailPage({
mutationConvertJob,
handleSubmit,
refetch,
scheduleModalState
scheduleModalState,
updateJobStatus
}) {
const { t } = useTranslation();
@@ -55,6 +56,7 @@ export default function JobsDetailPage({
refetch={refetch}
handleSubmit={handleSubmit}
scheduleModalState={scheduleModalState}
updateJobStatus={updateJobStatus}
/>
{isFieldsTouched() ? (

View File

@@ -7,7 +7,8 @@ import SpinComponent from "../../components/loading-spinner/loading-spinner.comp
import {
CONVERT_JOB_TO_RO,
GET_JOB_BY_PK,
UPDATE_JOB
UPDATE_JOB,
UPDATE_JOB_STATUS
} from "../../graphql/jobs.queries";
import JobsDetailPage from "./jobs-detail.page.component";
import JobDetailFormContext from "./jobs-detail.page.context";
@@ -24,7 +25,7 @@ function JobsDetailPageContainer({ match, form }) {
});
const [mutationUpdateJob] = useMutation(UPDATE_JOB);
const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO);
const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS);
useEffect(() => {
document.title = loading
? t("titles.app")
@@ -74,6 +75,7 @@ function JobsDetailPageContainer({ match, form }) {
getFieldDecorator={form.getFieldDecorator}
refetch={refetch}
scheduleModalState={scheduleModalState}
updateJobStatus={updateJobStatus}
/>
</JobDetailFormContext.Provider>
) : (

View File

@@ -1,15 +1,21 @@
import { BackTop, Layout } from "antd";
import { BackTop, Layout, notification } from "antd";
import React, { lazy, Suspense, useEffect } from "react";
import { useTranslation } from "react-i18next";
//This page will handle all routing for the entire application.
import { connect } from "react-redux";
import { Route } from "react-router";
import { createStructuredSelector } from "reselect";
import { useQuery } from "react-apollo";
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
import FooterComponent from "../../components/footer/footer.component";
//Component Imports
import HeaderContainer from "../../components/header/header.container";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
//const WhiteBoardPage = lazy(() => import("../white-board/white-board.page"));
import { setBodyshop } from "../../redux/user/user.actions";
import "./manage.page.styles.scss";
//const WhiteBoardPage = lazy(() => import("../white-board/white-board.page"));
const ManageRootPage = lazy(() =>
import("../manage-root/manage-root.page.container")
);
@@ -32,10 +38,27 @@ const ScheduleContainer = lazy(() =>
);
const { Header, Content, Footer } = Layout;
//This page will handle all routing for the entire application.
export default function Manage({ match }) {
const mapDispatchToProps = dispatch => ({
setBodyshop: bs => dispatch(setBodyshop(bs))
});
export default connect(
null,
mapDispatchToProps
)(function Manage({ match, setBodyshop }) {
const { t } = useTranslation();
const { error, data } = useQuery(QUERY_BODYSHOP, {
fetchPolicy: "network-only"
});
if (error) {
notification["error"]({ message: t("bodyshop.errors.loading") });
}
if (data) {
setBodyshop(data.bodyshops[0]);
}
useEffect(() => {
document.title = t("titles.app");
}, [t]);
@@ -96,4 +119,4 @@ export default function Manage({ match }) {
<BackTop />
</Layout>
);
}
});

View File

@@ -48,3 +48,8 @@ export const updateUserDetailsSuccess = userDetails => ({
type: UserActionTypes.UPDATE_USER_DETAILS_SUCCESS,
payload: userDetails
});
export const setBodyshop = bodyshop => ({
type: UserActionTypes.SET_SHOP_DETAILS,
payload: bodyshop
});

View File

@@ -3,8 +3,9 @@ import UserActionTypes from "./user.types";
const INITIAL_STATE = {
currentUser: {
authorized: null,
language: "en_US"
language: "en_us"
},
bodyshop: null,
error: null
};
@@ -41,6 +42,9 @@ const userReducer = (state = INITIAL_STATE, action) => {
...action.payload //Spread current user details in.
}
};
case UserActionTypes.SET_SHOP_DETAILS:
return { ...state, bodyshop: action.payload };
case UserActionTypes.SIGN_IN_FAILURE:
case UserActionTypes.SIGN_OUT_FAILURE:
case UserActionTypes.EMAIL_SIGN_UP_FAILURE:

View File

@@ -11,3 +11,8 @@ export const selectSignInError = createSelector(
[selectUser],
user => user.error
);
export const selectBodyshop = createSelector(
[selectUser],
user => user.bodyshop
);

View File

@@ -14,6 +14,7 @@ const UserActionTypes = {
UNAUTHORIZED_USER: "UNAUTHORIZED_USER",
SET_USER_LANGUAGE: "SET_USER_LANGUAGE",
UPDATE_USER_DETAILS: "UPDATE_USER_DETAILS",
UPDATE_USER_DETAILS_SUCCESS: "UPDATE_USER_DETAILS_SUCCESS"
UPDATE_USER_DETAILS_SUCCESS: "UPDATE_USER_DETAILS_SUCCESS",
SET_SHOP_DETAILS: "SET_SHOP_DETAILS"
};
export default UserActionTypes;

View File

@@ -35,6 +35,11 @@
"actions": "Actions"
}
},
"bodyshop": {
"errors": {
"loading": "Unable to load shop details. Please call technical support."
}
},
"documents": {
"errors": {
"deletes3": "Error deleting document from storage. ",
@@ -87,6 +92,7 @@
"actions": {
"addDocuments": "Add Job Documents",
"addNote": "Add Note",
"changestatus": "Change Status",
"convert": "Convert",
"postInvoices": "Post Invoices",
"printCenter": "Print Center",

View File

@@ -35,6 +35,11 @@
"actions": "Comportamiento"
}
},
"bodyshop": {
"errors": {
"loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico."
}
},
"documents": {
"errors": {
"deletes3": "Error al eliminar el documento del almacenamiento.",
@@ -87,6 +92,7 @@
"actions": {
"addDocuments": "Agregar documentos de trabajo",
"addNote": "Añadir la nota",
"changestatus": "Cambiar Estado",
"convert": "Convertir",
"postInvoices": "Contabilizar facturas",
"printCenter": "Centro de impresión",

View File

@@ -35,6 +35,11 @@
"actions": "actes"
}
},
"bodyshop": {
"errors": {
"loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique."
}
},
"documents": {
"errors": {
"deletes3": "Erreur lors de la suppression du document du stockage.",
@@ -87,6 +92,7 @@
"actions": {
"addDocuments": "Ajouter des documents de travail",
"addNote": "Ajouter une note",
"changestatus": "Changer le statut",
"convert": "Convertir",
"postInvoices": "Poster des factures",
"printCenter": "Centre d'impression",