{componentList.map((f, idx) => {
switch (f.type) {
case "checkbox":
- return
;
+ return (
+
+ );
case "slider":
- return
;
+ return
;
case "text":
- return
;
+ return
;
case "textarea":
- return
;
+ return
;
case "rate":
- return
;
+ return
;
default:
return
Error
;
}
diff --git a/client/src/components/config-form-components/rate/rate.component.jsx b/client/src/components/config-form-components/rate/rate.component.jsx
index 42b2e4ca7..6b9d31e73 100644
--- a/client/src/components/config-form-components/rate/rate.component.jsx
+++ b/client/src/components/config-form-components/rate/rate.component.jsx
@@ -2,7 +2,7 @@ import React from "react";
import { Form, Rate } from "antd";
import { useTranslation } from "react-i18next";
-export default function JobIntakeFormCheckboxComponent({ formItem }) {
+export default function JobIntakeFormCheckboxComponent({ formItem, readOnly }) {
const { name, label, required } = formItem;
const { t } = useTranslation();
return (
@@ -14,8 +14,9 @@ export default function JobIntakeFormCheckboxComponent({ formItem }) {
required: required,
message: t("general.validation.required"),
},
- ]}>
-
+ ]}
+ >
+
);
}
diff --git a/client/src/components/config-form-components/slider/slider.component.jsx b/client/src/components/config-form-components/slider/slider.component.jsx
index 021dbfeab..a3b3e7fe4 100644
--- a/client/src/components/config-form-components/slider/slider.component.jsx
+++ b/client/src/components/config-form-components/slider/slider.component.jsx
@@ -2,7 +2,7 @@ import { Form, Slider } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
-export default function JobIntakeFormCheckboxComponent({ formItem }) {
+export default function JobIntakeFormCheckboxComponent({ formItem, readOnly }) {
const { name, label, required, min, max } = formItem;
const { t } = useTranslation();
return (
@@ -14,8 +14,9 @@ export default function JobIntakeFormCheckboxComponent({ formItem }) {
required: required,
message: t("general.validation.required"),
},
- ]}>
-
+ ]}
+ >
+
);
}
diff --git a/client/src/components/config-form-components/text/text.component.jsx b/client/src/components/config-form-components/text/text.component.jsx
index e12ffa4df..623b73666 100644
--- a/client/src/components/config-form-components/text/text.component.jsx
+++ b/client/src/components/config-form-components/text/text.component.jsx
@@ -2,7 +2,7 @@ import React from "react";
import { Form, Input } from "antd";
import { useTranslation } from "react-i18next";
-export default function JobIntakeFormCheckboxComponent({ formItem }) {
+export default function JobIntakeFormCheckboxComponent({ formItem, readOnly }) {
const { name, label, required } = formItem;
const { t } = useTranslation();
return (
@@ -14,8 +14,9 @@ export default function JobIntakeFormCheckboxComponent({ formItem }) {
required: required,
message: t("general.validation.required"),
},
- ]}>
-
+ ]}
+ >
+
);
}
diff --git a/client/src/components/config-form-components/textarea/textarea.component.jsx b/client/src/components/config-form-components/textarea/textarea.component.jsx
index 0ebd6f4f8..d60c58fdc 100644
--- a/client/src/components/config-form-components/textarea/textarea.component.jsx
+++ b/client/src/components/config-form-components/textarea/textarea.component.jsx
@@ -2,7 +2,7 @@ import React from "react";
import { Form, Input } from "antd";
import { useTranslation } from "react-i18next";
-export default function JobIntakeFormCheckboxComponent({ formItem }) {
+export default function JobIntakeFormCheckboxComponent({ formItem, readOnly }) {
const { name, label, required, rows } = formItem;
const { t } = useTranslation();
return (
@@ -14,8 +14,9 @@ export default function JobIntakeFormCheckboxComponent({ formItem }) {
required: required,
message: t("general.validation.required"),
},
- ]}>
-
+ ]}
+ >
+
);
}
diff --git a/client/src/components/csi-response-form/csi-response-form.container.jsx b/client/src/components/csi-response-form/csi-response-form.container.jsx
new file mode 100644
index 000000000..ff9bd0fb2
--- /dev/null
+++ b/client/src/components/csi-response-form/csi-response-form.container.jsx
@@ -0,0 +1,43 @@
+import { useQuery } from "@apollo/react-hooks";
+import { Form } from "antd";
+import queryString from "query-string";
+import React, { useEffect } from "react";
+import { useLocation } from "react-router-dom";
+import { QUERY_CSI_RESPONSE_BY_PK } from "../../graphql/csi.queries";
+import ConfigFormComponents from "../config-form-components/config-form-components.component";
+import { useTranslation } from "react-i18next";
+import LoadingSpinner from "../loading-spinner/loading-spinner.component";
+import AlertComponent from "../alert/alert.component";
+
+export default function CsiResponseFormContainer() {
+ const { t } = useTranslation();
+ const [form] = Form.useForm();
+ const searchParams = queryString.parse(useLocation().search);
+ const { responseid } = searchParams;
+ const { loading, error, data } = useQuery(QUERY_CSI_RESPONSE_BY_PK, {
+ variables: {
+ id: responseid,
+ },
+ skip: !!!responseid,
+ });
+
+ useEffect(() => {
+ form.resetFields();
+ }, [data, form]);
+
+ if (!!!responseid) return
{t("csi.labels.noneselected")}
;
+
+ if (loading) return
;
+ if (error) return
;
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/components/csi-response-list-paginated/csi-response-list-paginated.component.jsx b/client/src/components/csi-response-list-paginated/csi-response-list-paginated.component.jsx
new file mode 100644
index 000000000..dbbb3bcf7
--- /dev/null
+++ b/client/src/components/csi-response-list-paginated/csi-response-list-paginated.component.jsx
@@ -0,0 +1,159 @@
+import { SyncOutlined } from "@ant-design/icons";
+import { Button, Table } from "antd";
+import queryString from "query-string";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Link, useHistory, useLocation } from "react-router-dom";
+import { DateFormatter } from "../../utils/DateFormatter";
+import { alphaSort } from "../../utils/sorters";
+
+export default function CsiResponseListPaginated({
+ refetch,
+ loading,
+ responses,
+ total,
+}) {
+ const search = queryString.parse(useLocation().search);
+ const { responseid, page, sortcolumn, sortorder } = search;
+ const history = useHistory();
+ const [state, setState] = useState({
+ sortedInfo: {},
+ filteredInfo: { text: "" },
+ });
+
+ const { t } = useTranslation();
+ const columns = [
+ {
+ title: t("jobs.fields.ro_number"),
+ dataIndex: "ro_number",
+ key: "ro_number",
+ width: "8%",
+ sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
+ sortOrder: sortcolumn === "ro_number" && sortorder,
+
+ render: (text, record) => (
+
{record.job.ro_number}
+ ),
+ },
+ {
+ title: t("jobs.fields.est_number"),
+ dataIndex: "est_number",
+ key: "est_number",
+ width: "8%",
+ sorter: (a, b) => a.job.est_number - b.job.est_number,
+ sortOrder: sortcolumn === "est_number" && sortorder,
+
+ render: (text, record) => (
+
+ {record.job.est_number}
+
+ ),
+ },
+ {
+ title: t("jobs.fields.owner"),
+ dataIndex: "owner",
+ key: "owner",
+ ellipsis: true,
+ sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
+ width: "25%",
+ sortOrder: sortcolumn === "owner" && sortorder,
+ render: (text, record) => {
+ return record.owner ? (
+
+ {`${record.job.ownr_fn || ""} ${record.job.ownr_ln || ""}`}
+
+ ) : (
+
{`${record.job.ownr_fn || ""} ${
+ record.job.ownr_ln || ""
+ }`}
+ );
+ },
+ },
+ {
+ title: t("csi.fields.completedon"),
+ dataIndex: "completedon",
+ key: "completedon",
+ ellipsis: true,
+ sorter: (a, b) => a.completedon - b.completedon,
+ width: "25%",
+ sortOrder: sortcolumn === "completedon" && sortorder,
+ render: (text, record) => {
+ return record.completedon ? (
+
{record.completedon}
+ ) : null;
+ },
+ },
+ ];
+
+ const handleTableChange = (pagination, filters, sorter) => {
+ setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
+ search.page = pagination.current;
+ search.sortcolumn = sorter.columnKey;
+ search.sortorder = sorter.order;
+ history.push({ search: queryString.stringify(search) });
+ };
+
+ const handleOnRowClick = (record) => {
+ if (record) {
+ if (record.id) {
+ search.responseid = record.id;
+ history.push({ search: queryString.stringify(search) });
+ }
+ } else {
+ delete search.responseid;
+ history.push({ search: queryString.stringify(search) });
+ }
+ };
+
+ return (
+
+
{
+ return (
+
+
+ {
+ // {
+ // search.search = value;
+ // history.push({ search: queryString.stringify(search) });
+ // }}
+ // enterButton
+ // />
+ }
+
+ );
+ }}
+ size="small"
+ pagination={{
+ position: "top",
+ pageSize: 25,
+ current: parseInt(page || 1),
+ total: total,
+ }}
+ columns={columns}
+ rowKey="id"
+ dataSource={responses}
+ onChange={handleTableChange}
+ rowSelection={{
+ onSelect: (record) => {
+ handleOnRowClick(record);
+ },
+ selectedRowKeys: [responseid],
+ type: "radio",
+ }}
+ onRow={(record, rowIndex) => {
+ return {
+ onClick: (event) => {
+ handleOnRowClick(record);
+ }, // click row
+ };
+ }}
+ />
+
+ );
+}
diff --git a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
index 58c55e1ea..be5c1ed23 100644
--- a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
+++ b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
@@ -21,7 +21,7 @@ const DateTimePicker = ({ value, onChange, onBlur }) => {
selected={value ? new Date(value) : null}
onChange={handleChange}
showTimeSelect
- timeIntervals={5}
+ timeIntervals={15}
onBlur={onBlur}
isClearable
placeholderText={t("general.labels.selectdate")}
diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx
index 17c538f9f..b2ae84283 100644
--- a/client/src/components/header/header.component.jsx
+++ b/client/src/components/header/header.component.jsx
@@ -250,6 +250,9 @@ function Header({
{t("menus.header.shop_vendors")}
+
+ {t("menus.header.shop_csi")}
+
-
+
);
return (
-
+
diff --git a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx
index 1013d0afa..c7c6408f3 100644
--- a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx
+++ b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx
@@ -1,4 +1,4 @@
-import { DownCircleFilled } from "@ant-design/icons";
+import { DownCircleFilled, PrinterFilled } from "@ant-design/icons";
import {
Avatar,
Badge,
@@ -31,13 +31,15 @@ const mapStateToProps = createStructuredSelector({
const mapDispatchToProps = (dispatch) => ({
setScheduleContext: (context) =>
dispatch(setModalContext({ context: context, modal: "schedule" })),
+ setPrintCenterContext: (context) =>
+ dispatch(setModalContext({ context: context, modal: "printCenter" })),
});
export function JobsDetailHeader({
job,
mutationConvertJob,
refetch,
-
+ setPrintCenterContext,
bodyshop,
updateJobStatus,
setScheduleContext,
@@ -66,11 +68,26 @@ export function JobsDetailHeader({
);
const menuExtra = [
-
+
,
+ ,