From 69690f01849a992fdaa4f4a95e9478f3bd3d2fc6 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Wed, 17 Nov 2021 15:29:04 -0800 Subject: [PATCH] IO-1533 Kanban Customizations --- bodyshop_translations.babel | 84 ++++++ ...production-board-kanban-card.component.jsx | 272 +++++++++++++----- ...n-board-kanban.card-settings.component.jsx | 175 ++++++++--- .../production-board-kanban.component.jsx | 25 +- .../production-board-kanban.styles.scss | 25 +- ...p-info.responsibilitycenters.component.jsx | 2 +- client/src/translations/en_us/common.json | 6 +- client/src/translations/es/common.json | 6 +- client/src/translations/fr/common.json | 6 +- client/src/utils/DateFormatter.jsx | 4 +- 10 files changed, 467 insertions(+), 138 deletions(-) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index b4dfcbf2a..2456b19d5 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -34872,6 +34872,27 @@ + + settings + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -35003,6 +35024,27 @@ + + compact + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + detailpriority false @@ -35024,6 +35066,27 @@ + + employeeassignments + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + employeesearch false @@ -35066,6 +35129,27 @@ + + laborhrs + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + note false diff --git a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx index ec803dbe8..b48c09e22 100644 --- a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx +++ b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx @@ -1,14 +1,13 @@ -import React from "react"; -import { Card, Row, Col, Dropdown } from "antd"; +import { EyeFilled, CalendarOutlined } from "@ant-design/icons"; +import { Card, Col, Row, Space, Typography } from "antd"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; import { DateTimeFormatter } from "../../utils/DateFormatter"; import ProductionAlert from "../production-list-columns/production-list-columns.alert.component"; -import { EyeFilled } from "@ant-design/icons"; -import { Link } from "react-router-dom"; -import "./production-board-card.styles.scss"; -import ProductionRemoveButton from "../production-remove-button/production-remove-button.component"; -import { useTranslation } from "react-i18next"; -import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component"; import ProductionListColumnProductionNote from "../production-list-columns/production-list-columns.productionnote.component"; +import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component"; +import "./production-board-card.styles.scss"; export default function ProductionBoardCard( technician, @@ -17,13 +16,7 @@ export default function ProductionBoardCard( cardSettings ) { const { t } = useTranslation(); - const menu = ( -
- - - -
- ); + const [flipped, setFlipped] = useState(false); let employee_body, employee_prep, employee_refinish, employee_csr; if (card.employee_body) { employee_body = bodyshop.employees.find((e) => e.id === card.employee_body); @@ -41,36 +34,62 @@ export default function ProductionBoardCard( } return ( - - + setFlipped(!flipped)} + > +
+ + {card.ro_number || t("general.labels.na")} + + + {cardSettings && cardSettings.alert && ( + + )} + {technician ? ( + + + + ) : ( + + + + )} + +
+ {flipped ? ( - -
{`${card.ownr_fn || ""} ${ - card.ownr_ln || "" - } ${card.ownr_co_nm || ""}`}
- -
- - -
{card.clm_no || ""}
- - -
{card.ins_co_nm || ""}
- -
- - -
-
+ {cardSettings && cardSettings.clm_no === "back" && ( + +
{card.clm_no || ""}
+ + )} + {cardSettings && cardSettings.ins_co_nm === "back" && ( + +
{card.ins_co_nm || ""}
+ + )} + {cardSettings && cardSettings.laborhrs === "back" && ( + +
{`B: ${card.labhrs.aggregate.sum.mod_lb_hrs || "?"}`}
{`R: ${card.larhrs.aggregate.sum.mod_lb_hrs || "?"}`}
-
-
+ + + )} + {cardSettings && cardSettings.employeeassignments === "back" && ( + +
{`B: ${ employee_body ? `${employee_body.first_name} ${employee_body.last_name}` @@ -91,35 +110,146 @@ export default function ProductionBoardCard( ? `${employee_csr.first_name} ${employee_csr.last_name}` : "" }`}
-
-
- -
- - - {card.scheduled_completion} - - -
{card.alt_transport || ""}
- -
-
- -
-
- - - {technician ? ( - - - - ) : ( - - - + + )} -
-
-
+ {cardSettings && cardSettings.scheduled_completion === "back" && ( + + + + + {card.scheduled_completion} + + + + )} + {cardSettings && cardSettings.ats === "back" && ( + + +
{card.alt_transport || ""}
+ + + )} + + {cardSettings && cardSettings.sublets === "back" && ( + + + + )} + {cardSettings && cardSettings.production_note === "back" && ( + + {cardSettings && cardSettings.production_note === "back" && ( + + )} + + )} + + ) : ( + + + {cardSettings && cardSettings.compact ? ( +
{`${card.ownr_ln || ""} ${ + card.ownr_co_nm || "" + }`}
+ ) : ( +
{`${card.ownr_ln || ""}, ${ + card.ownr_fn || "" + } ${card.ownr_co_nm || ""}`}
+ )} + + +
{`${card.v_model_yr || ""} ${ + card.v_make_desc || "" + } ${card.v_model_desc || ""}`}
+ + + {cardSettings && cardSettings.clm_no === "front" && ( + +
{card.clm_no || ""}
+ + )} + {cardSettings && cardSettings.ins_co_nm === "front" && ( + +
{card.ins_co_nm || ""}
+ + )} + {cardSettings && cardSettings.laborhrs === "front" && ( + + +
{`B: ${card.labhrs.aggregate.sum.mod_lb_hrs || "?"}`}
+
{`R: ${card.larhrs.aggregate.sum.mod_lb_hrs || "?"}`}
+
+ + )} + {cardSettings && cardSettings.employeeassignments === "front" && ( + + +
{`B: ${ + employee_body + ? `${employee_body.first_name} ${employee_body.last_name}` + : "" + }`}
+
{`P: ${ + employee_prep + ? `${employee_prep.first_name} ${employee_prep.last_name}` + : "" + }`}
+
{`R: ${ + employee_refinish + ? `${employee_refinish.first_name} ${employee_refinish.last_name}` + : "" + }`}
+
{`CSR: ${ + employee_csr + ? `${employee_csr.first_name} ${employee_csr.last_name}` + : "" + }`}
+
+ + )} + {cardSettings && cardSettings.scheduled_completion === "front" && ( + + + + + {card.scheduled_completion} + + + + )} + {cardSettings && cardSettings.ats === "front" && ( + +
{card.alt_transport || ""}
+ + )} + {cardSettings && cardSettings.sublets === "front" && ( + + + + )} + {cardSettings && cardSettings.production_note === "front" && ( + + {cardSettings && cardSettings.production_note === "front" && ( + + )} + + )} +
+ )} + ); } diff --git a/client/src/components/production-board-kanban/production-board-kanban.card-settings.component.jsx b/client/src/components/production-board-kanban/production-board-kanban.card-settings.component.jsx index c8c595100..9ae6666a1 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.card-settings.component.jsx +++ b/client/src/components/production-board-kanban/production-board-kanban.card-settings.component.jsx @@ -1,6 +1,16 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Dropdown, Form, Switch } from "antd"; -import React, { useEffect } from "react"; +import { + Button, + Card, + Col, + Form, + notification, + Popover, + Radio, + Row, + Switch, +} from "antd"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_KANBAN_SETTINGS } from "../../graphql/user.queries"; @@ -8,70 +18,149 @@ export default function ProductionBoardKanbanCardSettings({ associationSettings, }) { const [form] = Form.useForm(); + const [visible, setVisible] = useState(false); + const [loading, setLoading] = useState(false); const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS); + useEffect(() => { form.setFieldsValue( associationSettings && associationSettings.kanban_settings ); - }, [form, associationSettings]); + }, [form, associationSettings, visible]); const { t } = useTranslation(); const handleFinish = async (values) => { - await updateKbSettings({ + setLoading(true); + const result = await updateKbSettings({ variables: { id: associationSettings && associationSettings.id, ks: values, }, }); + if (result.errors) { + notification.open({ + type: "error", + message: t("production.errors.settings", { + error: JSON.stringify(result.errors), + }), + }); + } + setVisible(false); + setLoading(false); }; const overlay = (
-
- - - - - - - - - - - - - - - + + + + + + + + + Front + Back + Off + + + + + Front + Back + Off + + + + + Front + Back + Off + + + + + Front + Back + Off + + + + + Front + Back + Off + + {" "} + + + + + Front + Back + Off + + + + + Front + Back + Off + + + + + Front + Back + Off + + + + + Front + Back + Off + + + +
+
); return ( - - - + + + ); } diff --git a/client/src/components/production-board-kanban/production-board-kanban.component.jsx b/client/src/components/production-board-kanban/production-board-kanban.component.jsx index 6ec3e5155..4423a23fe 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.component.jsx +++ b/client/src/components/production-board-kanban/production-board-kanban.component.jsx @@ -18,6 +18,7 @@ import { selectTechnician } from "../../redux/tech/tech.selectors"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import ProductionBoardKanbanCardSettings from "./production-board-kanban.card-settings.component"; +import styled from "styled-components"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -145,8 +146,26 @@ export function ProductionBoardKanbanComponent({ ) .toFixed(1); + const Container = styled.div` + .react-kanban-card-skeleton, + .react-kanban-card, + .react-kanban-card-adder-form { + box-sizing: border-box; + max-width: ${associationSettings && + associationSettings.kanban_settings && + associationSettings.kanban_settings.compact + ? "145" + : "250"}px; + min-width: ${associationSettings && + associationSettings.kanban_settings && + associationSettings.kanban_settings.compact + ? "145" + : "250"}px; + } + `; + return ( -
+ -
+ ); } export default connect( diff --git a/client/src/components/production-board-kanban/production-board-kanban.styles.scss b/client/src/components/production-board-kanban/production-board-kanban.styles.scss index a6e4533dc..b705994bf 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.styles.scss +++ b/client/src/components/production-board-kanban/production-board-kanban.styles.scss @@ -4,23 +4,16 @@ .react-kanban-card { border-radius: 3px; background-color: #fff; - padding: 10px; + padding: 4px; margin-bottom: 7px; } -.react-kanban-card-skeleton, -.react-kanban-card, -.react-kanban-card-adder-form { - box-sizing: border-box; - max-width: 250px; - min-width: 250px; -} -.react-kanban-card-skeleton-compact, -.react-kanban-card-compact, -.react-kanban-card-adder-form-compact { - box-sizing: border-box; - max-width: 120px; - min-width: 120px; -} +// .react-kanban-card-skeleton, +// .react-kanban-card, +// .react-kanban-card-adder-form { +// box-sizing: border-box; +// max-width: 145px; +// min-width: 145px; +// } .react-kanban-card--dragging { box-shadow: 2px 2px grey; @@ -36,7 +29,7 @@ justify-content: space-between; } .react-kanban-column { - padding: 15px; + padding: 10px; border-radius: 2px; background-color: #eee; margin: 5px; diff --git a/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx b/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx index 3468e3c17..0dc49cf15 100644 --- a/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx +++ b/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx @@ -1385,7 +1385,7 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) { }, ({ getFieldValue }) => ({ validator(rule, value) { - if (costOptions.includes(value)) { + if (profitOptions.includes(value)) { return Promise.resolve(); } return Promise.reject( diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 6a62aabc9..7b7f6ea0a 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -2078,7 +2078,8 @@ }, "errors": { "boardupdate": "Error encountered updating job. {{message}}", - "removing": "Error removing from production board. {{error}}" + "removing": "Error removing from production board. {{error}}", + "settings": "Error saving board settings: {{error}}" }, "labels": { "alert": "Alert", @@ -2087,9 +2088,12 @@ "bodyhours": "B", "bodypriority": "B/P", "cardsettings": "Card Settings", + "compact": "Compact Cards", "detailpriority": "D/P", + "employeeassignments": "Employee Assignments", "employeesearch": "Employee Search", "jobdetail": "Job Details", + "laborhrs": "Labor Hours", "note": "Production Note", "paintpriority": "P/P", "refinishhours": "R", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 90540ba32..574d37980 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -2078,7 +2078,8 @@ }, "errors": { "boardupdate": "", - "removing": "" + "removing": "", + "settings": "" }, "labels": { "alert": "", @@ -2087,9 +2088,12 @@ "bodyhours": "", "bodypriority": "", "cardsettings": "", + "compact": "", "detailpriority": "", + "employeeassignments": "", "employeesearch": "", "jobdetail": "", + "laborhrs": "", "note": "", "paintpriority": "", "refinishhours": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 01479d025..1adff188e 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -2078,7 +2078,8 @@ }, "errors": { "boardupdate": "", - "removing": "" + "removing": "", + "settings": "" }, "labels": { "alert": "", @@ -2087,9 +2088,12 @@ "bodyhours": "", "bodypriority": "", "cardsettings": "", + "compact": "", "detailpriority": "", + "employeeassignments": "", "employeesearch": "", "jobdetail": "", + "laborhrs": "", "note": "", "paintpriority": "", "refinishhours": "", diff --git a/client/src/utils/DateFormatter.jsx b/client/src/utils/DateFormatter.jsx index 9452e67bc..18c2e633d 100644 --- a/client/src/utils/DateFormatter.jsx +++ b/client/src/utils/DateFormatter.jsx @@ -12,7 +12,9 @@ export function DateFormatter(props) { export function DateTimeFormatter(props) { return props.children - ? moment(props.children).format("MM/DD/YYYY hh:mm a") + ? moment(props.children).format( + props.format ? props.format : "MM/DD/YYYY hh:mm a" + ) : null; }