@@ -17,7 +17,6 @@ export default connect(mapStateToProps, mapDispatchToProps)(ProductionBoardFilte
|
||||
|
||||
export function ProductionBoardFilters({ bodyshop, filter, setFilter, loading }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Space wrap>
|
||||
{loading && <Spin />}
|
||||
|
||||
@@ -59,7 +59,12 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
|
||||
useEffect(() => {
|
||||
setIsMoving(true);
|
||||
const newBoardData = createBoardData({ statuses, data, filter });
|
||||
const newBoardData = createBoardData({
|
||||
statuses,
|
||||
data,
|
||||
filter,
|
||||
cardSettings: associationSettings?.kanban_settings
|
||||
});
|
||||
|
||||
newBoardData.lanes = newBoardData.lanes.map((lane) => ({
|
||||
...lane,
|
||||
@@ -74,7 +79,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
return prevBoardLanes;
|
||||
});
|
||||
setIsMoving(false);
|
||||
}, [data, bodyshop.md_ro_statuses, filter, statuses]);
|
||||
}, [data, bodyshop.md_ro_statuses, filter, statuses, associationSettings?.kanban_settings]);
|
||||
|
||||
const getCardByID = useCallback((data, cardId) => {
|
||||
for (const lane of data.lanes) {
|
||||
@@ -211,6 +216,8 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
parentLoading={setLoading}
|
||||
associationSettings={associationSettings}
|
||||
onSettingsChange={handleSettingsChange}
|
||||
bodyshop={bodyshop}
|
||||
data={data}
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Function to sort an array of objects by parentId
|
||||
import { groupBy } from "lodash";
|
||||
|
||||
// Function to sort an array of objects by parentId
|
||||
const sortByParentId = (arr) => {
|
||||
let parentId = "-1";
|
||||
const sortedList = [];
|
||||
@@ -28,7 +28,7 @@ const sortByParentId = (arr) => {
|
||||
};
|
||||
|
||||
// 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 lanes = statuses.map((status) => ({
|
||||
@@ -37,9 +37,21 @@ export const createBoardData = ({ statuses, data, filter }) => {
|
||||
cards: []
|
||||
}));
|
||||
|
||||
const filteredJobs =
|
||||
let filteredJobs =
|
||||
(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");
|
||||
|
||||
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";
|
||||
|
||||
const InformationSettings = ({ t }) => (
|
||||
<Card title={t("production.settings.information")} style={{ minWidth: "50vw", marginTop: 10 }}>
|
||||
<Card title={t("production.settings.information")}>
|
||||
<Row gutter={[16, 16]}>
|
||||
{[
|
||||
"model_info",
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const LayoutSettings = ({ t }) => (
|
||||
<Card title={t("production.settings.layout")} style={{ minWidth: "50vw", marginTop: 10 }}>
|
||||
<Card title={t("production.settings.layout")}>
|
||||
<Row gutter={[16, 16]}>
|
||||
{[
|
||||
{
|
||||
|
||||
@@ -15,35 +15,37 @@ const StatisticsSettings = ({ t, statisticsOrder, setStatisticsOrder, setHasChan
|
||||
};
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Droppable direction="horizontal" droppableId="statistics">
|
||||
{(provided) => (
|
||||
<div
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}
|
||||
>
|
||||
{statisticsOrder.map((itemId, index) => {
|
||||
const item = statisticsItems.find((stat) => stat.id === itemId);
|
||||
return (
|
||||
<Draggable key={itemId} draggableId={itemId.toString()} index={index}>
|
||||
{(provided) => (
|
||||
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
||||
<Card styles={{ body: { padding: "5px" } }} style={{ marginBottom: 8, flex: "0 1 auto" }}>
|
||||
<Form.Item style={{ marginBottom: 0 }} name={item.name} valuePropName="checked">
|
||||
<Checkbox>{t(`production.settings.statistics.${item.label}`)}</Checkbox>
|
||||
</Form.Item>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
})}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
<Card title={t("production.settings.statistics_title")}>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Droppable direction="horizontal" droppableId="statistics">
|
||||
{(provided) => (
|
||||
<div
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}
|
||||
>
|
||||
{statisticsOrder.map((itemId, index) => {
|
||||
const item = statisticsItems.find((stat) => stat.id === itemId);
|
||||
return (
|
||||
<Draggable key={itemId} draggableId={itemId.toString()} index={index}>
|
||||
{(provided) => (
|
||||
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
||||
<Card styles={{ body: { padding: "5px" } }} style={{ marginBottom: 8, flex: "0 1 auto" }}>
|
||||
<Form.Item style={{ marginBottom: 0 }} name={item.name} valuePropName="checked">
|
||||
<Checkbox>{t(`production.settings.statistics.${item.label}`)}</Checkbox>
|
||||
</Form.Item>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
})}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ const defaultKanbanSettings = {
|
||||
totalLAROnBoard: false,
|
||||
jobsOnBoard: false,
|
||||
totalAmountOnBoard: true,
|
||||
statisticsOrder: statisticsItems.map((item) => item.id)
|
||||
statisticsOrder: statisticsItems.map((item) => item.id),
|
||||
selectedMdInsCos: [],
|
||||
selectedEstimators: []
|
||||
};
|
||||
|
||||
export { defaultKanbanSettings, statisticsItems };
|
||||
|
||||
@@ -7,13 +7,16 @@ import { defaultKanbanSettings } from "./defaultKanbanSettings.js";
|
||||
import LayoutSettings from "./LayoutSettings.jsx";
|
||||
import InformationSettings from "./InformationSettings.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 [open, setOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
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 { t } = useTranslation();
|
||||
@@ -24,6 +27,12 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
||||
if (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]);
|
||||
|
||||
@@ -34,7 +43,13 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
||||
const result = await updateKbSettings({
|
||||
variables: {
|
||||
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
|
||||
});
|
||||
setStatisticsOrder(defaultKanbanSettings.statisticsOrder);
|
||||
setSelectedMdInsCos(defaultKanbanSettings.selectedMdInsCos);
|
||||
setSelectedEstimators(defaultKanbanSettings.selectedEstimators);
|
||||
setHasChanges(true);
|
||||
};
|
||||
|
||||
const overlay = (
|
||||
<Card>
|
||||
<Card style={{ minWidth: "80vw" }}>
|
||||
<Form form={form} onFinish={handleFinish} layout="vertical" onValuesChange={handleValuesChange}>
|
||||
<Tabs
|
||||
defaultActiveKey="1"
|
||||
@@ -91,6 +108,21 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
||||
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",
|
||||
"statistics_title": "Statistics",
|
||||
"board_settings": "Board Settings",
|
||||
"filters_title": "Filters",
|
||||
"filters": {
|
||||
"md_ins_cos": "Insurance Companies",
|
||||
"md_estimators": "Estimators"
|
||||
},
|
||||
"statistics": {
|
||||
"total_hours_in_production": "Hours in Production",
|
||||
"total_lab_in_production": "Body Hours in Production",
|
||||
|
||||
@@ -2736,6 +2736,11 @@
|
||||
"information": "",
|
||||
"statistics_title": "",
|
||||
"board_settings": "",
|
||||
"filters_title": "",
|
||||
"filters": {
|
||||
"md_ins_cos": "",
|
||||
"md_estimators": ""
|
||||
},
|
||||
"statistics": {
|
||||
"total_hours_in_production": "",
|
||||
"total_lab_in_production": "",
|
||||
|
||||
@@ -2736,6 +2736,11 @@
|
||||
"information": "",
|
||||
"statistics_title": "",
|
||||
"board_settings": "",
|
||||
"filters_title": "",
|
||||
"filters": {
|
||||
"md_ins_cos": "",
|
||||
"md_estimators": ""
|
||||
},
|
||||
"statistics": {
|
||||
"total_hours_in_production": "",
|
||||
"total_lab_in_production": "",
|
||||
|
||||
Reference in New Issue
Block a user