+
{dueDate}
);
};
+const RemindAtRecord = ({ remindAt }) => {
+ if (!remindAt) return <>>;
+
+ const remindAtDayjs = dayjs(remindAt);
+ const relativeRemindAtDate = remindAtDayjs.fromNow();
+ const isBeforeToday = remindAtDayjs.isBefore(dayjs());
+
+ return (
+
+ {remindAt}
+
+ );
+};
+
/**
* Priority Label Component
* @param priority
@@ -68,7 +82,7 @@ const PriorityLabel = ({ priority }) => {
default:
return (
- None
+ None
);
}
@@ -79,9 +93,7 @@ const mapDispatchToProps = (dispatch) => ({
setTaskUpsertContext: (context) => dispatch(setModalContext({ context, modal: "taskUpsert" }))
});
-const mapStateToProps = (state) => ({
- // Existing state props...
-});
+const mapStateToProps = (state) => ({});
export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent);
@@ -99,6 +111,7 @@ function TaskListComponent({
relationshipId,
onlyMine,
parentJobId,
+ query,
showRo = true
}) {
const { t } = useTranslation();
@@ -111,6 +124,17 @@ function TaskListComponent({
const history = useNavigate();
const columns = [];
+ columns.push({
+ title: t("tasks.fields.created_at"),
+ dataIndex: "created_at",
+ key: "created_at",
+ width: "8%",
+ defaultSortOrder: "ascend",
+ sorter: true,
+ sortOrder: sortcolumn === "created_at" && sortorder,
+ render: (text, record) =>
{record.created_at}
+ });
+
if (!onlyMine) {
columns.push({
title: t("tasks.fields.assigned_to"),
@@ -204,7 +228,7 @@ function TaskListComponent({
sorter: true,
sortOrder: sortcolumn === "remind_at" && sortorder,
width: "8%",
- render: (text, record) =>
+ render: (text, record) =>
},
{
title: t("tasks.fields.priority"),
@@ -226,7 +250,8 @@ function TaskListComponent({
onClick={() => {
setTaskUpsertContext({
context: {
- existingTask: record
+ existingTask: record,
+ query
}
});
}}
@@ -252,10 +277,11 @@ function TaskListComponent({
actions: {},
context: {
jobid: parentJobId,
- [relationshipType]: relationshipId
+ [relationshipType]: relationshipId,
+ query
}
});
- }, [parentJobId, relationshipId, relationshipType, setTaskUpsertContext]);
+ }, [parentJobId, relationshipId, relationshipType, setTaskUpsertContext, query]);
const handleTableChange = (pagination, filters, sorter) => {
search.page = pagination.current;
diff --git a/client/src/components/task-list/task-list.container.jsx b/client/src/components/task-list/task-list.container.jsx
index bb4c10b25..796249ec4 100644
--- a/client/src/components/task-list/task-list.container.jsx
+++ b/client/src/components/task-list/task-list.container.jsx
@@ -8,11 +8,22 @@ import React from "react";
import TaskListComponent from "./task-list.component.jsx";
import { notification } from "antd";
import { useTranslation } from "react-i18next";
-import { useDispatch } from "react-redux";
+import { connect, useDispatch } from "react-redux";
import { insertAuditTrail } from "../../redux/application/application.actions.js";
import AuditTrailMapping from "../../utils/AuditTrailMappings.js";
+import { createStructuredSelector } from "reselect";
+import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors.js";
-export default function TaskListContainer({
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+ currentUser: selectCurrentUser
+});
+
+const mapDispatchToProps = (dispatch) => ({});
+
+export default connect(mapStateToProps, mapDispatchToProps)(TaskListContainer);
+
+export function TaskListContainer({
bodyshop,
titleTranslation,
query,
@@ -140,7 +151,6 @@ export default function TaskListContainer({
return (
);
}
diff --git a/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx b/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
index 691edf94c..344e1fb89 100644
--- a/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
+++ b/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
@@ -1,4 +1,4 @@
-import { Col, DatePicker, Form, Input, Row, Select, Switch } from "antd";
+import { Col, Form, Input, Row, Select, Switch } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { FormDatePicker } from "../form-date-picker/form-date-picker.component.jsx";
@@ -9,6 +9,7 @@ import dayjs from "../../utils/day";
import { connect } from "react-redux";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
import JobSearchSelectComponent from "../job-search-select/job-search-select.component.jsx";
+import { FormDateTimePickerEnhanced } from "../form-date-time-picker-enhanced/form-date-time-picker-enhanced.component.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -194,12 +195,12 @@ export function TaskUpsertModalComponent({
-
+
-
+
diff --git a/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx b/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx
index dcf992b09..a2df073b6 100644
--- a/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx
+++ b/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx
@@ -34,7 +34,7 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
const [insertTask] = useMutation(MUTATION_INSERT_NEW_TASK);
const [updateTask] = useMutation(MUTATION_UPDATE_TASK);
const { open, context, actions } = taskUpsert;
- const { jobid, joblineid, billid, partsorderid, taskId, existingTask } = context;
+ const { jobid, joblineid, billid, partsorderid, taskId, existingTask, query } = context;
const { refetch } = actions;
const [form] = Form.useForm();
const [selectedJobId, setSelectedJobId] = useState(null);
@@ -54,7 +54,6 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
variables: { id: taskId },
skip: !taskId
});
-
// Use Effect to hydrate existing task if only a taskid is provided
useEffect(() => {
if (!taskLoading && !taskError && taskData && taskData?.tasks_by_pk) {
@@ -113,12 +112,19 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
const handleExistingTask = async (values) => {
const isAssignedToDirty = values.assigned_to !== existingTask.assigned_to;
- const taskData = await updateTask({
+ const taskObject = {
variables: {
taskId: existingTask.id,
task: replaceUndefinedWithNull(values)
- }
- });
+ },
+ refetchQueries: ["GET_JOB_BY_PK"]
+ };
+
+ if (query && Object.keys(query).length) {
+ taskObject.refetchQueries.push(Object.keys(query)[0]);
+ }
+
+ const taskData = await updateTask(taskObject);
if (!taskData.errors) {
const oldTask = taskData?.data?.update_tasks?.returning[0];
@@ -164,7 +170,7 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
};
const handleNewTask = async (values) => {
- const newTaskData = await insertTask({
+ const newTaskObject = {
variables: {
taskInput: [
{
@@ -174,16 +180,27 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
}
]
},
- update(cache, { data }) {
- cache.modify({
- fields: {
- tasks(cached) {
- return [...data?.insert_tasks?.returning, ...cached];
- }
- }
- });
- }
- });
+ refetchQueries: ["GET_JOB_BY_PK"]
+ // update(cache, { data }) {
+ // cache.modify({
+ // fields: {
+ // tasks(cached) {
+ // const newTasks = data?.insert_tasks?.returning.map(task => cache.writeFragment({
+ // data: task,
+ // fragment: PARTIAL_TASK_FIELDS_WRAPPER
+ // }));
+ // return [...cached, ...newTasks];
+ // }
+ // }
+ // });
+ // }
+ };
+
+ if (query && Object.keys(query).length) {
+ newTaskObject.refetchQueries.push(Object.keys(query)[0]);
+ }
+
+ const newTaskData = await insertTask(newTaskObject);
const newTask = newTaskData?.data?.insert_tasks?.returning[0];
const newTaskID = newTask?.id;
@@ -237,6 +254,7 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to
*/
const handleFinish = async (formValues) => {
const { ...values } = formValues;
+
if (existingTask) {
await handleExistingTask(values);
} else {
diff --git a/client/src/graphql/tasks.queries.js b/client/src/graphql/tasks.queries.js
index d06bf0717..60fe01fd9 100644
--- a/client/src/graphql/tasks.queries.js
+++ b/client/src/graphql/tasks.queries.js
@@ -1,6 +1,6 @@
import { gql } from "@apollo/client";
-const PARTIAL_TASK_FIELDS = gql`
+export const PARTIAL_TASK_FIELDS = gql`
fragment TaskFields on tasks {
id
created_at
@@ -63,6 +63,10 @@ const PARTIAL_TASK_FIELDS = gql`
}
`;
+export const PARTIAL_TASK_FIELDS_WRAPPER = gql`
+ ${PARTIAL_TASK_FIELDS}
+`;
+
export const QUERY_GET_TASK_BY_ID = gql`
${PARTIAL_TASK_FIELDS}
query QUERY_GET_TASK_BY_ID($id: uuid!) {
diff --git a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
index 5162e1621..e53c380e0 100644
--- a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
+++ b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
@@ -45,7 +45,7 @@ import ScheduleJobModalContainer from "../../components/schedule-job-modal/sched
import { insertAuditTrail } from "../../redux/application/application.actions";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions";
-import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
+import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import UndefinedToNull from "../../utils/undefinedtonull";
import _ from "lodash";
@@ -58,8 +58,7 @@ import { QUERY_JOB_TASKS_PAGINATED } from "../../graphql/tasks.queries.js";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
- jobRO: selectJobReadOnly,
- currentUser: selectCurrentUser
+ jobRO: selectJobReadOnly
});
const mapDispatchToProps = (dispatch) => ({
setPrintCenterContext: (context) =>
@@ -85,8 +84,6 @@ export function JobsDetailPage({
jobRO,
job,
mutationUpdateJob,
- handleSubmit,
- currentUser,
insertAuditTrail,
refetch
}) {
@@ -394,8 +391,6 @@ export function JobsDetailPage({
),
children: (
({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
@@ -23,13 +19,7 @@ const mapDispatchToProps = (dispatch) => ({
setTaskUpsertContext: (context) => dispatch(setModalContext({ context, modal: "taskUpsert" }))
});
-export function AllTasksPageContainer({
- bodyshop,
- currentUser,
- setBreadcrumbs,
- setSelectedHeader,
- setTaskUpsertContext
-}) {
+export function AllTasksPageContainer({ setBreadcrumbs, setSelectedHeader, setTaskUpsertContext }) {
const { t } = useTranslation();
const searchParams = queryString.parse(useLocation().search);
useEffect(() => {
@@ -64,7 +54,7 @@ export function AllTasksPageContainer({
}
}, [setTaskUpsertContext, searchParams]);
- return ;
+ return ;
}
export default connect(mapStateToProps, mapDispatchToProps)(AllTasksPageContainer);
diff --git a/client/src/pages/tasks/myTasksPageContainer.jsx b/client/src/pages/tasks/myTasksPageContainer.jsx
index 9e4776515..52b4b0fbf 100644
--- a/client/src/pages/tasks/myTasksPageContainer.jsx
+++ b/client/src/pages/tasks/myTasksPageContainer.jsx
@@ -6,20 +6,16 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions";
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
-import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors.js";
import TaskPageTypes from "./taskPageTypes.jsx";
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
- currentUser: selectCurrentUser
-});
+const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
setSelectedHeader: (key) => dispatch(setSelectedHeader(key))
});
-export function MyTasksPageContainer({ bodyshop, currentUser, setBreadcrumbs, setSelectedHeader }) {
+export function MyTasksPageContainer({ setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.my_tasks", {
@@ -38,7 +34,7 @@ export function MyTasksPageContainer({ bodyshop, currentUser, setBreadcrumbs, se
]);
}, [t, setBreadcrumbs, setSelectedHeader]);
- return ;
+ return ;
}
export default connect(mapStateToProps, mapDispatchToProps)(MyTasksPageContainer);
diff --git a/client/src/pages/tasks/tasks.page.component.jsx b/client/src/pages/tasks/tasks.page.component.jsx
index dc30cef67..1d8b1fc88 100644
--- a/client/src/pages/tasks/tasks.page.component.jsx
+++ b/client/src/pages/tasks/tasks.page.component.jsx
@@ -2,8 +2,15 @@ import React from "react";
import TaskListContainer from "../../components/task-list/task-list.container.jsx";
import { QUERY_ALL_TASKS_PAGINATED, QUERY_MY_TASKS_PAGINATED } from "../../graphql/tasks.queries.js";
import taskPageTypes from "./taskPageTypes.jsx";
+import { createStructuredSelector } from "reselect";
+import { selectCurrentUser } from "../../redux/user/user.selectors.js";
-export default function TasksPageComponent({ bodyshop, currentUser, type }) {
+const mapStateToProps = createStructuredSelector({
+ currentUser: selectCurrentUser
+});
+const mapDispatchToProps = (dispatch) => ({});
+
+export default function TasksPageComponent({ currentUser, type }) {
switch (type) {
case taskPageTypes.MY_TASKS:
return (
@@ -12,20 +19,11 @@ export default function TasksPageComponent({ bodyshop, currentUser, type }) {
relationshipId={currentUser.email}
relationshipType={"user"}
query={{ QUERY_MY_TASKS_PAGINATED }}
- bodyshop={bodyshop}
titleTranslation={"tasks.titles.my_tasks"}
- currentUser={currentUser}
/>
);
case taskPageTypes.ALL_TASKS:
- return (
-
- );
+ return ;
default:
return <>>;
}
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index dc1b24b7e..0e7419538 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -2205,6 +2205,7 @@
"medium": "Medium",
"high": "High"
},
+ "created_at": "Created At",
"jobline": "Job Line",
"parts_order": "Parts Order",
"bill": "Bill",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 5c138322b..f8585e858 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -2199,6 +2199,7 @@
"assigned_to": ""
},
"fields": {
+ "created_at": "" ,
"jobline": "",
"parts_order": "",
"bill": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index bf613fda1..67a8e7671 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -2199,6 +2199,7 @@
"assigned_to": ""
},
"fields": {
+ "created_at": "",
"jobline": "",
"parts_order": "",
"bill": "",