Merged release/2025-01-31 into feature/IO-2825-Node-22-Update
This commit is contained in:
@@ -1,26 +1,23 @@
|
||||
import { Collapse, Form, Input, InputNumber, Select, Space, Switch } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||
import FormItemPhone, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
|
||||
import JobsDetailChangeEstimator from "../jobs-detail-change-estimator/jobs-detail-change-estimator.component";
|
||||
import JobsDetailChangeFilehandler from "../jobs-detail-change-filehandler/jobs-detail-change-filehandler.component";
|
||||
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
|
||||
import JobsDetailRatesParts from "../jobs-detail-rates/jobs-detail-rates.parts.component";
|
||||
|
||||
import JobsDetailRatesLabor from "../jobs-detail-rates/jobs-detail-rates.labor.component";
|
||||
import JobsDetailRatesMaterials from "../jobs-detail-rates/jobs-detail-rates.materials.component";
|
||||
import JobsDetailRatesOther from "../jobs-detail-rates/jobs-detail-rates.other.component";
|
||||
import JobsDetailRatesParts from "../jobs-detail-rates/jobs-detail-rates.parts.component";
|
||||
import JobsDetailRatesTaxes from "../jobs-detail-rates/jobs-detail-rates.taxes.component";
|
||||
|
||||
import JobsMarkPstExempt from "../jobs-mark-pst-exempt/jobs-mark-pst-exempt.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
@@ -199,7 +196,9 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel forceRender key="financial" header={t("menus.jobsdetail.financials")}>
|
||||
<JobsDetailRatesChangeButton form={form} />
|
||||
<JobsMarkPstExempt form={form} />
|
||||
{InstanceRenderManager({
|
||||
imex: <JobsMarkPstExempt form={form} />
|
||||
})}
|
||||
<LayoutFormRow>
|
||||
<Form.Item label={t("jobs.fields.ded_amt")} name="ded_amt">
|
||||
<CurrencyInput min={0} />
|
||||
@@ -246,7 +245,6 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
||||
</LayoutFormRow>
|
||||
)
|
||||
})}
|
||||
|
||||
<LayoutFormRow>
|
||||
<Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab">
|
||||
<CurrencyInput />
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { Button, Input, Space, Spin } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { ExclamationCircleFilled, ExclamationCircleOutlined } from "@ant-design/icons";
|
||||
import {
|
||||
ExclamationCircleFilled,
|
||||
ExclamationCircleOutlined,
|
||||
UserDeleteOutlined,
|
||||
UsergroupDeleteOutlined
|
||||
} from "@ant-design/icons";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import EmployeeSearchSelectComponent from "../employee-search-select/employee-search-select.component";
|
||||
|
||||
@@ -20,6 +25,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(ProductionBoardFilte
|
||||
export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading }) {
|
||||
const { t } = useTranslation();
|
||||
const [alertFilter, setAlertFilter] = useState(false);
|
||||
const [unassignedFilter, setUnassignedFilter] = useState(false);
|
||||
|
||||
const toggleAlertFilter = () => {
|
||||
const newAlertFilter = !alertFilter;
|
||||
@@ -27,6 +33,12 @@ export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading })
|
||||
setFilter({ ...filter, alert: newAlertFilter });
|
||||
};
|
||||
|
||||
const toggleUnassignedFilter = () => {
|
||||
const newUnassignedFilter = !unassignedFilter;
|
||||
setUnassignedFilter(newUnassignedFilter);
|
||||
setFilter({ ...filter, unassigned: newUnassignedFilter });
|
||||
};
|
||||
|
||||
return (
|
||||
<Space wrap>
|
||||
{loading && <Spin />}
|
||||
@@ -52,6 +64,13 @@ export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading })
|
||||
>
|
||||
{t("production.labels.alerts")}
|
||||
</Button>
|
||||
<Button
|
||||
type={unassignedFilter ? "primary" : "default"}
|
||||
onClick={toggleUnassignedFilter}
|
||||
icon={unassignedFilter ? <UserDeleteOutlined /> : <UsergroupDeleteOutlined />}
|
||||
>
|
||||
{t("production.labels.unassigned")}
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const sortByParentId = (arr) => {
|
||||
|
||||
// Function to create board data based on statuses and jobs, with optional filtering
|
||||
export const createBoardData = ({ statuses, data, filter, cardSettings }) => {
|
||||
const { search, employeeId, alert } = filter;
|
||||
const { search, employeeId, alert, unassigned } = filter;
|
||||
|
||||
const lanes = statuses.map((status) => ({
|
||||
id: status,
|
||||
@@ -40,6 +40,13 @@ export const createBoardData = ({ statuses, data, filter, cardSettings }) => {
|
||||
let filteredJobs =
|
||||
(search === "" || !search) && !employeeId ? data : data.filter((job) => checkFilter(search, employeeId, job));
|
||||
|
||||
// Apply "Unassigned" filter
|
||||
if (unassigned) {
|
||||
filteredJobs = filteredJobs.filter(
|
||||
(job) => !job.employee_body && !job.employee_prep && !job.employee_refinish && !job.employee_csr
|
||||
);
|
||||
}
|
||||
|
||||
// Filter jobs by selectedMdInsCos if it has values
|
||||
if (cardSettings?.selectedMdInsCos?.length > 0) {
|
||||
filteredJobs = filteredJobs.filter((job) => cardSettings.selectedMdInsCos.includes(job.ins_co_nm));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button, Card, Col, Form, Popover, Row, Tabs } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js";
|
||||
import { defaultKanbanSettings, mergeWithDefaults } from "./defaultKanbanSettings.js";
|
||||
@@ -11,6 +11,7 @@ import FilterSettings from "./FilterSettings.jsx";
|
||||
import PropTypes from "prop-types";
|
||||
import { isFunction } from "lodash";
|
||||
import { useNotification } from "../../../contexts/Notifications/notificationContext.jsx";
|
||||
import { SettingOutlined } from "@ant-design/icons";
|
||||
|
||||
function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data, onSettingsChange }) {
|
||||
const [form] = Form.useForm();
|
||||
@@ -153,7 +154,7 @@ function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bod
|
||||
|
||||
return (
|
||||
<Popover content={overlay} open={open} placement="topRight">
|
||||
<Button loading={loading} onClick={() => setOpen(!open)}>
|
||||
<Button icon={<SettingOutlined />} loading={loading} onClick={() => setOpen(!open)}>
|
||||
{t("production.settings.board_settings")}
|
||||
</Button>
|
||||
</Popover>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Button, Dropdown } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GenerateDocument } from "../../utils/RenderTemplate";
|
||||
@@ -7,6 +7,7 @@ import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||
import { PrinterFilled } from "@ant-design/icons";
|
||||
|
||||
const ProdTemplates = TemplateList("production");
|
||||
const { production_by_technician_one, production_by_category_one, production_by_repair_status_one } =
|
||||
@@ -123,7 +124,9 @@ export function ProductionListPrint({ bodyshop }) {
|
||||
|
||||
return (
|
||||
<Dropdown trigger="click" menu={menu}>
|
||||
<Button loading={loading}>{t("general.labels.print")}</Button>
|
||||
<Button icon={<PrinterFilled />} loading={loading}>
|
||||
{t("general.labels.print")}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Button } from "antd";
|
||||
import { useLocation } from "react-router-dom";
|
||||
@@ -28,7 +27,6 @@ const mapStateToProps = createStructuredSelector({
|
||||
* @param {Object} [props.buttonStyle={}] - Style object for the Ant Design button.
|
||||
* @param {Object} [props.buttonIconStyle={}] - Style object for the icon within the button.
|
||||
* @param {string} [props.linkText] - Text to display on the button or link.
|
||||
* @param {Object} [props.additionalProps] - Additional props to pass to the rendered component.
|
||||
* @returns {React.ReactElement} A button or text link for sharing to Microsoft Teams.
|
||||
*/
|
||||
const ShareToTeamsComponent = ({
|
||||
@@ -40,8 +38,7 @@ const ShareToTeamsComponent = ({
|
||||
noIconStyle = {},
|
||||
buttonStyle = {},
|
||||
buttonIconStyle = {},
|
||||
linkText,
|
||||
...additionalProps
|
||||
linkText
|
||||
}) => {
|
||||
const location = useLocation();
|
||||
const { t } = useTranslation();
|
||||
@@ -87,7 +84,7 @@ const ShareToTeamsComponent = ({
|
||||
|
||||
if (noIcon) {
|
||||
return (
|
||||
<div style={{ cursor: "pointer", ...noIconStyle }} onClick={handleShare} {...additionalProps}>
|
||||
<div style={{ cursor: "pointer", ...noIconStyle }} onClick={handleShare}>
|
||||
{!linkText ? t("general.actions.sharetoteams") : linkText}
|
||||
</div>
|
||||
);
|
||||
@@ -104,7 +101,6 @@ const ShareToTeamsComponent = ({
|
||||
icon={<SiMicrosoftteams style={{ color: "#FFFFFF", ...buttonIconStyle }} />}
|
||||
onClick={handleShare}
|
||||
title={linkText === null ? t("general.actions.sharetoteams") : linkText}
|
||||
{...additionalProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -117,8 +113,7 @@ ShareToTeamsComponent.propTypes = {
|
||||
noIconStyle: PropTypes.object,
|
||||
buttonStyle: PropTypes.object,
|
||||
buttonIconStyle: PropTypes.object,
|
||||
linkText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||
additionalProps: PropTypes.oneOfType([PropTypes.object, PropTypes.node])
|
||||
linkText: PropTypes.oneOfType([PropTypes.string, PropTypes.node])
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(ShareToTeamsComponent);
|
||||
|
||||
@@ -1527,7 +1527,7 @@
|
||||
"addDocuments": "Add Job Documents",
|
||||
"addNote": "Add Note",
|
||||
"addtopartsqueue": "Add to Parts Queue",
|
||||
"addtoproduction": "Add In Production Flag",
|
||||
"addtoproduction": "Add to Production",
|
||||
"addtoscoreboard": "Add to Scoreboard",
|
||||
"allocate": "Allocate",
|
||||
"autoallocate": "Auto Allocate",
|
||||
@@ -1570,7 +1570,7 @@
|
||||
"printCenter": "Print Center",
|
||||
"recalculate": "Recalculate",
|
||||
"reconcile": "Reconcile",
|
||||
"removefromproduction": "Remove In Production Flag",
|
||||
"removefromproduction": "Remove from Production",
|
||||
"schedule": "Schedule",
|
||||
"sendcsi": "Send CSI",
|
||||
"sendpartspricechange": "Send Parts Price Change",
|
||||
@@ -2859,7 +2859,8 @@
|
||||
"touchtime": "T/T",
|
||||
"vertical": "Vertical",
|
||||
"viewname": "View Name",
|
||||
"wide": "Wide"
|
||||
"wide": "Wide",
|
||||
"unassigned": "Unassigned"
|
||||
},
|
||||
"options": {
|
||||
"horizontal": "Horizontal",
|
||||
|
||||
@@ -2859,7 +2859,8 @@
|
||||
"touchtime": "",
|
||||
"vertical": "",
|
||||
"viewname": "",
|
||||
"wide": ""
|
||||
"wide": "",
|
||||
"unassigned": ""
|
||||
},
|
||||
"options": {
|
||||
"horizontal": "",
|
||||
|
||||
@@ -2859,7 +2859,8 @@
|
||||
"touchtime": "",
|
||||
"vertical": "",
|
||||
"viewname": "",
|
||||
"wide": ""
|
||||
"wide": "",
|
||||
"unassigned": ""
|
||||
},
|
||||
"options": {
|
||||
"horizontal": "",
|
||||
|
||||
Reference in New Issue
Block a user