- Check Point

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-08-02 15:49:09 -04:00
parent a297bba193
commit fb7e3bc812
12 changed files with 203 additions and 41 deletions

View File

@@ -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 />}

View File

@@ -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>
}

View File

@@ -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) => {

View File

@@ -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;

View File

@@ -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",

View File

@@ -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]}>
{[
{

View File

@@ -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>
);
};

View File

@@ -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 };

View File

@@ -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}
/>
)
}
]}
/>

View File

@@ -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",

View File

@@ -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": "",

View File

@@ -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": "",