@@ -145,7 +145,7 @@ function TaskListComponent({
|
|||||||
key: "priority",
|
key: "priority",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
sortOrder: sortcolumn === "priority" && sortorder,
|
sortOrder: sortcolumn === "priority" && sortorder,
|
||||||
width: '5%',
|
width: '8%',
|
||||||
render: (text, record) => <PriorityLabel priority={record.priority}
|
render: (text, record) => <PriorityLabel priority={record.priority}
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
@@ -157,7 +157,6 @@ function TaskListComponent({
|
|||||||
<Space direction='horizontal'>
|
<Space direction='horizontal'>
|
||||||
<Button title={t('tasks.buttons.edit')} onClick={() => {
|
<Button title={t('tasks.buttons.edit')} onClick={() => {
|
||||||
setTaskUpsertContext({
|
setTaskUpsertContext({
|
||||||
actions: {},
|
|
||||||
context: {
|
context: {
|
||||||
existingTask: record,
|
existingTask: record,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,15 +2,19 @@ import queryString from "query-string";
|
|||||||
import {useLocation} from "react-router-dom";
|
import {useLocation} from "react-router-dom";
|
||||||
import {useMutation, useQuery} from "@apollo/client";
|
import {useMutation, useQuery} from "@apollo/client";
|
||||||
import {
|
import {
|
||||||
MUTATION_TOGGLE_TASK_COMPLETED, MUTATION_TOGGLE_TASK_DELETED,
|
MUTATION_TOGGLE_TASK_COMPLETED,
|
||||||
|
MUTATION_TOGGLE_TASK_DELETED,
|
||||||
QUERY_MY_TASKS_PAGINATED
|
QUERY_MY_TASKS_PAGINATED
|
||||||
} from "../../graphql/tasks.queries.js";
|
} from "../../graphql/tasks.queries.js";
|
||||||
import {pageLimit} from "../../utils/config.js";
|
import {pageLimit} from "../../utils/config.js";
|
||||||
import AlertComponent from "../alert/alert.component.jsx";
|
import AlertComponent from "../alert/alert.component.jsx";
|
||||||
import React, {useEffect} from "react";
|
import React, {useEffect} from "react";
|
||||||
import TaskListComponent from "./task-list.component.jsx";
|
import TaskListComponent from "./task-list.component.jsx";
|
||||||
|
import {notification} from "antd";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
|
||||||
export default function TaskListContainer({bodyshop, currentUser}) {
|
export default function TaskListContainer({bodyshop, currentUser}) {
|
||||||
|
const {t} = useTranslation();
|
||||||
const searchParams = queryString.parse(useLocation().search);
|
const searchParams = queryString.parse(useLocation().search);
|
||||||
const {page, sortcolumn, sortorder, deleted, completed} = searchParams;
|
const {page, sortcolumn, sortorder, deleted, completed} = searchParams;
|
||||||
const {loading, error, data, refetch} = useQuery(
|
const {loading, error, data, refetch} = useQuery(
|
||||||
@@ -45,7 +49,8 @@ export default function TaskListContainer({bodyshop, currentUser}) {
|
|||||||
const handleTaskUpdated = () => {
|
const handleTaskUpdated = () => {
|
||||||
refetch().catch((e) => {
|
refetch().catch((e) => {
|
||||||
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
||||||
}); };
|
});
|
||||||
|
};
|
||||||
}, [refetch]);
|
}, [refetch]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,16 +66,26 @@ export default function TaskListContainer({bodyshop, currentUser}) {
|
|||||||
*/
|
*/
|
||||||
const toggleCompletedStatus = async (id, currentStatus) => {
|
const toggleCompletedStatus = async (id, currentStatus) => {
|
||||||
const completed_at = !currentStatus ? new Date().toISOString() : null;
|
const completed_at = !currentStatus ? new Date().toISOString() : null;
|
||||||
await toggleTaskCompleted({
|
try {
|
||||||
variables: {
|
await toggleTaskCompleted({
|
||||||
id: id,
|
variables: {
|
||||||
completed: !currentStatus,
|
id: id,
|
||||||
completed_at: completed_at
|
completed: !currentStatus,
|
||||||
}
|
completed_at: completed_at
|
||||||
});
|
}
|
||||||
refetch().catch((e) => {
|
});
|
||||||
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
refetch().catch((e) => {
|
||||||
}); };
|
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
||||||
|
});
|
||||||
|
notification["success"]({
|
||||||
|
message: t("tasks.successes.completed"),
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("tasks.failures.completed"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle task deleted mutation
|
* Toggle task deleted mutation
|
||||||
@@ -85,20 +100,30 @@ export default function TaskListContainer({bodyshop, currentUser}) {
|
|||||||
*/
|
*/
|
||||||
const toggleDeletedStatus = async (id, currentStatus) => {
|
const toggleDeletedStatus = async (id, currentStatus) => {
|
||||||
const deleted_at = !currentStatus ? new Date().toISOString() : null;
|
const deleted_at = !currentStatus ? new Date().toISOString() : null;
|
||||||
await toggleTaskDeleted({
|
try {
|
||||||
variables: {
|
await toggleTaskDeleted({
|
||||||
id: id,
|
variables: {
|
||||||
deleted: !currentStatus,
|
id: id,
|
||||||
deleted_at: deleted_at
|
deleted: !currentStatus,
|
||||||
}
|
deleted_at: deleted_at
|
||||||
});
|
}
|
||||||
refetch().catch((e) => {
|
});
|
||||||
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
refetch().catch((e) => {
|
||||||
});
|
console.error(`Something went wrong fetching tasks: ${e.message || ''}`);
|
||||||
|
});
|
||||||
|
notification["success"]({
|
||||||
|
message: t("tasks.successes.deleted"),
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("tasks.failures.deleted"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (error) return <AlertComponent message={error.message} type="error"/>;
|
if (error) return <AlertComponent message={error.message} type="error"/>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TaskListComponent
|
<TaskListComponent
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import dayjs from '../../utils/day';
|
|||||||
|
|
||||||
import {connect} from "react-redux";
|
import {connect} from "react-redux";
|
||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
|
||||||
|
import JobSearchSelectComponent from "../job-search-select/job-search-select.component.jsx";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -41,8 +42,27 @@ export function TaskUpsertModalComponent({
|
|||||||
{label: t('tasks.date_presets.three_weeks'), value: dayjs().add(3, 'weeks')},
|
{label: t('tasks.date_presets.three_weeks'), value: dayjs().add(3, 'weeks')},
|
||||||
{label: t('tasks.date_presets.one_month'), value: dayjs().add(1, 'month')},
|
{label: t('tasks.date_presets.one_month'), value: dayjs().add(1, 'month')},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (loading || error) return <LoadingSkeleton active/>;
|
const clearRelations = () => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
billid: null,
|
||||||
|
partsorderid: null,
|
||||||
|
joblineid: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the selected job id
|
||||||
|
* @param jobId
|
||||||
|
*/
|
||||||
|
const changeJobId = (jobId) => {
|
||||||
|
setSelectedJobId(jobId || null);
|
||||||
|
// Reset the form fields when selectedJobId changes
|
||||||
|
clearRelations();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (!data || loading || error) return <LoadingSkeleton active/>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -80,20 +100,95 @@ export function TaskUpsertModalComponent({
|
|||||||
label={t("tasks.fields.completed")}
|
label={t("tasks.fields.completed")}
|
||||||
name="completed"
|
name="completed"
|
||||||
valuePropName="checked"
|
valuePropName="checked"
|
||||||
|
initialValue={false}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Switch/>
|
<Switch/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row gutter={[16, 16]}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item
|
||||||
|
name="jobid"
|
||||||
|
// initialValue={selectedJobId}
|
||||||
|
label={t("tasks.fields.jobid")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<JobSearchSelectComponent placeholder={t('tasks.placeholders.jobid')}
|
||||||
|
onSelect={changeJobId} onClear={changeJobId}/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={[16, 16]}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("tasks.fields.joblineid")}
|
||||||
|
name="joblineid"
|
||||||
|
>
|
||||||
|
<Select allowClear placeholder={t("tasks.placeholders.joblineid")}
|
||||||
|
disabled={!selectedJobDetails || !selectedJobId}>
|
||||||
|
{selectedJobDetails?.joblines?.map((jobline) => (
|
||||||
|
<Select.Option key={jobline.id} value={jobline.id}>
|
||||||
|
{jobline.line_desc}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("tasks.fields.partsorderid")}
|
||||||
|
name="partsorderid"
|
||||||
|
>
|
||||||
|
<Select allowClear placeholder={t("tasks.placeholders.partsorderid")}
|
||||||
|
disabled={!selectedJobDetails || !selectedJobId}>
|
||||||
|
{selectedJobDetails?.parts_orders?.map((partsOrder) => (
|
||||||
|
<Select.Option key={partsOrder.id} value={partsOrder.id}>
|
||||||
|
{partsOrder.order_number} - {partsOrder.vendor.name}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("tasks.fields.billid")}
|
||||||
|
name="billid"
|
||||||
|
>
|
||||||
|
<Select allowClear placeholder={t("tasks.placeholders.billid")}
|
||||||
|
disabled={!selectedJobDetails || !selectedJobId}>
|
||||||
|
{selectedJobDetails?.bills?.map((bill) => (
|
||||||
|
<Select.Option key={bill.id} value={bill.id}>
|
||||||
|
{bill.invoice_number} - {bill.vendor.name}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("tasks.fields.assigned_to")}
|
label={t("tasks.fields.assigned_to")}
|
||||||
name="assigned_to"
|
name="assigned_to"
|
||||||
initialValue={currentUser.email}
|
initialValue={currentUser.email}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Select placeholder={t("tasks.labels.selectemployee")}>
|
<Select placeholder={t("tasks.labels.selectemployee")}>
|
||||||
{bodyshop.employees.map((employee) => (
|
{bodyshop.employees.filter(x => x.active).map((employee) => (
|
||||||
<Select.Option key={employee.id} value={employee.user_email}>
|
<Select.Option key={employee.id} value={employee.user_email}>
|
||||||
{employee.first_name} {employee.last_name}
|
{employee.first_name} {employee.last_name}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
@@ -131,71 +226,6 @@ export function TaskUpsertModalComponent({
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row gutter={[16, 16]}>
|
|
||||||
<Col span={24}>
|
|
||||||
<Form.Item
|
|
||||||
name="jobid"
|
|
||||||
label={t("tasks.fields.jobid")}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
},1
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Select placeholder={t('tasks.placeholders.jobid')} defaultValue={selectedJobId} onSelect={setSelectedJobId}>
|
|
||||||
{data.jobs.map((job) => (
|
|
||||||
<Select.Option key={job.id} value={job.id}>
|
|
||||||
{job.ro_number}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row gutter={[16, 16]}>
|
|
||||||
<Col span={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={t("tasks.fields.joblineid")}
|
|
||||||
name="joblineid"
|
|
||||||
>
|
|
||||||
<Select placeholder={t("tasks.placeholders.joblineid")} disabled={!selectedJobDetails}>
|
|
||||||
{selectedJobDetails?.joblines?.map((jobline) => (
|
|
||||||
<Select.Option key={jobline.id} value={jobline.id}>
|
|
||||||
{jobline.line_desc}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={t("tasks.fields.partsorderid")}
|
|
||||||
name="partsorderid"
|
|
||||||
>
|
|
||||||
<Select placeholder={t("tasks.placeholders.partsorderid")} disabled={!selectedJobDetails}>
|
|
||||||
{selectedJobDetails?.parts_orders?.map((partsOrder) => (
|
|
||||||
<Select.Option key={partsOrder.id} value={partsOrder.id}>
|
|
||||||
{partsOrder.order_number} - {partsOrder.vendor.name}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={8}>
|
|
||||||
<Form.Item
|
|
||||||
label={t("tasks.fields.billid")}
|
|
||||||
name="billid"
|
|
||||||
>
|
|
||||||
<Select placeholder={t("tasks.placeholders.billid")} disabled={!selectedJobDetails}>
|
|
||||||
{selectedJobDetails?.bills?.map((bill) => (
|
|
||||||
<Select.Option key={bill.id} value={bill.id}>
|
|
||||||
{bill.invoice_number} - {bill.vendor.name}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ import {useTranslation} from "react-i18next";
|
|||||||
import {connect} from "react-redux";
|
import {connect} from "react-redux";
|
||||||
import {createStructuredSelector} from "reselect";
|
import {createStructuredSelector} from "reselect";
|
||||||
import {MUTATION_INSERT_NEW_TASK, MUTATION_UPDATE_TASK} from "../../graphql/tasks.queries";
|
import {MUTATION_INSERT_NEW_TASK, MUTATION_UPDATE_TASK} from "../../graphql/tasks.queries";
|
||||||
import {
|
import {QUERY_GET_TASKS_JOB_DETAILS_BY_ID} from "../../graphql/jobs.queries.js";
|
||||||
QUERY_GET_TASKS_JOB_DETAILS,
|
|
||||||
QUERY_GET_TASKS_JOB_DETAILS_BY_ID
|
|
||||||
} from "../../graphql/jobs.queries.js";
|
|
||||||
import {toggleModalVisible} from "../../redux/modals/modals.actions";
|
import {toggleModalVisible} from "../../redux/modals/modals.actions";
|
||||||
import {selectTaskUpsert} from "../../redux/modals/modals.selectors";
|
import {selectTaskUpsert} from "../../redux/modals/modals.selectors";
|
||||||
import {selectBodyshop, selectCurrentUser} from "../../redux/user/user.selectors";
|
import {selectBodyshop, selectCurrentUser} from "../../redux/user/user.selectors";
|
||||||
import TaskUpsertModalComponent from "./task-upsert-modal.component";
|
import TaskUpsertModalComponent from "./task-upsert-modal.component";
|
||||||
|
import {replaceUndefinedWithNull} from "../../utils/undefinedtonull.js";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
@@ -41,16 +39,14 @@ export function TaskUpsertModalContainer({
|
|||||||
const [selectedJobDetails, setSelectedJobDetails] = useState(null);
|
const [selectedJobDetails, setSelectedJobDetails] = useState(null);
|
||||||
const [jobIdState, setJobIdState] = useState(null);
|
const [jobIdState, setJobIdState] = useState(null);
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading: jobDetailsLoading,
|
loading: loading,
|
||||||
error: jobDetailsError,
|
error: error,
|
||||||
data: jobDetailsData
|
data: data
|
||||||
} = useQuery(QUERY_GET_TASKS_JOB_DETAILS_BY_ID, {
|
} = useQuery(QUERY_GET_TASKS_JOB_DETAILS_BY_ID, {
|
||||||
variables: {id: jobIdState},
|
variables: {id: jobIdState},
|
||||||
skip: !jobIdState, // Skip the query if jobIdState is null
|
skip: !jobIdState,
|
||||||
});
|
});
|
||||||
const {loading, error, data} = useQuery(QUERY_GET_TASKS_JOB_DETAILS);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the selected job id when the modal is opened and jobId is passed as a prop or when an existing task is passed as a prop
|
* Set the selected job id when the modal is opened and jobId is passed as a prop or when an existing task is passed as a prop
|
||||||
@@ -72,16 +68,6 @@ export function TaskUpsertModalContainer({
|
|||||||
}
|
}
|
||||||
}, [existingTask, form, open]);
|
}, [existingTask, form, open]);
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the form values when the selected job id changes
|
|
||||||
*/
|
|
||||||
useEffect(() => {
|
|
||||||
form.setFieldsValue({
|
|
||||||
joblineid: undefined,
|
|
||||||
billid: undefined,
|
|
||||||
partsorderid: undefined,
|
|
||||||
});
|
|
||||||
}, [selectedJobId, form]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the job id state when the selected job id changes
|
* Set the job id state when the selected job id changes
|
||||||
@@ -97,10 +83,11 @@ export function TaskUpsertModalContainer({
|
|||||||
* Set the selected job details when the job details query is successful
|
* Set the selected job details when the job details query is successful
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!jobDetailsLoading && !jobDetailsError && jobDetailsData) {
|
if (!loading && !error && data) {
|
||||||
setSelectedJobDetails(jobDetailsData.jobs_by_pk);
|
setSelectedJobDetails(data.jobs_by_pk);
|
||||||
}
|
}
|
||||||
}, [jobDetailsLoading, jobDetailsError, jobDetailsData]);
|
}, [loading, error, data]);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the form submit
|
* Handle the form submit
|
||||||
@@ -109,13 +96,11 @@ export function TaskUpsertModalContainer({
|
|||||||
*/
|
*/
|
||||||
const handleFinish = async (formValues) => {
|
const handleFinish = async (formValues) => {
|
||||||
const {...values} = formValues;
|
const {...values} = formValues;
|
||||||
|
|
||||||
if (existingTask) {
|
if (existingTask) {
|
||||||
await updateTask({
|
await updateTask({
|
||||||
variables: {
|
variables: {
|
||||||
taskId: existingTask.id,
|
taskId: existingTask.id,
|
||||||
task: values,
|
task: replaceUndefinedWithNull(values)
|
||||||
jobid: selectedJobId,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -128,19 +113,19 @@ export function TaskUpsertModalContainer({
|
|||||||
await insertTask({
|
await insertTask({
|
||||||
variables: {
|
variables: {
|
||||||
taskInput: [
|
taskInput: [
|
||||||
{...values, jobid: selectedJobId, created_by: currentUser.email, bodyshopid: bodyshop.id},
|
{
|
||||||
|
...replaceUndefinedWithNull(values),
|
||||||
|
created_by: currentUser.email,
|
||||||
|
bodyshopid: bodyshop.id
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
updateQueries: {
|
|
||||||
query: QUERY_GET_TASKS_JOB_DETAILS,
|
|
||||||
},
|
|
||||||
update(cache) {
|
update(cache) {
|
||||||
cache.modify({
|
cache.modify({
|
||||||
fields: {
|
fields: {
|
||||||
tasks(existingTasks) {
|
tasks(existingTasks) {
|
||||||
return [{
|
return [{
|
||||||
...values,
|
...values,
|
||||||
jobid: selectedJobId,
|
|
||||||
created_by: currentUser.email,
|
created_by: currentUser.email,
|
||||||
bodyshopid: bodyshop.id
|
bodyshopid: bodyshop.id
|
||||||
}, ...existingTasks]
|
}, ...existingTasks]
|
||||||
@@ -154,7 +139,7 @@ export function TaskUpsertModalContainer({
|
|||||||
form.resetFields();
|
form.resetFields();
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("tasks.successes.create"),
|
message: t("tasks.successes.created"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -176,7 +161,7 @@ export function TaskUpsertModalContainer({
|
|||||||
>
|
>
|
||||||
<Form form={form} onFinish={handleFinish} layout="vertical">
|
<Form form={form} onFinish={handleFinish} layout="vertical">
|
||||||
<TaskUpsertModalComponent form={form} loading={loading} error={error} data={data}
|
<TaskUpsertModalComponent form={form} loading={loading} error={error} data={data}
|
||||||
selectedJobId={setSelectedJobId}
|
selectedJobId={selectedJobId}
|
||||||
setSelectedJobId={setSelectedJobId}
|
setSelectedJobId={setSelectedJobId}
|
||||||
selectedJobDetails={selectedJobDetails}/>
|
selectedJobDetails={selectedJobDetails}/>
|
||||||
|
|
||||||
|
|||||||
@@ -2156,18 +2156,6 @@ export const QUERY_GET_TASKS_JOB_DETAILS_BY_ID = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QUERY_GET_TASKS_JOB_DETAILS = gql`
|
|
||||||
query GetTasksJobDetails {
|
|
||||||
jobs {
|
|
||||||
id
|
|
||||||
ro_number
|
|
||||||
ownr_fn
|
|
||||||
ownr_ln
|
|
||||||
ownr_co_nm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const GET_JOB_FOR_CC_CONTRACT = gql`
|
export const GET_JOB_FOR_CC_CONTRACT = gql`
|
||||||
query GET_JOB_FOR_CC_CONTRACT($id: uuid!) {
|
query GET_JOB_FOR_CC_CONTRACT($id: uuid!) {
|
||||||
jobs_by_pk(id: $id) {
|
jobs_by_pk(id: $id) {
|
||||||
|
|||||||
@@ -900,6 +900,7 @@
|
|||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"joblifecycle": "Job Life Cycles",
|
"joblifecycle": "Job Life Cycles",
|
||||||
|
"tasks": "Tasks",
|
||||||
"labhours": "Total Body Hours",
|
"labhours": "Total Body Hours",
|
||||||
"larhours": "Total Refinish Hours",
|
"larhours": "Total Refinish Hours",
|
||||||
"monthlyemployeeefficiency": "Monthly Employee Efficiency",
|
"monthlyemployeeefficiency": "Monthly Employee Efficiency",
|
||||||
@@ -2096,6 +2097,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tasks": {
|
"tasks": {
|
||||||
|
"failures": {
|
||||||
|
"created": "Failed to create Task.",
|
||||||
|
"deleted": "Failed to toggle Task deletion.",
|
||||||
|
"updated": "Failed to update Task.",
|
||||||
|
"completed": "Failed to toggle Task completion."
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "Task created successfully.",
|
||||||
|
"deleted": "Toggled Task deletion successfully.",
|
||||||
|
"updated": "Task updated successfully.",
|
||||||
|
"completed": "Toggled Task completion successfully."
|
||||||
|
},
|
||||||
"date_presets": {
|
"date_presets": {
|
||||||
"next_week": "Next Week",
|
"next_week": "Next Week",
|
||||||
"two_weeks": "Two Weeks",
|
"two_weeks": "Two Weeks",
|
||||||
@@ -3117,6 +3130,7 @@
|
|||||||
"accounting-receivables": "Receivables | {{app}}",
|
"accounting-receivables": "Receivables | {{app}}",
|
||||||
"app": "",
|
"app": "",
|
||||||
"bc": {
|
"bc": {
|
||||||
|
"tasks": "Tasks",
|
||||||
"accounting-payables": "Payables",
|
"accounting-payables": "Payables",
|
||||||
"accounting-payments": "Payments",
|
"accounting-payments": "Payments",
|
||||||
"accounting-receivables": "Receivables",
|
"accounting-receivables": "Receivables",
|
||||||
|
|||||||
@@ -900,6 +900,7 @@
|
|||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"joblifecycle": "",
|
"joblifecycle": "",
|
||||||
|
"tasks": "",
|
||||||
"labhours": "",
|
"labhours": "",
|
||||||
"larhours": "",
|
"larhours": "",
|
||||||
"monthlyemployeeefficiency": "",
|
"monthlyemployeeefficiency": "",
|
||||||
@@ -2095,6 +2096,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tasks": {
|
"tasks": {
|
||||||
|
"failures": {
|
||||||
|
"created": "",
|
||||||
|
"deleted": "",
|
||||||
|
"updated": "",
|
||||||
|
"completed": ""
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "",
|
||||||
|
"deleted": "",
|
||||||
|
"updated": "",
|
||||||
|
"completed": ""
|
||||||
|
},
|
||||||
"date_presets": {
|
"date_presets": {
|
||||||
"next_week": "",
|
"next_week": "",
|
||||||
"two_weeks": "",
|
"two_weeks": "",
|
||||||
@@ -3116,6 +3129,7 @@
|
|||||||
"accounting-receivables": "",
|
"accounting-receivables": "",
|
||||||
"app": "",
|
"app": "",
|
||||||
"bc": {
|
"bc": {
|
||||||
|
"tasks": "",
|
||||||
"accounting-payables": "",
|
"accounting-payables": "",
|
||||||
"accounting-payments": "",
|
"accounting-payments": "",
|
||||||
"accounting-receivables": "",
|
"accounting-receivables": "",
|
||||||
|
|||||||
@@ -900,7 +900,8 @@
|
|||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"joblifecycle": "",
|
"joblifecycle": "",
|
||||||
"labhours": "",
|
"tasks": "",
|
||||||
|
"labhours": "",
|
||||||
"larhours": "",
|
"larhours": "",
|
||||||
"monthlyemployeeefficiency": "",
|
"monthlyemployeeefficiency": "",
|
||||||
"monthlyjobcosting": "",
|
"monthlyjobcosting": "",
|
||||||
@@ -2095,6 +2096,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tasks": {
|
"tasks": {
|
||||||
|
"failures": {
|
||||||
|
"created": "",
|
||||||
|
"deleted": "",
|
||||||
|
"updated": "",
|
||||||
|
"completed": ""
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "",
|
||||||
|
"deleted": "",
|
||||||
|
"updated": "",
|
||||||
|
"completed": ""
|
||||||
|
},
|
||||||
"date_presets": {
|
"date_presets": {
|
||||||
"next_week": "",
|
"next_week": "",
|
||||||
"two_weeks": "",
|
"two_weeks": "",
|
||||||
@@ -3116,7 +3129,8 @@
|
|||||||
"accounting-receivables": "",
|
"accounting-receivables": "",
|
||||||
"app": "",
|
"app": "",
|
||||||
"bc": {
|
"bc": {
|
||||||
"accounting-payables": "",
|
"tasks": "",
|
||||||
|
"accounting-payables": "",
|
||||||
"accounting-payments": "",
|
"accounting-payments": "",
|
||||||
"accounting-receivables": "",
|
"accounting-receivables": "",
|
||||||
"availablejobs": "",
|
"availablejobs": "",
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Replaces undefined values with null in an object.
|
||||||
|
* Optionally, you can specify keys to replace.
|
||||||
|
* If keys are specified, only those keys will be replaced.
|
||||||
|
* If no keys are specified, all undefined values will be replaced.
|
||||||
|
* @param obj
|
||||||
|
* @param keys
|
||||||
|
* @returns {*}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
export default function UndefinedToNull(obj, keys) {
|
export default function UndefinedToNull(obj, keys) {
|
||||||
Object.keys(obj).forEach((key) => {
|
Object.keys(obj).forEach((key) => {
|
||||||
if (keys && keys.indexOf(key) >= 0) {
|
if (keys && keys.indexOf(key) >= 0) {
|
||||||
@@ -8,3 +18,21 @@ export default function UndefinedToNull(obj, keys) {
|
|||||||
});
|
});
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces undefined values with null in an object. Optionally, you can specify keys to replace. If keys are specified, only those keys will be replaced. If no keys are specified, all undefined values will be replaced.
|
||||||
|
* @param obj
|
||||||
|
* @param keys
|
||||||
|
* @returns {{[p: string]: unknown}}
|
||||||
|
*/
|
||||||
|
export function replaceUndefinedWithNull(obj, keys) {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(obj).map(([key, value]) => {
|
||||||
|
if (keys) {
|
||||||
|
return [key, (keys.includes(key) && value === undefined) ? null : value];
|
||||||
|
} else {
|
||||||
|
return [key, value === undefined ? null : value];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user