@@ -17,7 +17,6 @@ export default connect(mapStateToProps, mapDispatchToProps)(ProductionBoardFilte
|
|||||||
|
|
||||||
export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading }) {
|
export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
{loading && <Spin />}
|
{loading && <Spin />}
|
||||||
|
|||||||
@@ -59,7 +59,12 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsMoving(true);
|
setIsMoving(true);
|
||||||
const newBoardData = createBoardData({ statuses, data, filter });
|
const newBoardData = createBoardData({
|
||||||
|
statuses,
|
||||||
|
data,
|
||||||
|
filter,
|
||||||
|
cardSettings: associationSettings?.kanban_settings
|
||||||
|
});
|
||||||
|
|
||||||
newBoardData.lanes = newBoardData.lanes.map((lane) => ({
|
newBoardData.lanes = newBoardData.lanes.map((lane) => ({
|
||||||
...lane,
|
...lane,
|
||||||
@@ -74,7 +79,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
return prevBoardLanes;
|
return prevBoardLanes;
|
||||||
});
|
});
|
||||||
setIsMoving(false);
|
setIsMoving(false);
|
||||||
}, [data, bodyshop.md_ro_statuses, filter, statuses]);
|
}, [data, bodyshop.md_ro_statuses, filter, statuses, associationSettings?.kanban_settings]);
|
||||||
|
|
||||||
const getCardByID = useCallback((data, cardId) => {
|
const getCardByID = useCallback((data, cardId) => {
|
||||||
for (const lane of data.lanes) {
|
for (const lane of data.lanes) {
|
||||||
@@ -211,6 +216,8 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
parentLoading={setLoading}
|
parentLoading={setLoading}
|
||||||
associationSettings={associationSettings}
|
associationSettings={associationSettings}
|
||||||
onSettingsChange={handleSettingsChange}
|
onSettingsChange={handleSettingsChange}
|
||||||
|
bodyshop={bodyshop}
|
||||||
|
data={data}
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
// Function to sort an array of objects by parentId
|
||||||
import { groupBy } from "lodash";
|
import { groupBy } from "lodash";
|
||||||
|
|
||||||
// Function to sort an array of objects by parentId
|
|
||||||
const sortByParentId = (arr) => {
|
const sortByParentId = (arr) => {
|
||||||
let parentId = "-1";
|
let parentId = "-1";
|
||||||
const sortedList = [];
|
const sortedList = [];
|
||||||
@@ -28,7 +28,7 @@ const sortByParentId = (arr) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Function to create board data based on statuses and jobs, with optional filtering
|
// Function to create board data based on statuses and jobs, with optional filtering
|
||||||
export const createBoardData = ({ statuses, data, filter }) => {
|
export const createBoardData = ({ statuses, data, filter, cardSettings }) => {
|
||||||
const { search, employeeId } = filter;
|
const { search, employeeId } = filter;
|
||||||
|
|
||||||
const lanes = statuses.map((status) => ({
|
const lanes = statuses.map((status) => ({
|
||||||
@@ -37,9 +37,21 @@ export const createBoardData = ({ statuses, data, filter }) => {
|
|||||||
cards: []
|
cards: []
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const filteredJobs =
|
let filteredJobs =
|
||||||
(search === "" || !search) && !employeeId ? data : data.filter((job) => checkFilter(search, employeeId, job));
|
(search === "" || !search) && !employeeId ? data : data.filter((job) => checkFilter(search, employeeId, job));
|
||||||
|
|
||||||
|
// Filter jobs by selectedMdInsCos if it has values
|
||||||
|
if (cardSettings?.selectedMdInsCos?.length > 0) {
|
||||||
|
filteredJobs = filteredJobs.filter((job) => cardSettings.selectedMdInsCos.includes(job.ins_co_nm));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter jobs by selectedEstimators if it has values
|
||||||
|
if (cardSettings?.selectedEstimators?.length > 0) {
|
||||||
|
filteredJobs = filteredJobs.filter((job) =>
|
||||||
|
cardSettings.selectedEstimators.includes(`${job.est_ct_fn} ${job.est_ct_ln}`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const DataGroupedByStatus = groupBy(filteredJobs, "status");
|
const DataGroupedByStatus = groupBy(filteredJobs, "status");
|
||||||
|
|
||||||
Object.keys(DataGroupedByStatus).forEach((statusGroupKey) => {
|
Object.keys(DataGroupedByStatus).forEach((statusGroupKey) => {
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Card, Form, Select } from "antd";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
const FilterSettings = ({
|
||||||
|
selectedMdInsCos,
|
||||||
|
setSelectedMdInsCos,
|
||||||
|
selectedEstimators,
|
||||||
|
setSelectedEstimators,
|
||||||
|
setHasChanges,
|
||||||
|
bodyshop,
|
||||||
|
data
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const extractNames = (source, firstNameKey, lastNameKey) =>
|
||||||
|
source.map((item) => ({
|
||||||
|
firstName: item[firstNameKey],
|
||||||
|
lastName: item[lastNameKey]
|
||||||
|
}));
|
||||||
|
|
||||||
|
const bodyshopNames = extractNames(bodyshop.md_estimators, "est_ct_fn", "est_ct_ln");
|
||||||
|
const dataNames = extractNames(data, "est_ct_fn", "est_ct_ln");
|
||||||
|
|
||||||
|
const combinedNames = [...bodyshopNames, ...dataNames];
|
||||||
|
|
||||||
|
const uniqueNames = Array.from(
|
||||||
|
new Map(combinedNames.map((item) => [`${item.firstName} ${item.lastName}`, item])).values()
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card title={t("production.settings.filters_title")}>
|
||||||
|
<Form.Item label={t("production.settings.filters.md_ins_cos")}>
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
placeholder={t("production.settings.filters.md_ins_cos")}
|
||||||
|
value={selectedMdInsCos}
|
||||||
|
onChange={(value) => {
|
||||||
|
setSelectedMdInsCos(value);
|
||||||
|
setHasChanges(true);
|
||||||
|
}}
|
||||||
|
options={bodyshop.md_ins_cos.map((item) => ({
|
||||||
|
value: item.name,
|
||||||
|
label: item.name
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("production.settings.filters.md_estimators")}>
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
placeholder={t("production.settings.filters.md_estimators")}
|
||||||
|
value={selectedEstimators}
|
||||||
|
onChange={(value) => {
|
||||||
|
setSelectedEstimators(value);
|
||||||
|
setHasChanges(true);
|
||||||
|
}}
|
||||||
|
options={uniqueNames.map((item) => {
|
||||||
|
const name = `${item.firstName} ${item.lastName}`.trim();
|
||||||
|
return {
|
||||||
|
value: name,
|
||||||
|
label: name
|
||||||
|
};
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterSettings.propTypes = {
|
||||||
|
selectedMdInsCos: PropTypes.array.isRequired,
|
||||||
|
setSelectedMdInsCos: PropTypes.func.isRequired,
|
||||||
|
setHasChanges: PropTypes.func.isRequired,
|
||||||
|
selectedEstimators: PropTypes.array.isRequired,
|
||||||
|
setSelectedEstimators: PropTypes.func,
|
||||||
|
bodyshop: PropTypes.shape({
|
||||||
|
md_ins_cos: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
name: PropTypes.string.isRequired
|
||||||
|
})
|
||||||
|
).isRequired,
|
||||||
|
md_estimators: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
est_ct_fn: PropTypes.string.isRequired,
|
||||||
|
est_ct_ln: PropTypes.string.isRequired
|
||||||
|
})
|
||||||
|
).isRequired
|
||||||
|
}).isRequired,
|
||||||
|
data: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterSettings;
|
||||||
@@ -3,7 +3,7 @@ import React from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
const InformationSettings = ({ t }) => (
|
const InformationSettings = ({ t }) => (
|
||||||
<Card title={t("production.settings.information")} style={{ minWidth: "50vw", marginTop: 10 }}>
|
<Card title={t("production.settings.information")}>
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
{[
|
{[
|
||||||
"model_info",
|
"model_info",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
const LayoutSettings = ({ t }) => (
|
const LayoutSettings = ({ t }) => (
|
||||||
<Card title={t("production.settings.layout")} style={{ minWidth: "50vw", marginTop: 10 }}>
|
<Card title={t("production.settings.layout")}>
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,35 +15,37 @@ const StatisticsSettings = ({ t, statisticsOrder, setStatisticsOrder, setHasChan
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
<Card title={t("production.settings.statistics_title")}>
|
||||||
<Droppable direction="horizontal" droppableId="statistics">
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
{(provided) => (
|
<Droppable direction="horizontal" droppableId="statistics">
|
||||||
<div
|
{(provided) => (
|
||||||
{...provided.droppableProps}
|
<div
|
||||||
ref={provided.innerRef}
|
{...provided.droppableProps}
|
||||||
style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}
|
ref={provided.innerRef}
|
||||||
>
|
style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}
|
||||||
{statisticsOrder.map((itemId, index) => {
|
>
|
||||||
const item = statisticsItems.find((stat) => stat.id === itemId);
|
{statisticsOrder.map((itemId, index) => {
|
||||||
return (
|
const item = statisticsItems.find((stat) => stat.id === itemId);
|
||||||
<Draggable key={itemId} draggableId={itemId.toString()} index={index}>
|
return (
|
||||||
{(provided) => (
|
<Draggable key={itemId} draggableId={itemId.toString()} index={index}>
|
||||||
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
{(provided) => (
|
||||||
<Card styles={{ body: { padding: "5px" } }} style={{ marginBottom: 8, flex: "0 1 auto" }}>
|
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
||||||
<Form.Item style={{ marginBottom: 0 }} name={item.name} valuePropName="checked">
|
<Card styles={{ body: { padding: "5px" } }} style={{ marginBottom: 8, flex: "0 1 auto" }}>
|
||||||
<Checkbox>{t(`production.settings.statistics.${item.label}`)}</Checkbox>
|
<Form.Item style={{ marginBottom: 0 }} name={item.name} valuePropName="checked">
|
||||||
</Form.Item>
|
<Checkbox>{t(`production.settings.statistics.${item.label}`)}</Checkbox>
|
||||||
</Card>
|
</Form.Item>
|
||||||
</div>
|
</Card>
|
||||||
)}
|
</div>
|
||||||
</Draggable>
|
)}
|
||||||
);
|
</Draggable>
|
||||||
})}
|
);
|
||||||
{provided.placeholder}
|
})}
|
||||||
</div>
|
{provided.placeholder}
|
||||||
)}
|
</div>
|
||||||
</Droppable>
|
)}
|
||||||
</DragDropContext>
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ const defaultKanbanSettings = {
|
|||||||
totalLAROnBoard: false,
|
totalLAROnBoard: false,
|
||||||
jobsOnBoard: false,
|
jobsOnBoard: false,
|
||||||
totalAmountOnBoard: true,
|
totalAmountOnBoard: true,
|
||||||
statisticsOrder: statisticsItems.map((item) => item.id)
|
statisticsOrder: statisticsItems.map((item) => item.id),
|
||||||
|
selectedMdInsCos: [],
|
||||||
|
selectedEstimators: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export { defaultKanbanSettings, statisticsItems };
|
export { defaultKanbanSettings, statisticsItems };
|
||||||
|
|||||||
@@ -7,13 +7,16 @@ import { defaultKanbanSettings } from "./defaultKanbanSettings.js";
|
|||||||
import LayoutSettings from "./LayoutSettings.jsx";
|
import LayoutSettings from "./LayoutSettings.jsx";
|
||||||
import InformationSettings from "./InformationSettings.jsx";
|
import InformationSettings from "./InformationSettings.jsx";
|
||||||
import StatisticsSettings from "./StatisticsSettings.jsx";
|
import StatisticsSettings from "./StatisticsSettings.jsx";
|
||||||
|
import FilterSettings from "./FilterSettings.jsx";
|
||||||
|
|
||||||
export default function ProductionBoardKanbanSettings({ associationSettings, parentLoading }) {
|
export default function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [hasChanges, setHasChanges] = useState(false);
|
const [hasChanges, setHasChanges] = useState(false);
|
||||||
const [statisticsOrder, setStatisticsOrder] = useState(defaultKanbanSettings.statisticsOrder);
|
const [statisticsOrder, setStatisticsOrder] = useState(defaultKanbanSettings.statisticsOrder);
|
||||||
|
const [selectedMdInsCos, setSelectedMdInsCos] = useState(defaultKanbanSettings.selectedMdInsCos);
|
||||||
|
const [selectedEstimators, setSelectedEstimators] = useState(defaultKanbanSettings.selectedEstimators);
|
||||||
|
|
||||||
const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS);
|
const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -24,6 +27,12 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
if (associationSettings.kanban_settings.statisticsOrder) {
|
if (associationSettings.kanban_settings.statisticsOrder) {
|
||||||
setStatisticsOrder(associationSettings.kanban_settings.statisticsOrder);
|
setStatisticsOrder(associationSettings.kanban_settings.statisticsOrder);
|
||||||
}
|
}
|
||||||
|
if (associationSettings.kanban_settings.selectedMdInsCos) {
|
||||||
|
setSelectedMdInsCos(associationSettings.kanban_settings.selectedMdInsCos);
|
||||||
|
}
|
||||||
|
if (associationSettings.kanban_settings.selectedEstimators) {
|
||||||
|
setSelectedEstimators(associationSettings.kanban_settings.selectedEstimators);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [form, associationSettings]);
|
}, [form, associationSettings]);
|
||||||
|
|
||||||
@@ -34,7 +43,13 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
const result = await updateKbSettings({
|
const result = await updateKbSettings({
|
||||||
variables: {
|
variables: {
|
||||||
id: associationSettings?.id,
|
id: associationSettings?.id,
|
||||||
ks: { ...associationSettings.kanban_settings, ...values, statisticsOrder }
|
ks: {
|
||||||
|
...associationSettings.kanban_settings,
|
||||||
|
...values,
|
||||||
|
statisticsOrder,
|
||||||
|
selectedMdInsCos,
|
||||||
|
selectedEstimators
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -61,11 +76,13 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
statisticsOrder: defaultKanbanSettings.statisticsOrder
|
statisticsOrder: defaultKanbanSettings.statisticsOrder
|
||||||
});
|
});
|
||||||
setStatisticsOrder(defaultKanbanSettings.statisticsOrder);
|
setStatisticsOrder(defaultKanbanSettings.statisticsOrder);
|
||||||
|
setSelectedMdInsCos(defaultKanbanSettings.selectedMdInsCos);
|
||||||
|
setSelectedEstimators(defaultKanbanSettings.selectedEstimators);
|
||||||
setHasChanges(true);
|
setHasChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const overlay = (
|
const overlay = (
|
||||||
<Card>
|
<Card style={{ minWidth: "80vw" }}>
|
||||||
<Form form={form} onFinish={handleFinish} layout="vertical" onValuesChange={handleValuesChange}>
|
<Form form={form} onFinish={handleFinish} layout="vertical" onValuesChange={handleValuesChange}>
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultActiveKey="1"
|
defaultActiveKey="1"
|
||||||
@@ -91,6 +108,21 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
setHasChanges={setHasChanges}
|
setHasChanges={setHasChanges}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "4",
|
||||||
|
label: t("production.settings.filters_title"),
|
||||||
|
children: (
|
||||||
|
<FilterSettings
|
||||||
|
selectedMdInsCos={selectedMdInsCos}
|
||||||
|
setSelectedMdInsCos={setSelectedMdInsCos}
|
||||||
|
selectedEstimators={selectedEstimators}
|
||||||
|
setSelectedEstimators={setSelectedEstimators}
|
||||||
|
setHasChanges={setHasChanges}
|
||||||
|
bodyshop={bodyshop}
|
||||||
|
data={data}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2736,6 +2736,11 @@
|
|||||||
"information": "Information",
|
"information": "Information",
|
||||||
"statistics_title": "Statistics",
|
"statistics_title": "Statistics",
|
||||||
"board_settings": "Board Settings",
|
"board_settings": "Board Settings",
|
||||||
|
"filters_title": "Filters",
|
||||||
|
"filters": {
|
||||||
|
"md_ins_cos": "Insurance Companies",
|
||||||
|
"md_estimators": "Estimators"
|
||||||
|
},
|
||||||
"statistics": {
|
"statistics": {
|
||||||
"total_hours_in_production": "Hours in Production",
|
"total_hours_in_production": "Hours in Production",
|
||||||
"total_lab_in_production": "Body Hours in Production",
|
"total_lab_in_production": "Body Hours in Production",
|
||||||
|
|||||||
@@ -2736,6 +2736,11 @@
|
|||||||
"information": "",
|
"information": "",
|
||||||
"statistics_title": "",
|
"statistics_title": "",
|
||||||
"board_settings": "",
|
"board_settings": "",
|
||||||
|
"filters_title": "",
|
||||||
|
"filters": {
|
||||||
|
"md_ins_cos": "",
|
||||||
|
"md_estimators": ""
|
||||||
|
},
|
||||||
"statistics": {
|
"statistics": {
|
||||||
"total_hours_in_production": "",
|
"total_hours_in_production": "",
|
||||||
"total_lab_in_production": "",
|
"total_lab_in_production": "",
|
||||||
|
|||||||
@@ -2736,6 +2736,11 @@
|
|||||||
"information": "",
|
"information": "",
|
||||||
"statistics_title": "",
|
"statistics_title": "",
|
||||||
"board_settings": "",
|
"board_settings": "",
|
||||||
|
"filters_title": "",
|
||||||
|
"filters": {
|
||||||
|
"md_ins_cos": "",
|
||||||
|
"md_estimators": ""
|
||||||
|
},
|
||||||
"statistics": {
|
"statistics": {
|
||||||
"total_hours_in_production": "",
|
"total_hours_in_production": "",
|
||||||
"total_lab_in_production": "",
|
"total_lab_in_production": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user