IO-3624 Extract shared title-row UI and polish config forms

This commit is contained in:
Dave
2026-03-24 20:56:30 -04:00
parent 1102670e66
commit 866e9581c2
23 changed files with 2706 additions and 1680 deletions

View File

@@ -1,4 +1,4 @@
import { DeleteFilled } from "@ant-design/icons";
import { DeleteFilled, HolderOutlined } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, DatePicker, Form, Input, InputNumber, Radio, Select, Space, Switch } from "antd";
import { useState } from "react";
@@ -13,6 +13,14 @@ import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import {
INLINE_TITLE_GROUP_STYLE,
INLINE_TITLE_HANDLE_STYLE,
INLINE_TITLE_INPUT_STYLE,
INLINE_TITLE_LABEL_STYLE,
INLINE_TITLE_ROW_STYLE,
INLINE_TITLE_SEPARATOR_STYLE
} from "../layout-form-row/inline-form-row-title.utils.js";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
import ShopInfoResponsibilitycentersTaxesComponent from "./shop-info.responsibilitycenters.taxes.component";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
@@ -34,8 +42,6 @@ export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoResponsibili
export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
const { t } = useTranslation();
const dmsPayers = Form.useWatch(["cdk_configuration", "payers"], form) || [];
const costResponsibilityCenters = Form.useWatch(["md_responsibility_centers", "costs"], form) || [];
const profitResponsibilityCenters = Form.useWatch(["md_responsibility_centers", "profits"], form) || [];
const hasDMSKey = bodyshopHasDmsKey(bodyshop);
@@ -659,18 +665,116 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
return (
<div>
{fields.map((field, index) => {
const responsibilityCenter = costResponsibilityCenters[field.name] || {};
const hasProfitCenterBodyFields =
(hasDMSKey && !bodyshop.rr_dealerid) || bodyshop.cdk_dealerid || bodyshop.rr_dealerid;
return (
<Form.Item key={field.key}>
<LayoutFormRow
noDivider
title={getFormListItemTitle(
t("bodyshop.fields.responsibilitycenter"),
index,
responsibilityCenter.name,
responsibilityCenter.accountname
)}
titleOnly={!hasProfitCenterBodyFields}
title={
<div style={INLINE_TITLE_ROW_STYLE}>
<HolderOutlined style={INLINE_TITLE_HANDLE_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1 1 340px",
maxWidth: 390
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter")}
</div>
<Form.Item noStyle name={[field.name, "name"]} rules={[{ required: true }]}>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1 1 220px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter_accountname")}
</div>
<Form.Item noStyle name={[field.name, "accountname"]} rules={[{ required: true }]}>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter_accountname")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1 1 220px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter_accountdesc")}
</div>
<Form.Item noStyle name={[field.name, "accountdesc"]} rules={[{ required: true }]}>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter_accountdesc")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
{!hasDMSKey && (
<>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "0.9 1 220px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter_accountitem")}
</div>
<Form.Item
noStyle
name={[field.name, "accountitem"]}
rules={[{ required: true }]}
>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter_accountitem")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
</>
)}
</div>
}
wrapTitle
extra={
<Space align="center" size="small">
<Button
@@ -689,31 +793,6 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
</Space>
}
>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_accountname")}
key={`${index}accountname`}
name={[field.name, "accountname"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
key={`${index}accountdesc`}
name={[field.name, "accountdesc"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
{hasDMSKey && !bodyshop.rr_dealerid && (
<>
<Form.Item
@@ -774,18 +853,135 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
return (
<div>
{fields.map((field, index) => {
const responsibilityCenter = profitResponsibilityCenters[field.name] || {};
const hasProfitCenterBodyFields =
(hasDMSKey && !bodyshop.rr_dealerid) || bodyshop.cdk_dealerid || bodyshop.rr_dealerid;
return (
<Form.Item key={field.key}>
<LayoutFormRow
noDivider
title={getFormListItemTitle(
t("bodyshop.fields.responsibilitycenter"),
index,
responsibilityCenter.name,
responsibilityCenter.accountdesc
)}
titleOnly={!hasProfitCenterBodyFields}
title={
<div style={INLINE_TITLE_ROW_STYLE}>
<HolderOutlined style={INLINE_TITLE_HANDLE_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1.4 1 440px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter")}
</div>
<Form.Item noStyle name={[field.name, "name"]} rules={[{ required: true }]}>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1 1 260px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter_accountdesc")}
</div>
<Form.Item noStyle name={[field.name, "accountdesc"]} rules={[{ required: true }]}>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter_accountdesc")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
{!hasDMSKey && (
<>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "0.9 1 220px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenter_accountitem")}
</div>
<Form.Item
noStyle
name={[field.name, "accountitem"]}
rules={[{ required: true }]}
>
<Input
placeholder={t("bodyshop.fields.responsibilitycenter_accountitem")}
onBlur={handleBlur}
size="small"
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
</>
)}
{bodyshop.rr_dealerid && (
<>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "0.9 1 220px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenters.item_type")}
</div>
<Form.Item
noStyle
name={[field.name, "rr_item_type"]}
rules={[{ required: true }]}
>
<Select
size="small"
style={{ width: "100%" }}
styles={{
selector: INLINE_TITLE_INPUT_STYLE
}}
options={[
{
value: "G",
label: t("bodyshop.fields.responsibilitycenters.item_type_gog")
},
{
value: "P",
label: t("bodyshop.fields.responsibilitycenters.item_type_paint")
},
{
value: "F",
label: t("bodyshop.fields.responsibilitycenters.item_type_freight")
}
]}
/>
</Form.Item>
</div>
</>
)}
</div>
}
wrapTitle
extra={
<Space align="center" size="small">
<Button
@@ -804,32 +1000,6 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
</Space>
}
>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
key={`${index}accountdesc`}
name={[field.name, "accountdesc"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
{!hasDMSKey && (
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_accountitem")}
key={`${index}accountitem`}
name={[field.name, "accountitem"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
)}
{hasDMSKey && !bodyshop.rr_dealerid && (
<Form.Item
label={t("bodyshop.fields.dms.dms_acctnumber")}
@@ -849,53 +1019,31 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Input onBlur={handleBlur} />
</Form.Item>
)}
{bodyshop.rr_dealerid && (
<>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.gogcode")}
key={`${index}rr_gogcode`}
name={[field.name, "rr_gogcode"]}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.item_type")}
key={`${index}rr_item_type`}
name={[field.name, "rr_item_type"]}
rules={[{ required: true }]}
>
<Select
options={[
{ value: "G", label: t("bodyshop.fields.responsibilitycenters.item_type_gog") },
{
value: "P",
label: t("bodyshop.fields.responsibilitycenters.item_type_paint")
},
{
value: "F",
label: t("bodyshop.fields.responsibilitycenters.item_type_freight")
}
]}
/>
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.taxable_flag")}
key={`${index}rr_cust_txbl_flag`}
name={[field.name, "rr_cust_txbl_flag"]}
rules={[{ required: true }]}
>
<Select
options={[
{ value: "T", label: t("bodyshop.fields.responsibilitycenters.taxable") },
{ value: "N", label: t("bodyshop.fields.responsibilitycenters.nontaxable") }
]}
/>
</Form.Item>
</>
)}
{bodyshop.rr_dealerid && [
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.gogcode")}
key={`${index}rr_gogcode`}
name={[field.name, "rr_gogcode"]}
col={{ xs: 24, md: 8, lg: 8, xl: 8, xxl: 8 }}
rules={[{ required: true }]}
>
<Input onBlur={handleBlur} />
</Form.Item>,
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.taxable_flag")}
key={`${index}rr_cust_txbl_flag`}
name={[field.name, "rr_cust_txbl_flag"]}
col={{ xs: 24, md: 8, lg: 8, xl: 8, xxl: 8 }}
rules={[{ required: true }]}
>
<Select
options={[
{ value: "T", label: t("bodyshop.fields.responsibilitycenters.taxable") },
{ value: "N", label: t("bodyshop.fields.responsibilitycenters.nontaxable") }
]}
/>
</Form.Item>
]}
</LayoutFormRow>
</Form.Item>
);
@@ -3459,20 +3607,61 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
return (
<div>
{fields.map((field, index) => {
const salesTaxCode =
form.getFieldValue(["md_responsibility_centers", "sales_tax_codes", field.name]) || {};
return (
<Form.Item key={field.key}>
<LayoutFormRow
id="sales_tax_codes"
noDivider
title={getFormListItemTitle(
t("bodyshop.fields.responsibilitycenters.sales_tax_codes.description"),
index,
salesTaxCode.description,
salesTaxCode.code
)}
title={
<div style={INLINE_TITLE_ROW_STYLE}>
<HolderOutlined style={INLINE_TITLE_HANDLE_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "1.2 1 320px"
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenters.sales_tax_codes.description")}
</div>
<Form.Item noStyle name={[field.name, "description"]} rules={[{ required: true }]}>
<Input
size="small"
placeholder={t(
"bodyshop.fields.responsibilitycenters.sales_tax_codes.description"
)}
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
<div aria-hidden style={INLINE_TITLE_SEPARATOR_STYLE} />
<div
style={{
...INLINE_TITLE_GROUP_STYLE,
flex: "0 1 140px",
maxWidth: 170
}}
>
<div style={INLINE_TITLE_LABEL_STYLE}>
{t("bodyshop.fields.responsibilitycenters.sales_tax_codes.code")}
</div>
<Form.Item noStyle name={[field.name, "code"]} rules={[{ required: true }]}>
<Input
size="small"
placeholder={t("bodyshop.fields.responsibilitycenters.sales_tax_codes.code")}
style={{
...INLINE_TITLE_INPUT_STYLE,
width: "100%"
}}
/>
</Form.Item>
</div>
</div>
}
wrapTitle
extra={
<Button
type="text"
@@ -3483,22 +3672,6 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
/>
}
>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.sales_tax_codes.description")}
key={`${index}description`}
name={[field.name, "description"]}
rules={[{ required: true }]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.sales_tax_codes.code")}
key={`${index}code`}
name={[field.name, "code"]}
rules={[{ required: true }]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenters.sales_tax_codes.federal")}
key={`${index}federal`}