diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx index 0dfac2ac6..75a9e39c0 100644 --- a/client/src/components/header/header.component.jsx +++ b/client/src/components/header/header.component.jsx @@ -17,6 +17,7 @@ import Icon, { LineChartOutlined, PaperClipOutlined, PhoneOutlined, + PlusCircleOutlined, QuestionCircleFilled, ScheduleOutlined, SettingOutlined, @@ -25,11 +26,11 @@ import Icon, { UnorderedListOutlined, UserOutlined, } from '@ant-design/icons'; -import { useSplitTreatments } from '@splitsoftware/splitio-react'; -import { Layout, Menu, Switch, Tooltip } from 'antd'; -import React, { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { BsKanban } from 'react-icons/bs'; +import {useSplitTreatments} from '@splitsoftware/splitio-react'; +import {Layout, Menu, Switch, Tooltip} from 'antd'; +import React, {useEffect, useState} from 'react'; +import {useTranslation} from 'react-i18next'; +import {BsKanban} from 'react-icons/bs'; import { FaCalendarAlt, FaCarCrash, @@ -37,23 +38,23 @@ import { FaFileInvoiceDollar, FaTasks } from 'react-icons/fa'; -import { GiPayMoney, GiPlayerTime, GiSettingsKnobs } from 'react-icons/gi'; -import { IoBusinessOutline } from 'react-icons/io5'; -import { RiSurveyLine } from 'react-icons/ri'; -import { connect } from 'react-redux'; -import { Link } from 'react-router-dom'; -import { createStructuredSelector } from 'reselect'; +import {GiPayMoney, GiPlayerTime, GiSettingsKnobs} from 'react-icons/gi'; +import {IoBusinessOutline} from 'react-icons/io5'; +import {RiSurveyLine} from 'react-icons/ri'; +import {connect} from 'react-redux'; +import {Link} from 'react-router-dom'; +import {createStructuredSelector} from 'reselect'; import { selectRecentItems, selectSelectedHeader, } from '../../redux/application/application.selectors'; -import { setModalContext } from '../../redux/modals/modals.actions'; -import { signOutStart } from '../../redux/user/user.actions'; -import { selectBodyshop, selectCurrentUser } from '../../redux/user/user.selectors'; -import { FiLogOut } from 'react-icons/fi'; -import { checkBeta, handleBeta, setBeta } from '../../utils/betaHandler'; +import {setModalContext} from '../../redux/modals/modals.actions'; +import {signOutStart} from '../../redux/user/user.actions'; +import {selectBodyshop, selectCurrentUser} from '../../redux/user/user.selectors'; +import {FiLogOut} from 'react-icons/fi'; +import {checkBeta, handleBeta, setBeta} from '../../utils/betaHandler'; import InstanceRenderManager from '../../utils/instanceRenderMgr'; -import { HasFeatureAccess } from '../feature-wrapper/feature-wrapper.component'; +import {HasFeatureAccess} from '../feature-wrapper/feature-wrapper.component'; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -73,6 +74,10 @@ const mapDispatchToProps = (dispatch) => ({ signOutStart: () => dispatch(signOutStart()), setCardPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: 'cardPayment' })), + setTaskUpsertContext: (context) => dispatch(setModalContext({ + context: context, + modal: 'taskUpsert' + })), }); function Header({ @@ -87,6 +92,7 @@ function Header({ setReportCenterContext, recentItems, setCardPaymentContext, + setTaskUpsertContext, }) { const { treatments: { ImEXPay, DmsAp, Simple_Inventory }, @@ -470,7 +476,25 @@ function Header({ key: 'tasks', id: 'tasks', icon: , - label: {t('menus.header.tasks')}, + label: t('menus.header.tasks'), + children: [ + { + key: 'createTask', + icon: , + label: t('menus.header.create_task'), + onClick: () => { + setTaskUpsertContext({ + actions: {}, + context: {}, + }); + }, + }, + { + key: 'mytasks', + icon: , + label: {t('menus.header.tasks')}, + } + ] }, { key: 'shopsubmenu', diff --git a/client/src/components/task-list/task-list.component.jsx b/client/src/components/task-list/task-list.component.jsx index 4a9aea817..2f1d125b8 100644 --- a/client/src/components/task-list/task-list.component.jsx +++ b/client/src/components/task-list/task-list.component.jsx @@ -2,58 +2,91 @@ import {Button, Card, Space, Switch, Table} from "antd"; import queryString from "query-string"; import React, {useCallback, useState} from "react"; import {useTranslation} from "react-i18next"; -import {useLocation, useNavigate} from "react-router-dom"; +import {Link, useLocation, useNavigate} from "react-router-dom"; import {pageLimit} from "../../utils/config"; import dayjs from "../../utils/day"; import { CheckCircleFilled, CheckCircleOutlined, DeleteFilled, - DeleteOutlined, ExclamationCircleFilled, + DeleteOutlined, + EditFilled, + ExclamationCircleFilled, + PlusCircleFilled, SyncOutlined } from "@ant-design/icons"; +import {DateFormatter} from "../../utils/DateFormatter.jsx"; +import {connect} from 'react-redux'; +import {setModalContext} from '../../redux/modals/modals.actions'; +/** + * Task List Component + * @param dueDate + * @returns {Element} + * @constructor + */ const DueDateRecord = ({dueDate}) => { if (dueDate) { - const dueDateFormatted = dayjs(dueDate).format("YYYY-MM-DD"); - const relativeDueDate = dayjs(dueDate).fromNow(); - const today = dayjs().format("YYYY-MM-DD"); - if (dueDateFormatted < today) { - return
{dueDateFormatted}
; + const dueDateDayjs = dayjs(dueDate); + const relativeDueDate = dueDateDayjs.fromNow(); + const today = dayjs(); + + if (dueDateDayjs.isAfter(today)) { + return
+ {dueDate}
; } else { - return
{dueDateFormatted}
; + return
{dueDate}
; } } else { return
N/A
; } } + +/** + * Priority Label Component + * @param priority + * @returns {Element} + * @constructor + */ const PriorityLabel = ({priority}) => { switch(priority) { case 1: return
- High + High
; case 2: return
- Medium + Medium
; case 3: return
- Low + Low
; default: return
- None + None
; } } -export default function TaskListComponent({ +const mapDispatchToProps = (dispatch) => ({ + // Existing dispatch props... + setTaskUpsertContext: (context) => dispatch(setModalContext({context, modal: 'taskUpsert'})), +}); + +const mapStateToProps = (state) => ({ + // Existing state props... +}); + +export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent); + +function TaskListComponent({ loading, tasks, total, refetch, toggleCompletedStatus, + setTaskUpsertContext, }) { const {t} = useTranslation(); @@ -71,6 +104,17 @@ export default function TaskListComponent({ const history = useNavigate(); const columns = [ + { + title: t("tasks.fields.job.ro_number"), + dataIndex: ["job", "ro_number"], + key: "job.ro_number", + width: '5%', + render: (text, record) => ( + + {record.job.ro_number} + + ), + }, { title: t("tasks.fields.title"), dataIndex: "title", @@ -110,6 +154,16 @@ export default function TaskListComponent({ width: '5%', render: (text, record) => ( +