Fix Formatting issues

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-04-08 22:25:07 -04:00
parent df0f8ef9dc
commit 33c282051b
34 changed files with 1805 additions and 1820 deletions

View File

@@ -1,58 +1,53 @@
import {Col, 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";
import {createStructuredSelector} from "reselect";
import {selectBodyshop, selectCurrentUser} from "../../redux/user/user.selectors.js";
import dayjs from '../../utils/day';
import { useTranslation } from "react-i18next";
import { FormDatePicker } from "../form-date-picker/form-date-picker.component.jsx";
import { createStructuredSelector } from "reselect";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors.js";
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 JobSearchSelectComponent from "../job-search-select/job-search-select.component.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({});
export default connect(
mapStateToProps,
mapDispatchToProps
)(TaskUpsertModalComponent);
export default connect(mapStateToProps, mapDispatchToProps)(TaskUpsertModalComponent);
export function TaskUpsertModalComponent({
form,
bodyshop,
currentUser,
selectedJobId,
setSelectedJobId,
selectedJobDetails,
loading,
error,
}) {
const {t} = useTranslation();
form,
bodyshop,
currentUser,
selectedJobId,
setSelectedJobId,
selectedJobDetails,
loading,
error
}) {
const { t } = useTranslation();
const datePickerPresets = [
{label: t('tasks.date_presets.today'), value: dayjs()},
{label: t('tasks.date_presets.tomorrow'), value: dayjs().add(1, 'day')},
{label: t('tasks.date_presets.next_week'), value: dayjs().add(1, 'week')},
{label: t('tasks.date_presets.two_weeks'), value: dayjs().add(2, '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.three_months'), value: dayjs().add(3, 'month')},
{ label: t("tasks.date_presets.today"), value: dayjs() },
{ label: t("tasks.date_presets.tomorrow"), value: dayjs().add(1, "day") },
{ label: t("tasks.date_presets.next_week"), value: dayjs().add(1, "week") },
{ label: t("tasks.date_presets.two_weeks"), value: dayjs().add(2, "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.three_months"), value: dayjs().add(3, "month") }
];
const clearRelations = () => {
form.setFieldsValue({
billid: null,
partsorderid: null,
joblineid: null
});
}
};
/**
* Change the selected job id
@@ -64,8 +59,7 @@ export function TaskUpsertModalComponent({
clearRelations();
};
if (loading || error) return <LoadingSkeleton active/>;
if (loading || error) return <LoadingSkeleton active />;
return (
<>
@@ -76,24 +70,20 @@ export function TaskUpsertModalComponent({
name="title"
rules={[
{
required: true,
},
required: true
}
]}
>
<Input placeholder={t("tasks.fields.title")}/>
<Input placeholder={t("tasks.fields.title")} />
</Form.Item>
</Col>
<Col span={4}>
<Form.Item
label={t("tasks.fields.priority")}
name="priority"
initialValue={3}
>
<Form.Item label={t("tasks.fields.priority")} name="priority" initialValue={3}>
<Select
options={[
{value: 3, label: t("tasks.fields.priorities.low")},
{value: 2, label: t("tasks.fields.priorities.medium")},
{value: 1, label: t("tasks.fields.priorities.high")},
{ value: 3, label: t("tasks.fields.priorities.low") },
{ value: 2, label: t("tasks.fields.priorities.medium") },
{ value: 1, label: t("tasks.fields.priorities.high") }
]}
/>
</Form.Item>
@@ -106,11 +96,11 @@ export function TaskUpsertModalComponent({
initialValue={false}
rules={[
{
required: true,
},
required: true
}
]}
>
<Switch/>
<Switch />
</Form.Item>
</Col>
</Row>
@@ -122,23 +112,27 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.jobid")}
rules={[
{
required: true,
},
required: true
}
]}
>
<JobSearchSelectComponent placeholder={t('tasks.placeholders.jobid')}
onSelect={changeJobId} onClear={changeJobId} autoFocus={false}/>
<JobSearchSelectComponent
placeholder={t("tasks.placeholders.jobid")}
onSelect={changeJobId}
onClear={changeJobId}
autoFocus={false}
/>
</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}>
<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}
@@ -148,12 +142,12 @@ export function TaskUpsertModalComponent({
</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}>
<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}
@@ -163,12 +157,12 @@ export function TaskUpsertModalComponent({
</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}>
<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}
@@ -186,46 +180,36 @@ export function TaskUpsertModalComponent({
initialValue={currentUser.email}
rules={[
{
required: true,
},
required: true
}
]}
>
<Select placeholder={t("tasks.placeholders.assigned_to")}>
{bodyshop.employees.filter(x => x.active).map((employee) => (
<Select.Option key={employee.id} value={employee.user_email}>
{employee.first_name} {employee.last_name}
</Select.Option>
))}
{bodyshop.employees
.filter((x) => x.active)
.map((employee) => (
<Select.Option key={employee.id} value={employee.user_email}>
{employee.first_name} {employee.last_name}
</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
label={t("tasks.fields.due_date")}
name="due_date"
>
<FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets}/>
<Form.Item label={t("tasks.fields.due_date")} name="due_date">
<FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
label={t("tasks.fields.remind_at")}
name="remind_at"
>
<FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets}/>
<Form.Item label={t("tasks.fields.remind_at")} name="remind_at">
<FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets} />
</Form.Item>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={24}>
<Form.Item
label={t("tasks.fields.description")}
name="description"
>
<Input.TextArea
rows={8}
placeholder={t("tasks.fields.description")}
/>
<Form.Item label={t("tasks.fields.description")} name="description">
<Input.TextArea rows={8} placeholder={t("tasks.fields.description")} />
</Form.Item>
</Col>
</Row>

View File

@@ -1,30 +1,26 @@
import {useMutation, useQuery} from "@apollo/client";
import {Form, Modal, notification} from "antd";
import React, {useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {connect} from "react-redux";
import {createStructuredSelector} from "reselect";
import {
MUTATION_INSERT_NEW_TASK,
MUTATION_UPDATE_TASK,
QUERY_GET_TASK_BY_ID
} from "../../graphql/tasks.queries";
import {QUERY_GET_TASKS_JOB_DETAILS_BY_ID} from "../../graphql/jobs.queries.js";
import {toggleModalVisible} from "../../redux/modals/modals.actions";
import {selectTaskUpsert} from "../../redux/modals/modals.selectors";
import {selectBodyshop, selectCurrentUser} from "../../redux/user/user.selectors";
import { useMutation, useQuery } from "@apollo/client";
import { Form, Modal, notification } from "antd";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { MUTATION_INSERT_NEW_TASK, MUTATION_UPDATE_TASK, QUERY_GET_TASK_BY_ID } from "../../graphql/tasks.queries";
import { QUERY_GET_TASKS_JOB_DETAILS_BY_ID } from "../../graphql/jobs.queries.js";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectTaskUpsert } from "../../redux/modals/modals.selectors";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import TaskUpsertModalComponent from "./task-upsert-modal.component";
import {replaceUndefinedWithNull} from "../../utils/undefinedtonull.js";
import {useNavigate} from "react-router-dom";
import { replaceUndefinedWithNull } from "../../utils/undefinedtonull.js";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import dayjs from '../../utils/day';
import {insertAuditTrail} from "../../redux/application/application.actions.js";
import dayjs from "../../utils/day";
import { insertAuditTrail } from "../../redux/application/application.actions.js";
import AuditTrailMapping from "../../utils/AuditTrailMappings.js";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop,
taskUpsert: selectTaskUpsert,
taskUpsert: selectTaskUpsert
});
const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("taskUpsert")),
@@ -32,32 +28,22 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(insertAuditTrail({ jobid, billid, operation, type }))
});
export function TaskUpsertModalContainer({
bodyshop,
currentUser,
taskUpsert,
toggleModalVisible,
insertAuditTrail
}) {
const {t} = useTranslation();
export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, toggleModalVisible, insertAuditTrail }) {
const { t } = useTranslation();
const history = useNavigate();
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 {refetch} = actions;
const { open, context, actions } = taskUpsert;
const { jobid, joblineid, billid, partsorderid, taskId, existingTask } = context;
const { refetch } = actions;
const [form] = Form.useForm();
const [selectedJobId, setSelectedJobId] = useState(null);
const [selectedJobDetails, setSelectedJobDetails] = useState(null);
const [jobIdState, setJobIdState] = useState(null);
const {
loading,
error,
data
} = useQuery(QUERY_GET_TASKS_JOB_DETAILS_BY_ID, {
variables: {id: jobIdState},
skip: !jobIdState,
const { loading, error, data } = useQuery(QUERY_GET_TASKS_JOB_DETAILS_BY_ID, {
variables: { id: jobIdState },
skip: !jobIdState
});
const {
@@ -65,8 +51,8 @@ export function TaskUpsertModalContainer({
error: taskError,
data: taskData
} = useQuery(QUERY_GET_TASK_BY_ID, {
variables: {id: taskId},
skip: !taskId,
variables: { id: taskId },
skip: !taskId
});
// Use Effect to hydrate existing task if only a taskid is provided
@@ -100,25 +86,24 @@ export function TaskUpsertModalContainer({
form.setFieldsValue(existingTask);
} else if (!existingTask && open) {
form.resetFields();
if (joblineid) form.setFieldsValue({joblineid});
if (billid) form.setFieldsValue({billid});
if (partsorderid) form.setFieldsValue({partsorderid});
if (joblineid) form.setFieldsValue({ joblineid });
if (billid) form.setFieldsValue({ billid });
if (partsorderid) form.setFieldsValue({ partsorderid });
}
return () => {
setSelectedJobId(null);
};
}, [jobid, existingTask, form, open, joblineid, billid, partsorderid]);
/**
* Remove the taskid from the URL
*/
const removeTaskIdFromUrl = () => {
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has('taskid')) return;
urlParams.delete('taskid');
if (!urlParams.has("taskid")) return;
urlParams.delete("taskid");
history(`${window.location.pathname}?${urlParams}`);
}
};
/**
* Handle existing task
@@ -132,48 +117,51 @@ export function TaskUpsertModalContainer({
variables: {
taskId: existingTask.id,
task: replaceUndefinedWithNull(values)
},
}
});
if (!taskData.errors) {
const oldTask = taskData?.data?.update_tasks?.returning[0];
const oldTask = taskData?.data?.update_tasks?.returning[0];
insertAuditTrail({
jobid: oldTask.jobid,
operation: AuditTrailMapping.tasksUpdated(
oldTask.title,
currentUser.email
),
operation: AuditTrailMapping.tasksUpdated(oldTask.title, currentUser.email),
type: "tasksUpdated"
});
}
if (isAssignedToDirty) {
// TODO This is being moved serverside
axios.post("/sendemail", {
from: {
name: bodyshop.shopname,
address: bodyshop.email,
},
ReplyTo: {
Email: 'noreply@imex.online'
},
to: values.assigned_to,
subject: `A Task has been re-assigned to you on ${bodyshop.shopname} - ${values.title}`,
templateStrings: {
header: values.title,
subHeader: `Assigned by ${currentUser.email} ${values.due_at ? `| Due on ${dayjs(values.due_at).format('MM/DD/YYYY')}` : ''}`,
body: `<a href="${window.location.protocol}//${window.location.host}/manage/tasks/alltasks?taskid=${existingTask.id}">Please sign in to your account to view the task details.</a>`
}
}).catch(e => console.error(`Something went wrong sending email to Assigned party on Task creation. ${e.message || ''}`));
axios
.post("/sendemail", {
from: {
name: bodyshop.shopname,
address: bodyshop.email
},
ReplyTo: {
Email: "noreply@imex.online"
},
to: values.assigned_to,
subject: `A Task has been re-assigned to you on ${bodyshop.shopname} - ${values.title}`,
templateStrings: {
header: values.title,
subHeader: `Assigned by ${currentUser.email} ${values.due_at ? `| Due on ${dayjs(values.due_at).format("MM/DD/YYYY")}` : ""}`,
body: `<a href="${window.location.protocol}//${window.location.host}/manage/tasks/alltasks?taskid=${existingTask.id}">Please sign in to your account to view the task details.</a>`
}
})
.catch((e) =>
console.error(`Something went wrong sending email to Assigned party on Task creation. ${e.message || ""}`)
);
}
window.dispatchEvent(new CustomEvent('taskUpdated', {
detail: {message: 'A task has been created or edited.'},
}));
window.dispatchEvent(
new CustomEvent("taskUpdated", {
detail: { message: "A task has been created or edited." }
})
);
notification["success"]({
message: t("tasks.successes.updated"),
message: t("tasks.successes.updated")
});
if (refetch) await refetch();
@@ -189,56 +177,59 @@ export function TaskUpsertModalContainer({
...values,
created_by: currentUser.email,
bodyshopid: bodyshop.id
},
],
},
}
]
}
});
const newTask = newTaskData?.data?.insert_tasks?.returning[0];
const newTask = newTaskData?.data?.insert_tasks?.returning[0];
const newTaskID = newTask?.id;
if (!newTaskData.errors) {
insertAuditTrail({
jobid: newTask.jobid,
operation: AuditTrailMapping.tasksCreated(
newTask.title,
currentUser.email
),
operation: AuditTrailMapping.tasksCreated(newTask.title, currentUser.email),
type: "tasksCreated"
});
}
if (refetch) await refetch();
form.resetFields();
toggleModalVisible();
// send notification to the assigned user
// TODO: This is being moved serverside
axios.post("/sendemail", {
from: {
name: bodyshop.shopname,
address: bodyshop.email,
},
replyTo: {
Email: 'noreply@imex.online'
},
to: values.assigned_to,
subject: `A new Task has been assigned to you on ${bodyshop.shopname} - ${values.title}`,
templateName: 'taskAssigned',
templateStrings: {
header: values.title,
subHeader: `Assigned by ${currentUser.email} ${values.due_at ? `| Due on ${dayjs(values.due_at).format('MM/DD/YYYY')}` : ''}`,
body: `<a href="${window.location.protocol}//${window.location.host}/manage/tasks/alltasks?taskid=${newTaskID}">Please sign to your account to view the task details.</a>`
}
}).catch(e => console.error(`Something went wrong sending email to Assigned party on Task edit. ${e.message || ''}`));
axios
.post("/sendemail", {
from: {
name: bodyshop.shopname,
address: bodyshop.email
},
replyTo: {
Email: "noreply@imex.online"
},
to: values.assigned_to,
subject: `A new Task has been assigned to you on ${bodyshop.shopname} - ${values.title}`,
templateName: "taskAssigned",
templateStrings: {
header: values.title,
subHeader: `Assigned by ${currentUser.email} ${values.due_at ? `| Due on ${dayjs(values.due_at).format("MM/DD/YYYY")}` : ""}`,
body: `<a href="${window.location.protocol}//${window.location.host}/manage/tasks/alltasks?taskid=${newTaskID}">Please sign to your account to view the task details.</a>`
}
})
.catch((e) =>
console.error(`Something went wrong sending email to Assigned party on Task edit. ${e.message || ""}`)
);
window.dispatchEvent(new CustomEvent('taskUpdated', {
detail: {message: 'A task has been created or edited.'},
}));
window.dispatchEvent(
new CustomEvent("taskUpdated", {
detail: { message: "A task has been created or edited." }
})
);
notification["success"]({
message: t("tasks.successes.created"),
message: t("tasks.successes.created")
});
};
@@ -248,7 +239,7 @@ export function TaskUpsertModalContainer({
* @returns {Promise<[{jobid, bodyshopid, created_by},...*]>}
*/
const handleFinish = async (formValues) => {
const {...values} = formValues;
const { ...values } = formValues;
if (existingTask) {
await handleExistingTask(values);
} else {
@@ -273,18 +264,18 @@ export function TaskUpsertModalContainer({
destroyOnClose
>
<Form form={form} onFinish={handleFinish} layout="vertical">
<TaskUpsertModalComponent form={form} loading={loading || (taskId && taskLoading)}
error={error} data={data}
selectedJobId={selectedJobId}
setSelectedJobId={setSelectedJobId}
selectedJobDetails={selectedJobDetails}/>
<TaskUpsertModalComponent
form={form}
loading={loading || (taskId && taskLoading)}
error={error}
data={data}
selectedJobId={selectedJobId}
setSelectedJobId={setSelectedJobId}
selectedJobDetails={selectedJobDetails}
/>
</Form>
</Modal>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(TaskUpsertModalContainer);
export default connect(mapStateToProps, mapDispatchToProps)(TaskUpsertModalContainer);