- Progress commit

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-03-26 21:36:27 -04:00
parent 595159f24d
commit 301c680bff
8 changed files with 222 additions and 38 deletions

View File

@@ -476,7 +476,7 @@ function Header({
key: 'tasks', key: 'tasks',
id: 'tasks', id: 'tasks',
icon: <FaTasks />, icon: <FaTasks />,
label: t('menus.header.my_tasks'), label: t('menus.header.tasks'),
children: [ children: [
{ {
key: 'createTask', key: 'createTask',
@@ -492,7 +492,7 @@ function Header({
{ {
key: 'mytasks', key: 'mytasks',
icon: <FaTasks/>, icon: <FaTasks/>,
label: <Link to="/manage/tasks">{t('menus.header.tasks')}</Link>, label: <Link to="/manage/tasks">{t('menus.header.my_tasks')}</Link>,
} }
] ]
}, },

View File

@@ -774,7 +774,7 @@ export function JobsDetailHeaderActions({
menuItems.push( menuItems.push(
job.inproduction ? job.inproduction ?
{ {
key: 'addtoproduction', key: 'removefromproduction',
disabled: !job.converted, disabled: !job.converted,
label: t("jobs.actions.removefromproduction"), label: t("jobs.actions.removefromproduction"),
onClick: () => AddToProduction(client, job.id, refetch, true) onClick: () => AddToProduction(client, job.id, refetch, true)

View File

@@ -31,7 +31,7 @@ const DueDateRecord = ({dueDate}) => {
const relativeDueDate = dueDateDayjs.fromNow(); const relativeDueDate = dueDateDayjs.fromNow();
const today = dayjs(); const today = dayjs();
if (dueDateDayjs.isAfter(today)) { if (dueDateDayjs.isBefore(today)) {
return <div title={relativeDueDate} style={{color: 'red'}}> return <div title={relativeDueDate} style={{color: 'red'}}>
<DateFormatter>{dueDate}</DateFormatter></div>; <DateFormatter>{dueDate}</DateFormatter></div>;
} else { } else {
@@ -81,13 +81,14 @@ const mapStateToProps = (state) => ({
export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent); export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent);
function TaskListComponent({ function TaskListComponent({
loading, loading,
tasks, tasks,
total, total,
refetch, refetch,
toggleCompletedStatus, toggleCompletedStatus,
setTaskUpsertContext, setTaskUpsertContext,
}) { toggleDeletedStatus
}) {
const {t} = useTranslation(); const {t} = useTranslation();
const search = queryString.parse(useLocation().search); const search = queryString.parse(useLocation().search);
@@ -135,7 +136,7 @@ function TaskListComponent({
key: "due_date", key: "due_date",
sorter: true, sorter: true,
sortOrder: sortcolumn === "due_date" && sortorder, sortOrder: sortcolumn === "due_date" && sortorder,
width: '5%', width: '8%',
render: (text, record) => <DueDateRecord dueDate={record.due_date} />, render: (text, record) => <DueDateRecord dueDate={record.due_date} />,
}, },
{ {
@@ -154,7 +155,7 @@ function TaskListComponent({
width: '5%', width: '5%',
render: (text, record) => ( render: (text, record) => (
<Space direction='horizontal'> <Space direction='horizontal'>
<Button title={t('tasks.actions.edit')} onClick={() => { <Button title={t('tasks.buttons.edit')} onClick={() => {
setTaskUpsertContext({ setTaskUpsertContext({
actions: {}, actions: {},
context: { context: {
@@ -164,12 +165,12 @@ function TaskListComponent({
}}> }}>
<EditFilled/> <EditFilled/>
</Button> </Button>
<Button title={t('tasks.actions.toggle_completed')} <Button title={t('tasks.buttons.complete')}
onClick={() => toggleCompletedStatus(record.id, record.completed)}> onClick={() => toggleCompletedStatus(record.id, record.completed)}>
{record.completed ? <CheckCircleOutlined/> : {record.completed ? <CheckCircleOutlined/> :
<CheckCircleFilled/>} <CheckCircleFilled/>}
</Button> </Button>
<Button title={t('tasks.actions.toggle_deleted')} <Button title={t('tasks.buttons.delete')}
onClick={() => toggleDeletedStatus(record.id, record.deleted)}> onClick={() => toggleDeletedStatus(record.id, record.deleted)}>
{record.deleted ? <DeleteFilled/> : <DeleteOutlined/>} {record.deleted ? <DeleteFilled/> : <DeleteOutlined/>}
</Button> </Button>
@@ -228,10 +229,10 @@ function TaskListComponent({
checked={deleted === "true"} checked={deleted === "true"}
onChange={(value) => handleSwitchChange('deleted', value)} onChange={(value) => handleSwitchChange('deleted', value)}
/> />
<Button title={t('tasks.titles.create')} onClick={handleCreateTask}> <Button title={t('tasks.buttons.create')} onClick={handleCreateTask}>
<PlusCircleFilled/>{t('tasks.buttons.create')} <PlusCircleFilled/>{t('tasks.buttons.create')}
</Button> </Button>
<Button title={t('tasks.titles.refresh')} <Button title={t('tasks.buttons.refresh')}
onClick={() => refetch()}> onClick={() => refetch()}>
<SyncOutlined/> <SyncOutlined/>
</Button> </Button>

View File

@@ -1,15 +1,17 @@
import {Col, Form, Input, Row, Select, Switch} from "antd"; import {Col, Form, Input, Row, Select, Switch} from "antd";
import React, {useCallback} from "react"; import React from "react";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {FormDatePicker} from "../form-date-picker/form-date-picker.component.jsx"; import {FormDatePicker} from "../form-date-picker/form-date-picker.component.jsx";
import {createStructuredSelector} from "reselect"; import {createStructuredSelector} from "reselect";
import {selectBodyshop} from "../../redux/user/user.selectors.js"; 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 LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
}); });
const mapDispatchToProps = (dispatch) => ({}); const mapDispatchToProps = (dispatch) => ({});
@@ -23,6 +25,7 @@ export default connect(
export function TaskUpsertModalComponent({ export function TaskUpsertModalComponent({
form, form,
bodyshop, bodyshop,
currentUser,
selectedJobId, selectedJobId,
setSelectedJobId, setSelectedJobId,
selectedJobDetails, selectedJobDetails,
@@ -32,14 +35,19 @@ export function TaskUpsertModalComponent({
}) { }) {
const {t} = useTranslation(); const {t} = useTranslation();
console.dir(data) const datePickerPresets = [
{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')},
];
if (loading || error) return <LoadingSkeleton active/>; if (loading || error) return <LoadingSkeleton active/>;
return ( return (
<> <>
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col span={18}> <Col span={16}>
<Form.Item <Form.Item
label={t("tasks.fields.title")} label={t("tasks.fields.title")}
name="title" name="title"
@@ -49,7 +57,7 @@ export function TaskUpsertModalComponent({
}, },
]} ]}
> >
<Input placeholder={t("tasks.labels.titleplaceholder")}/> <Input placeholder={t("tasks.fields.title")}/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={4}> <Col span={4}>
@@ -60,14 +68,14 @@ export function TaskUpsertModalComponent({
> >
<Select <Select
options={[ options={[
{value: 3, label: t("tasks.fields.priority.low")}, {value: 3, label: t("tasks.fields.priorities.low")},
{value: 2, label: t("tasks.fields.priority.medium")}, {value: 2, label: t("tasks.fields.priorities.medium")},
{value: 1, label: t("tasks.fields.priority.high")}, {value: 1, label: t("tasks.fields.priorities.high")},
]} ]}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={2}> <Col span={4}>
<Form.Item <Form.Item
label={t("tasks.fields.completed")} label={t("tasks.fields.completed")}
name="completed" name="completed"
@@ -82,6 +90,7 @@ export function TaskUpsertModalComponent({
<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}
> >
<Select placeholder={t("tasks.labels.selectemployee")}> <Select placeholder={t("tasks.labels.selectemployee")}>
{bodyshop.employees.map((employee) => ( {bodyshop.employees.map((employee) => (
@@ -97,7 +106,7 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.due_date")} label={t("tasks.fields.due_date")}
name="due_date" name="due_date"
> >
<FormDatePicker/> <FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets}/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={8}> <Col span={8}>
@@ -105,7 +114,7 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.remind_at")} label={t("tasks.fields.remind_at")}
name="remind_at" name="remind_at"
> >
<FormDatePicker/> <FormDatePicker format="MM/DD/YYYY" presets={datePickerPresets}/>
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
@@ -117,7 +126,7 @@ export function TaskUpsertModalComponent({
> >
<Input.TextArea <Input.TextArea
rows={8} rows={8}
placeholder={t("tasks.labels.descriptionplaceholder")} placeholder={t("tasks.fields.description")}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
@@ -126,16 +135,14 @@ export function TaskUpsertModalComponent({
<Col span={24}> <Col span={24}>
<Form.Item <Form.Item
name="jobid" name="jobid"
label="Job ID" label={t("tasks.fields.jobid")}
rules={[ rules={[
{ {
required: true, required: true,
message: 'Please select a Job ID', },1
},
]} ]}
> >
<Select placeholder="Select a Job ID" defaultValue={selectedJobId} onSelect={setSelectedJobId}> <Select placeholder={t('tasks.placeholders.jobid')} defaultValue={selectedJobId} onSelect={setSelectedJobId}>
{data.jobs.map((job) => ( {data.jobs.map((job) => (
<Select.Option key={job.id} value={job.id}> <Select.Option key={job.id} value={job.id}>
{job.ro_number} {job.ro_number}
@@ -151,7 +158,7 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.joblineid")} label={t("tasks.fields.joblineid")}
name="joblineid" name="joblineid"
> >
<Select placeholder={t("tasks.labels.joblineidplaceholder")} disabled={!selectedJobDetails}> <Select placeholder={t("tasks.placeholders.joblineid")} disabled={!selectedJobDetails}>
{selectedJobDetails?.joblines?.map((jobline) => ( {selectedJobDetails?.joblines?.map((jobline) => (
<Select.Option key={jobline.id} value={jobline.id}> <Select.Option key={jobline.id} value={jobline.id}>
{jobline.line_desc} {jobline.line_desc}
@@ -165,8 +172,12 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.partsorderid")} label={t("tasks.fields.partsorderid")}
name="partsorderid" name="partsorderid"
> >
<Select placeholder={t("tasks.labels.partsorderidplaceholder")} disabled={!selectedJobDetails}> <Select placeholder={t("tasks.placeholders.partsorderid")} disabled={!selectedJobDetails}>
{/* Add your options here */} {selectedJobDetails?.parts_orders?.map((partsOrder) => (
<Select.Option key={partsOrder.id} value={partsOrder.id}>
{partsOrder.order_number} - {partsOrder.vendor.name}
</Select.Option>
))}
</Select> </Select>
</Form.Item> </Form.Item>
</Col> </Col>
@@ -175,8 +186,12 @@ export function TaskUpsertModalComponent({
label={t("tasks.fields.billid")} label={t("tasks.fields.billid")}
name="billid" name="billid"
> >
<Select placeholder={t("tasks.labels.billidplaceholder")} disabled={!selectedJobDetails}> <Select placeholder={t("tasks.placeholders.billid")} disabled={!selectedJobDetails}>
{/* Add your options here */} {selectedJobDetails?.bills?.map((bill) => (
<Select.Option key={bill.id} value={bill.id}>
{bill.invoice_number} - {bill.vendor.name}
</Select.Option>
))}
</Select> </Select>
</Form.Item> </Form.Item>
</Col> </Col>

View File

@@ -131,6 +131,9 @@ export function TaskUpsertModalContainer({
{...values, jobid: selectedJobId, created_by: currentUser.email, bodyshopid: bodyshop.id}, {...values, jobid: selectedJobId, created_by: currentUser.email, bodyshopid: bodyshop.id},
], ],
}, },
updateQueries: {
query: QUERY_GET_TASKS_JOB_DETAILS,
},
update(cache) { update(cache) {
cache.modify({ cache.modify({
fields: { fields: {

View File

@@ -2095,12 +2095,67 @@
} }
} }
}, },
"tasks": {
"date_presets": {
"next_week": "Next Week",
"two_weeks": "Two Weeks",
"three_weeks": "Three Weeks",
"one_month": "One Month"
},
"actions": {
"new": "New Task",
"edit": "Edit Task"
},
"titles": {
"completed": "Completed Tasks",
"deleted": "Deleted Tasks"
},
"buttons": {
"create": "Create Task",
"complete": "Complete",
"delete": "Delete",
"edit": "Edit",
"refresh": "Refresh"
},
"placeholders": {
"description": "Enter a description",
"jobid": "Select a Job",
"joblineid": "Select a Job Line",
"partsorderid": "Select a Parts Order",
"billid": "Select a Bill"
},
"fields": {
"priorities": {
"low": "Low",
"medium": "Medium",
"high": "High"
},
"title": "Title",
"joblineid": "Job Line",
"jobid": "Job",
"partsorderid": "Parts Order",
"billid": "Bill",
"description": "Description",
"due_date": "Due Date",
"actions": "Actions",
"priority": "Priority",
"remind_at": "Remind At",
"assigned_to": "Assigned To",
"completed": "Completed",
"job": {
"ro_number": "RO #"
}
}
},
"menus": { "menus": {
"currentuser": { "currentuser": {
"languageselector": "Language", "languageselector": "Language",
"profile": "Profile" "profile": "Profile"
}, },
"header": { "header": {
"create_task": "Create Task",
"tasks": "Tasks",
"my_tasks": "My Tasks",
"accounting": "Accounting", "accounting": "Accounting",
"accounting-payables": "Payables", "accounting-payables": "Payables",
"accounting-payments": "Payments", "accounting-payments": "Payments",

View File

@@ -2094,12 +2094,67 @@
} }
} }
}, },
"tasks": {
"date_presets": {
"next_week": "",
"two_weeks": "",
"three_weeks": "",
"one_month": ""
},
"actions": {
"new": "",
"edit": ""
},
"titles": {
"completed": "",
"deleted": ""
},
"buttons": {
"create": "",
"complete": "",
"delete": "",
"edit": "",
"refresh":""
},
"placeholders": {
"description": "",
"jobid": "",
"joblineid": "",
"partsorderid": "",
"billid": ""
},
"fields": {
"priorities": {
"low": "",
"medium":"",
"high": ""
},
"title": "",
"joblineid":"",
"jobid": "",
"partsorderid": "",
"billid": "",
"description": "",
"due_date": "",
"actions": "",
"priority": "",
"remind_at": "",
"assigned_to": "",
"completed": "",
"job": {
"ro_number": ""
}
}
},
"menus": { "menus": {
"currentuser": { "currentuser": {
"languageselector": "idioma", "languageselector": "idioma",
"profile": "Perfil" "profile": "Perfil"
}, },
"header": { "header": {
"create_task": "",
"tasks": "",
"my_tasks": "",
"accounting": "", "accounting": "",
"accounting-payables": "", "accounting-payables": "",
"accounting-payments": "", "accounting-payments": "",

View File

@@ -2094,12 +2094,67 @@
} }
} }
}, },
"tasks": {
"date_presets": {
"next_week": "",
"two_weeks": "",
"three_weeks": "",
"one_month": ""
},
"actions": {
"new": "",
"edit": ""
},
"titles": {
"completed": "",
"deleted": ""
},
"buttons": {
"create": "",
"complete": "",
"delete": "",
"edit": "",
"refresh":""
},
"placeholders": {
"description": "",
"jobid": "",
"joblineid": "",
"partsorderid": "",
"billid": ""
},
"fields": {
"priorities": {
"low": "",
"medium":"",
"high": ""
},
"title": "",
"joblineid":"",
"jobid": "",
"partsorderid": "",
"billid": "",
"description": "",
"due_date": "",
"actions": "",
"priority": "",
"remind_at": "",
"assigned_to": "",
"completed": "",
"job": {
"ro_number": ""
}
}
},
"menus": { "menus": {
"currentuser": { "currentuser": {
"languageselector": "La langue", "languageselector": "La langue",
"profile": "Profil" "profile": "Profil"
}, },
"header": { "header": {
"create_task": "",
"tasks": "",
"my_tasks": "",
"accounting": "", "accounting": "",
"accounting-payables": "", "accounting-payables": "",
"accounting-payments": "", "accounting-payments": "",