From c90cccb6bebfcc90cc5d322deebdafc53e9d4a27 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 20 Feb 2020 10:38:07 -0800 Subject: [PATCH 01/14] Added bulk assignment. Added partial parts order line remarks capability. --- bodyshop_translations.babel | 42 ++++++++++++ .../allocations-assignment.container.jsx | 1 - .../allocations-bulk-assignment.component.jsx | 66 +++++++++++++++++++ .../allocations-bulk-assignment.container.jsx | 46 +++++++++++++ .../chat-window/chat-window.styles.scss | 2 +- .../job-detail-lines/job-lines.component.jsx | 20 ++++-- .../jobs-available-supplement.container.jsx | 8 +-- .../parts-order-modal.component.jsx | 35 ++++++++-- .../parts-order-modal.container.jsx | 60 +++++++++-------- client/src/translations/en_us/common.json | 4 +- client/src/translations/es/common.json | 4 +- client/src/translations/fr/common.json | 4 +- 12 files changed, 245 insertions(+), 47 deletions(-) create mode 100644 client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.component.jsx create mode 100644 client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 0a097dcfb..268434fa7 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -5979,6 +5979,27 @@ + + lineremarks + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -6005,6 +6026,27 @@ + + inthisorder + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + print false diff --git a/client/src/components/allocations-assignment/allocations-assignment.container.jsx b/client/src/components/allocations-assignment/allocations-assignment.container.jsx index 434f71ecb..914312109 100644 --- a/client/src/components/allocations-assignment/allocations-assignment.container.jsx +++ b/client/src/components/allocations-assignment/allocations-assignment.container.jsx @@ -24,7 +24,6 @@ export default function AllocationsAssignmentContainer({ notification["success"]({ message: t("employees.successes.save") }); - //TODO Better way to reset the field decorators? visibilityState[1](false); if (refetch) refetch(); }); diff --git a/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.component.jsx b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.component.jsx new file mode 100644 index 000000000..5a926cd79 --- /dev/null +++ b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.component.jsx @@ -0,0 +1,66 @@ +import { Button, Popover, Select } from "antd"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop +}); + +export default connect( + mapStateToProps, + null +)(function AllocationsBulkAssignmentComponent({ + bodyshop, + handleAssignment, + assignment, + setAssignment, + visibilityState +}) { + const { t } = useTranslation(); + + const onChange = e => { + console.log("e", e); + setAssignment({ ...assignment, employeeid: e }); + }; + + const [visibility, setVisibility] = visibilityState; + + const popContent = ( +
+ + + + +
+ ); + + return ( + + + + ); +}); diff --git a/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx new file mode 100644 index 000000000..0b73b2cb0 --- /dev/null +++ b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx @@ -0,0 +1,46 @@ +import React, { useState } from "react"; +import AllocationsBulkAssignment from "./allocations-bulk-assignment.component"; +import { useMutation } from "react-apollo"; +import { INSERT_ALLOCATION } from "../../graphql/allocations.queries"; +import { useTranslation } from "react-i18next"; +import { notification } from "antd"; + +export default function AllocationsBulkAssignmentContainer({ + jobLines, + refetch +}) { + const visibilityState = useState(false); + const { t } = useTranslation(); + const [assignment, setAssignment] = useState({ + employeeid: null + }); + const [insertAllocation] = useMutation(INSERT_ALLOCATION); + + const handleAssignment = () => { + const allocs = jobLines.reduce((acc, value) => { + acc.push({ + joblineid: value.id, + hours: parseFloat(value.mod_lb_hrs) || 0, + employeeid: assignment.employeeid + }); + return acc; + }, []); + + insertAllocation({ variables: { alloc: allocs } }).then(r => { + notification["success"]({ + message: t("employees.successes.save") + }); + visibilityState[1](false); + if (refetch) refetch(); + }); + }; + + return ( + + ); +} diff --git a/client/src/components/chat-window/chat-window.styles.scss b/client/src/components/chat-window/chat-window.styles.scss index 1b68074fb..a7e128649 100644 --- a/client/src/components/chat-window/chat-window.styles.scss +++ b/client/src/components/chat-window/chat-window.styles.scss @@ -20,7 +20,7 @@ .messages ul li { display: inline-block; clear: both; - float: left; + //float: left; margin: 5px 15px 5px 15px; width: calc(100% - 25px); font-size: 0.9em; diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 0b11301b3..9ff03410f 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -6,7 +6,7 @@ import { alphaSort } from "../../utils/sorters"; //import EditableCell from "./job-lines-cell.component"; import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; - +import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container"; export default function JobLinesComponent({ loading, refetch, @@ -166,11 +166,13 @@ export default function JobLinesComponent({ return (
- + {partsOrderModalVisible[0] ? ( + + ) : null} { @@ -188,13 +190,17 @@ export default function JobLinesComponent({ onClick={() => setPartsModalVisible(true)}> {t("parts.actions.order")} + ); }} {...formItemLayout} loading={loading} size='small' - pagination={{ position: "bottom", defaultPageSize: 50 }} + pagination={{ position: "top", defaultPageSize: 25 }} rowSelection={{ // selectedRowKeys: selectedLines, onSelect: (record, selected, selectedRows, nativeEvent) => diff --git a/client/src/components/jobs-available-supplement/jobs-available-supplement.container.jsx b/client/src/components/jobs-available-supplement/jobs-available-supplement.container.jsx index e9c189aa0..5f0469cdb 100644 --- a/client/src/components/jobs-available-supplement/jobs-available-supplement.container.jsx +++ b/client/src/components/jobs-available-supplement/jobs-available-supplement.container.jsx @@ -54,12 +54,13 @@ export default withRouter(function JobsAvailableSupplementContainer({ //create upsert job let supp = estData.data.available_jobs_by_pk.est_data; delete supp.joblines; + //TODO How to update the estimate lines. delete supp.owner; delete supp.vehicle; if (!importOptions.overrideHeaders) { delete supp["ins_ea"]; - //Strip out the header options + //TODO Remove all required fields. } updateJob({ @@ -101,12 +102,11 @@ export default withRouter(function JobsAvailableSupplementContainer({ setSelectedJob(null); }; - if (error) return ; + if (error) return ; return ( + message={t("jobs.labels.creating_new_job")}> { - console.log("value", value); - console.log("option", option); setPartsOrder({ ...partsOrder, vendorid: option.key }); }; @@ -52,6 +52,33 @@ export default function PartsOrderModalComponent({ }} /> + {t("parts_orders.labels.inthisorder")} + + ( + + //TODO Editable table/adding line remarks to the order. + ]}> + { + // + // } + // title={{item.name.last}} + // description='Ant Design, a design language for background applications, is refined by Ant UED Team' + // /> + } +
{`${item.line_desc}${ + item.oem_partno ? " | " + item.oem_partno : "" + }`}
+
+ )} + /> + setSendType(e.target.value)}> diff --git a/client/src/components/parts-order-modal/parts-order-modal.container.jsx b/client/src/components/parts-order-modal/parts-order-modal.container.jsx index 06cccf380..bd775f8f4 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.container.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.container.jsx @@ -1,18 +1,18 @@ import { Modal, notification } from "antd"; import React, { useState } from "react"; -import { useQuery, useMutation } from "react-apollo"; +import { useMutation, useQuery } from "react-apollo"; +import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import { QUERY_ALL_VENDORS_FOR_ORDER } from "../../graphql/vendors.queries"; import { INSERT_NEW_PARTS_ORDERS } from "../../graphql/parts-orders.queries"; +import { QUERY_ALL_VENDORS_FOR_ORDER } from "../../graphql/vendors.queries"; import { - selectCurrentUser, - selectBodyshop + selectBodyshop, + selectCurrentUser } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import PartsOrderModalComponent from "./parts-order-modal.component"; -import { useTranslation } from "react-i18next"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -28,23 +28,40 @@ export default connect( currentUser, bodyshop }) { - const [modalVisible, setModalVisible] = partsOrderModalVisible; - const { loading, error, data } = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, { - fetchPolicy: "network-only", - skip: !modalVisible - }); const { t } = useTranslation(); - const [insertPartOrder] = useMutation(INSERT_NEW_PARTS_ORDERS); - const sendTypeState = useState("e"); + const [modalVisible, setModalVisible] = partsOrderModalVisible; + //set order lines to be a version of the incoming lines. + const orderLinesState = useState( + linesToOrder.reduce((acc, value) => { + acc.push({ + line_desc: value.line_desc, + oem_partno: value.oem_partno, + db_price: value.db_price, + act_price: value.act_price, + line_remarks: "Alalala", + joblineid: value.joblineid, + status: bodyshop.md_order_statuses.default_ordered || "Ordered*" + }); + return acc; + }, []) + ); + const orderLines = orderLinesState[0]; + + const sendTypeState = useState("e"); const partsOrderState = useState({ vendorid: null, jobid: jobId, user_email: currentUser.email }); - - console.log("sendTypeState[0]", sendTypeState[0]); const partsOrder = partsOrderState[0]; + + const { loading, error, data } = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, { + fetchPolicy: "network-only", + skip: !modalVisible + }); + const [insertPartOrder] = useMutation(INSERT_NEW_PARTS_ORDERS); + const handleOk = () => { insertPartOrder({ variables: { @@ -53,19 +70,7 @@ export default connect( ...partsOrder, status: bodyshop.md_order_statuses.default_ordered || "Ordered*", parts_order_lines: { - data: linesToOrder.reduce((acc, value) => { - acc.push({ - line_desc: value.line_desc, - oem_partno: value.oem_partno, - db_price: value.db_price, - act_price: value.act_price, - line_remarks: "Alalala", - joblineid: value.joblineid, - status: - bodyshop.md_order_statuses.default_ordered || "Ordered*" - }); - return acc; - }, []) + data: orderLines } } ] @@ -96,6 +101,7 @@ export default connect( vendorList={(data && data.vendors) || []} state={partsOrderState} sendTypeState={sendTypeState} + orderLinesState={orderLinesState} />
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 70a7a1959..f8df11c07 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -385,10 +385,12 @@ "creating": "Error encountered when creating parts order. " }, "fields": { - "deliver_by": "Deliver By" + "deliver_by": "Deliver By", + "lineremarks": "Line Remarks" }, "labels": { "email": "Send by Email", + "inthisorder": "Parts in this Order", "print": "Show Printed Form" }, "successes": { diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 270442c45..e93c6be9e 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -385,10 +385,12 @@ "creating": "Se encontró un error al crear el pedido de piezas." }, "fields": { - "deliver_by": "Entregado por" + "deliver_by": "Entregado por", + "lineremarks": "Comentarios de línea" }, "labels": { "email": "Enviar por correo electrónico", + "inthisorder": "Partes en este pedido", "print": "Mostrar formulario impreso" }, "successes": { diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index e64421219..e37f04001 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -385,10 +385,12 @@ "creating": "Erreur rencontrée lors de la création de la commande de pièces." }, "fields": { - "deliver_by": "Livrer par" + "deliver_by": "Livrer par", + "lineremarks": "Remarques sur la ligne" }, "labels": { "email": "Envoyé par email", + "inthisorder": "Pièces dans cette commande", "print": "Afficher le formulaire imprimé" }, "successes": { From b845e620700c07a61f7a2cc1629f1a2b02b31752 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 20 Feb 2020 11:52:41 -0800 Subject: [PATCH 02/14] Added est line status + expandable row for previous orders on jobs lines detail --- bodyshop_translations.babel | 42 ++++++++++ .../job-detail-lines/job-lines.component.jsx | 24 ++++++ .../parts-order-modal.container.jsx | 30 ++++++-- client/src/graphql/jobs-lines.queries.js | 22 ++++++ client/src/translations/en_us/common.json | 2 + client/src/translations/es/common.json | 2 + client/src/translations/fr/common.json | 2 + .../down.yaml | 5 ++ .../up.yaml | 5 ++ .../down.yaml | 75 ++++++++++++++++++ .../up.yaml | 76 +++++++++++++++++++ .../down.yaml | 73 ++++++++++++++++++ .../up.yaml | 74 ++++++++++++++++++ .../down.yaml | 75 ++++++++++++++++++ .../up.yaml | 76 +++++++++++++++++++ 15 files changed, 577 insertions(+), 6 deletions(-) create mode 100644 hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/down.yaml create mode 100644 hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/up.yaml create mode 100644 hasura/migrations/1582224725146_update_permission_user_public_table_joblines/down.yaml create mode 100644 hasura/migrations/1582224725146_update_permission_user_public_table_joblines/up.yaml create mode 100644 hasura/migrations/1582224730652_update_permission_user_public_table_joblines/down.yaml create mode 100644 hasura/migrations/1582224730652_update_permission_user_public_table_joblines/up.yaml create mode 100644 hasura/migrations/1582224737046_update_permission_user_public_table_joblines/down.yaml create mode 100644 hasura/migrations/1582224737046_update_permission_user_public_table_joblines/up.yaml diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 268434fa7..711a56d3a 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -1707,6 +1707,27 @@ + + status + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + unq_seq false @@ -6047,6 +6068,27 @@ + + orderhistory + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + print false diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 9ff03410f..f2c7e54c2 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -3,6 +3,7 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { alphaSort } from "../../utils/sorters"; +import { Link } from "react-router-dom"; //import EditableCell from "./job-lines-cell.component"; import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; @@ -111,6 +112,14 @@ export default function JobLinesComponent({ sortOrder: state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order }, + { + title: t("joblines.fields.status"), + dataIndex: "status", + key: "status", + sorter: (a, b) => alphaSort(a.status, b.status), + sortOrder: + state.sortedInfo.columnKey === "status" && state.sortedInfo.order + }, { title: t("allocations.fields.employee"), dataIndex: "employee", @@ -170,6 +179,7 @@ export default function JobLinesComponent({ ) : null} @@ -200,6 +210,20 @@ export default function JobLinesComponent({ {...formItemLayout} loading={loading} size='small' + expandedRowRender={record => ( +
+ {t("parts_orders.labels.orderhistory")} + {record.parts_order_lines.map(item => ( +
+ {`${item.parts_order.order_number || ""} from `} + + {item.parts_order.vendor.name || ""} + + {` on ${item.parts_order.order_date || ""}`} +
+ ))} +
+ )} pagination={{ position: "top", defaultPageSize: 25 }} rowSelection={{ // selectedRowKeys: selectedLines, diff --git a/client/src/components/parts-order-modal/parts-order-modal.container.jsx b/client/src/components/parts-order-modal/parts-order-modal.container.jsx index bd775f8f4..3200890dc 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.container.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.container.jsx @@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_NEW_PARTS_ORDERS } from "../../graphql/parts-orders.queries"; +import { UPDATE_JOB_LINE_STATUS } from "../../graphql/jobs-lines.queries"; import { QUERY_ALL_VENDORS_FOR_ORDER } from "../../graphql/vendors.queries"; import { selectBodyshop, @@ -26,7 +27,8 @@ export default connect( linesToOrder, jobId, currentUser, - bodyshop + bodyshop, + refetch }) { const { t } = useTranslation(); const [modalVisible, setModalVisible] = partsOrderModalVisible; @@ -40,7 +42,7 @@ export default connect( db_price: value.db_price, act_price: value.act_price, line_remarks: "Alalala", - joblineid: value.joblineid, + job_line_id: value.id, status: bodyshop.md_order_statuses.default_ordered || "Ordered*" }); return acc; @@ -61,6 +63,7 @@ export default connect( skip: !modalVisible }); const [insertPartOrder] = useMutation(INSERT_NEW_PARTS_ORDERS); + const [updateJobLines] = useMutation(UPDATE_JOB_LINE_STATUS); const handleOk = () => { insertPartOrder({ @@ -77,10 +80,25 @@ export default connect( } }) .then(r => { - notification["success"]({ - message: t("parts_orders.successes.created") - }); - setModalVisible(false); + updateJobLines({ + variables: { + ids: linesToOrder.map(item => item.id), + status: bodyshop.md_order_statuses.default_ordered || "Ordered*" + } + }) + .then(response => { + notification["success"]({ + message: t("parts_orders.successes.created") + }); + if (refetch) refetch(); + setModalVisible(false); + }) + .catch(error => { + notification["error"]({ + message: t("parts_orders.errors.creating"), + description: error.message + }); + }); }) .catch(error => { notification["error"]({ diff --git a/client/src/graphql/jobs-lines.queries.js b/client/src/graphql/jobs-lines.queries.js index 5efd5ccd0..ea3c2f9dc 100644 --- a/client/src/graphql/jobs-lines.queries.js +++ b/client/src/graphql/jobs-lines.queries.js @@ -18,6 +18,20 @@ export const GET_JOB_LINES_BY_PK = gql` lbr_op lbr_amt op_code_desc + status + parts_order_lines { + id + parts_order { + id + order_number + order_date + user_email + vendor { + id + name + } + } + } allocations { id hours @@ -30,3 +44,11 @@ export const GET_JOB_LINES_BY_PK = gql` } } `; + +export const UPDATE_JOB_LINE_STATUS = gql` + mutation UPDATE_JOB_LINE_STATUS($ids: [uuid!]!, $status: String!) { + update_joblines(where: { id: { _in: $ids } }, _set: { status: $status }) { + affected_rows + } + } +`; diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index f8df11c07..ea981ec14 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -135,6 +135,7 @@ "mod_lb_hrs": "Labor Hours", "oem_partno": "OEM Part #", "part_type": "Part Type", + "status": "Status", "unq_seq": "Seq #" } }, @@ -391,6 +392,7 @@ "labels": { "email": "Send by Email", "inthisorder": "Parts in this Order", + "orderhistory": "Order History", "print": "Show Printed Form" }, "successes": { diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index e93c6be9e..5b473a6b1 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -135,6 +135,7 @@ "mod_lb_hrs": "Horas laborales", "oem_partno": "OEM parte #", "part_type": "Tipo de parte", + "status": "Estado", "unq_seq": "Seq #" } }, @@ -391,6 +392,7 @@ "labels": { "email": "Enviar por correo electrónico", "inthisorder": "Partes en este pedido", + "orderhistory": "Historial de pedidos", "print": "Mostrar formulario impreso" }, "successes": { diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index e37f04001..df963678b 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -135,6 +135,7 @@ "mod_lb_hrs": "Heures de travail", "oem_partno": "Pièce OEM #", "part_type": "Type de pièce", + "status": "Statut", "unq_seq": "Seq #" } }, @@ -391,6 +392,7 @@ "labels": { "email": "Envoyé par email", "inthisorder": "Pièces dans cette commande", + "orderhistory": "Historique des commandes", "print": "Afficher le formulaire imprimé" }, "successes": { diff --git a/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/down.yaml b/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/down.yaml new file mode 100644 index 000000000..2c4cd87c3 --- /dev/null +++ b/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."joblines" DROP COLUMN "status"; + type: run_sql diff --git a/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/up.yaml b/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/up.yaml new file mode 100644 index 000000000..428023a4c --- /dev/null +++ b/hasura/migrations/1582224710136_alter_table_public_joblines_add_column_status/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."joblines" ADD COLUMN "status" text NULL; + type: run_sql diff --git a/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/down.yaml b/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/down.yaml new file mode 100644 index 000000000..3d0722715 --- /dev/null +++ b/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/down.yaml @@ -0,0 +1,75 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_insert_permission +- args: + permission: + check: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + columns: + - id + - created_at + - updated_at + - jobid + - unq_seq + - line_ind + - line_desc + - part_type + - oem_partno + - est_seq + - db_ref + - line_ref + - tax_part + - db_price + - act_price + - part_qty + - alt_partno + - mod_lbr_ty + - db_hrs + - mod_lb_hrs + - lbr_op + - lbr_amt + - glass_flag + - price_inc + - alt_part_i + - price_j + - cert_part + - alt_co_id + - alt_overrd + - alt_partm + - prt_dsmk_p + - prt_dsmk_m + - lbr_inc + - lbr_hrs_j + - lbr_typ_j + - lbr_op_j + - paint_stg + - paint_tone + - lbr_tax + - misc_amt + - misc_sublt + - misc_tax + - bett_type + - bett_pctg + - bett_amt + - bett_tax + - op_code_desc + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: joblines + schema: public + type: create_insert_permission diff --git a/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/up.yaml b/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/up.yaml new file mode 100644 index 000000000..df8b59464 --- /dev/null +++ b/hasura/migrations/1582224725146_update_permission_user_public_table_joblines/up.yaml @@ -0,0 +1,76 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_insert_permission +- args: + permission: + check: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + columns: + - id + - created_at + - updated_at + - jobid + - unq_seq + - line_ind + - line_desc + - part_type + - oem_partno + - est_seq + - db_ref + - line_ref + - tax_part + - db_price + - act_price + - part_qty + - alt_partno + - mod_lbr_ty + - db_hrs + - mod_lb_hrs + - lbr_op + - lbr_amt + - glass_flag + - price_inc + - alt_part_i + - price_j + - cert_part + - alt_co_id + - alt_overrd + - alt_partm + - prt_dsmk_p + - prt_dsmk_m + - lbr_inc + - lbr_hrs_j + - lbr_typ_j + - lbr_op_j + - paint_stg + - paint_tone + - lbr_tax + - misc_amt + - misc_sublt + - misc_tax + - bett_type + - bett_pctg + - bett_amt + - bett_tax + - op_code_desc + - status + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: joblines + schema: public + type: create_insert_permission diff --git a/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/down.yaml b/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/down.yaml new file mode 100644 index 000000000..32c4e42a2 --- /dev/null +++ b/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/down.yaml @@ -0,0 +1,73 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - alt_overrd + - alt_part_i + - bett_tax + - cert_part + - glass_flag + - lbr_hrs_j + - lbr_inc + - lbr_op_j + - lbr_tax + - lbr_typ_j + - misc_sublt + - misc_tax + - price_inc + - price_j + - tax_part + - est_seq + - paint_stg + - paint_tone + - part_qty + - unq_seq + - act_price + - bett_amt + - bett_pctg + - db_hrs + - db_price + - lbr_amt + - line_ref + - misc_amt + - mod_lb_hrs + - prt_dsmk_m + - prt_dsmk_p + - alt_co_id + - alt_partm + - alt_partno + - bett_type + - db_ref + - lbr_op + - line_desc + - line_ind + - mod_lbr_ty + - oem_partno + - op_code_desc + - part_type + - created_at + - updated_at + - id + - jobid + computed_fields: [] + filter: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + role: user + table: + name: joblines + schema: public + type: create_select_permission diff --git a/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/up.yaml b/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/up.yaml new file mode 100644 index 000000000..c639e07f8 --- /dev/null +++ b/hasura/migrations/1582224730652_update_permission_user_public_table_joblines/up.yaml @@ -0,0 +1,74 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - alt_overrd + - alt_part_i + - bett_tax + - cert_part + - glass_flag + - lbr_hrs_j + - lbr_inc + - lbr_op_j + - lbr_tax + - lbr_typ_j + - misc_sublt + - misc_tax + - price_inc + - price_j + - tax_part + - est_seq + - paint_stg + - paint_tone + - part_qty + - unq_seq + - act_price + - bett_amt + - bett_pctg + - db_hrs + - db_price + - lbr_amt + - line_ref + - misc_amt + - mod_lb_hrs + - prt_dsmk_m + - prt_dsmk_p + - alt_co_id + - alt_partm + - alt_partno + - bett_type + - db_ref + - lbr_op + - line_desc + - line_ind + - mod_lbr_ty + - oem_partno + - op_code_desc + - part_type + - status + - created_at + - updated_at + - id + - jobid + computed_fields: [] + filter: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + role: user + table: + name: joblines + schema: public + type: create_select_permission diff --git a/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/down.yaml b/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/down.yaml new file mode 100644 index 000000000..befcc2bb7 --- /dev/null +++ b/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/down.yaml @@ -0,0 +1,75 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_update_permission +- args: + permission: + columns: + - alt_overrd + - alt_part_i + - bett_tax + - cert_part + - glass_flag + - lbr_hrs_j + - lbr_inc + - lbr_op_j + - lbr_tax + - lbr_typ_j + - misc_sublt + - misc_tax + - price_inc + - price_j + - tax_part + - est_seq + - paint_stg + - paint_tone + - part_qty + - unq_seq + - act_price + - bett_amt + - bett_pctg + - db_hrs + - db_price + - lbr_amt + - line_ref + - misc_amt + - mod_lb_hrs + - prt_dsmk_m + - prt_dsmk_p + - alt_co_id + - alt_partm + - alt_partno + - bett_type + - db_ref + - lbr_op + - line_desc + - line_ind + - mod_lbr_ty + - oem_partno + - op_code_desc + - part_type + - created_at + - updated_at + - id + - jobid + filter: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: joblines + schema: public + type: create_update_permission diff --git a/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/up.yaml b/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/up.yaml new file mode 100644 index 000000000..a04baffe3 --- /dev/null +++ b/hasura/migrations/1582224737046_update_permission_user_public_table_joblines/up.yaml @@ -0,0 +1,76 @@ +- args: + role: user + table: + name: joblines + schema: public + type: drop_update_permission +- args: + permission: + columns: + - alt_overrd + - alt_part_i + - bett_tax + - cert_part + - glass_flag + - lbr_hrs_j + - lbr_inc + - lbr_op_j + - lbr_tax + - lbr_typ_j + - misc_sublt + - misc_tax + - price_inc + - price_j + - tax_part + - est_seq + - paint_stg + - paint_tone + - part_qty + - unq_seq + - act_price + - bett_amt + - bett_pctg + - db_hrs + - db_price + - lbr_amt + - line_ref + - misc_amt + - mod_lb_hrs + - prt_dsmk_m + - prt_dsmk_p + - alt_co_id + - alt_partm + - alt_partno + - bett_type + - db_ref + - lbr_op + - line_desc + - line_ind + - mod_lbr_ty + - oem_partno + - op_code_desc + - part_type + - status + - created_at + - updated_at + - id + - jobid + filter: + job: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: joblines + schema: public + type: create_update_permission From cf461b05361735ccdeaaee9c95517e9dca9f6547 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 20 Feb 2020 16:48:25 -0800 Subject: [PATCH 03/14] Refactord email popup screen to use Redx + implement all email redux/saga scaffolding. --- .../src/components/_test/test.component.jsx | 37 +++++++ .../email-overlay.component.jsx} | 13 ++- .../email-overlay/email-overlay.container.jsx | 100 ++++++++++++++++++ .../send-email-button.container.jsx | 72 ------------- .../manage-root.page.component.jsx | 39 ++++--- client/src/pages/manage/manage.page.jsx | 15 ++- client/src/redux/email/email.actions.js | 24 +++++ client/src/redux/email/email.reducer.js | 35 ++++++ client/src/redux/email/email.sagas.js | 50 +++++++++ client/src/redux/email/email.selectors.js | 25 +++++ client/src/redux/email/email.types.js | 8 ++ client/src/redux/root.reducer.js | 14 +-- client/src/redux/root.saga.js | 8 +- 13 files changed, 322 insertions(+), 118 deletions(-) create mode 100644 client/src/components/_test/test.component.jsx rename client/src/components/{send-email-button/send-email-button.component.jsx => email-overlay/email-overlay.component.jsx} (75%) create mode 100644 client/src/components/email-overlay/email-overlay.container.jsx delete mode 100644 client/src/components/send-email-button/send-email-button.container.jsx create mode 100644 client/src/redux/email/email.actions.js create mode 100644 client/src/redux/email/email.reducer.js create mode 100644 client/src/redux/email/email.sagas.js create mode 100644 client/src/redux/email/email.selectors.js create mode 100644 client/src/redux/email/email.types.js diff --git a/client/src/components/_test/test.component.jsx b/client/src/components/_test/test.component.jsx new file mode 100644 index 000000000..033f0ed3f --- /dev/null +++ b/client/src/components/_test/test.component.jsx @@ -0,0 +1,37 @@ +import React from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { setEmailOptions } from "../../redux/email/email.actions"; +import T from "../../emails/parts-order/parts-order.email"; +import { REPORT_QUERY_PARTS_ORDER_BY_PK } from "../../emails/parts-order/parts-order.query"; + +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser +}); +const mapDispatchToProps = dispatch => ({ + setEmailOptions: e => dispatch(setEmailOptions(e)) +}); +export default connect( + mapStateToProps, + mapDispatchToProps +)(function Test({ setEmailOptions }) { + return ( + + ); +}); diff --git a/client/src/components/send-email-button/send-email-button.component.jsx b/client/src/components/email-overlay/email-overlay.component.jsx similarity index 75% rename from client/src/components/send-email-button/send-email-button.component.jsx rename to client/src/components/email-overlay/email-overlay.component.jsx index 86187363d..635a86e56 100644 --- a/client/src/components/send-email-button/send-email-button.component.jsx +++ b/client/src/components/email-overlay/email-overlay.component.jsx @@ -4,35 +4,34 @@ import CKEditor from "@ckeditor/ckeditor5-react"; import ClassicEditor from "@ckeditor/ckeditor5-build-classic"; export default function SendEmailButtonComponent({ - emailConfig, + messageOptions, handleConfigChange, handleHtmlChange }) { return (
- THis is where the text editing will happen To CC Subject { - // You can store the "editor" and use when it is needed. + //You can store the "editor" and use when it is needed. console.log("Editor is ready to use!", editor); }} onChange={(event, editor) => { diff --git a/client/src/components/email-overlay/email-overlay.container.jsx b/client/src/components/email-overlay/email-overlay.container.jsx new file mode 100644 index 000000000..9e758c0b8 --- /dev/null +++ b/client/src/components/email-overlay/email-overlay.container.jsx @@ -0,0 +1,100 @@ +import { Button, Modal } from "antd"; +import React, { useEffect, useState } from "react"; +import { useLazyQuery } from "react-apollo"; +import { renderEmail } from "react-html-email"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { + sendEmail, + toggleEmailOverlayVisible +} from "../../redux/email/email.actions"; +import { + selectEmailConfig, + selectEmailVisible +} from "../../redux/email/email.selectors.js"; +import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import EmailOverlayComponent from "./email-overlay.component"; + +const mapStateToProps = createStructuredSelector({ + modalVisible: selectEmailVisible, + emailConfig: selectEmailConfig +}); +const mapDispatchToProps = dispatch => ({ + toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible()), + sendEmail: email => dispatch(sendEmail(email)) +}); +export default connect( + mapStateToProps, + mapDispatchToProps +)(function SendEmail({ + emailConfig, + modalVisible, + sendEmail, + toggleEmailOverlayVisible +}) { + const [messageOptions, setMessageOptions] = useState( + emailConfig.messageOptions + ); + useEffect(() => { + setMessageOptions(emailConfig.messageOptions); + }, [setMessageOptions, emailConfig.messageOptions]); + + const [executeQuery, { called, loading, data }] = useLazyQuery( + emailConfig.queryConfig[0], + { + ...emailConfig.queryConfig[1], + fetchPolicy: "network-only" + } + ); + + if ( + emailConfig.queryConfig[0] && + emailConfig.queryConfig[1] && + modalVisible && + !called + ) { + executeQuery(); + } + + if (data && !messageOptions.html && emailConfig.template) { + //console.log(ReactDOMServer.renderToStaticMarkup(