Merged in feature/IO-2636-Customized-Report-Filtering-Version-2 (pull request #1302)
Feature/IO-2636 Customized Report Filtering Version 2
This commit is contained in:
@@ -1,52 +1,352 @@
|
||||
import {Button, Card, Checkbox, Col, Form, Input, InputNumber, Row, Select} from "antd";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import React, {useCallback, useEffect, useMemo, useState} from "react";
|
||||
import {fetchFilterData} from "../../utils/RenderTemplate";
|
||||
import {DeleteFilled} from "@ant-design/icons";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {getOperatorsByType} from "../../utils/graphQLmodifier";
|
||||
import {getOrderOperatorsByType, getWhereOperatorsByType} from "../../utils/graphQLmodifier";
|
||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||
import {generateInternalReflections} from "./report-center-modal-utils";
|
||||
|
||||
export default function ReportCenterModalFiltersSortersComponent({form}) {
|
||||
|
||||
export default function ReportCenterModalFiltersSortersComponent({form, bodyshop}) {
|
||||
return (
|
||||
<Form.Item style={{margin: 0, padding: 0}} dependencies={["key"]}>
|
||||
{() => {
|
||||
const key = form.getFieldValue("key");
|
||||
return <RenderFilters form={form} templateId={key}/>;
|
||||
return <RenderFilters form={form} templateId={key} bodyshop={bodyshop}/>;
|
||||
}}
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
|
||||
function RenderFilters({templateId, form}) {
|
||||
/**
|
||||
* Filters Section
|
||||
* @param filters
|
||||
* @param form
|
||||
* @param bodyshop
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
function FiltersSection({filters, form, bodyshop}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<Card type='inner' title={t('reportcenter.labels.advanced_filters_filters')} style={{marginTop: '10px'}}>
|
||||
<Form.List name={["filters"]}>
|
||||
{(fields, {add, remove, move}) => {
|
||||
return (
|
||||
<div>
|
||||
{fields.map((field, index) => (
|
||||
<Form.Item key={field.key}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={10}>
|
||||
<Form.Item
|
||||
key={`${index}field`}
|
||||
label={t('reportcenter.labels.advanced_filters_filter_field')}
|
||||
name={[field.name, "field"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
onChange={() => {
|
||||
// Clear related Fields
|
||||
form.setFieldValue(['filters', field.name, 'value'], null);
|
||||
form.setFieldValue(['filters', field.name, 'operator'], null);
|
||||
}}
|
||||
options={
|
||||
filters.map((f) => {
|
||||
return {
|
||||
value: f.name,
|
||||
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item dependencies={[['filters', field.name, "field"]]}>
|
||||
{
|
||||
() => {
|
||||
const name = form.getFieldValue(['filters', field.name, "field"]);
|
||||
const type = filters.find(f => f.name === name)?.type;
|
||||
|
||||
return <Form.Item
|
||||
key={`${index}operator`}
|
||||
label={t('reportcenter.labels.advanced_filters_filter_operator')}
|
||||
name={[field.name, "operator"]}
|
||||
dependencies={[]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
options={getWhereOperatorsByType(type)}/>
|
||||
</Form.Item>
|
||||
}
|
||||
}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item dependencies={[['filters', field.name, "field"]]}>
|
||||
{
|
||||
() => {
|
||||
const name = form.getFieldValue(['filters', field.name, "field"]);
|
||||
const type = filters.find(f => f.name === name)?.type;
|
||||
const reflector = filters.find(f => f.name === name)?.reflector;
|
||||
|
||||
return <Form.Item
|
||||
key={`${index}value`}
|
||||
label={t('reportcenter.labels.advanced_filters_filter_value')}
|
||||
name={[field.name, "value"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{
|
||||
(() => {
|
||||
const generateReflections = (reflector) => {
|
||||
if (!reflector) return [];
|
||||
|
||||
const {name} = reflector;
|
||||
const path = name?.split('.');
|
||||
const upperPath = path?.[0];
|
||||
const finalPath = path?.slice(1).join('.');
|
||||
|
||||
return generateInternalReflections({
|
||||
bodyshop,
|
||||
upperPath,
|
||||
finalPath
|
||||
});
|
||||
};
|
||||
|
||||
const reflections = reflector ? generateReflections(reflector) : [];
|
||||
const fieldPath = [[field.name, "value"]];
|
||||
|
||||
if (reflections.length > 0) {
|
||||
return (
|
||||
<Select
|
||||
options={reflections}
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
onChange={(value) => {
|
||||
form.setFieldValue(fieldPath, value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === "number") {
|
||||
return (
|
||||
<InputNumber
|
||||
onChange={(value) => form.setFieldValue(fieldPath, value)}/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Input
|
||||
onChange={(e) => form.setFieldValue(fieldPath, e.target.value)}/>
|
||||
);
|
||||
})()
|
||||
}
|
||||
</Form.Item>
|
||||
}
|
||||
}
|
||||
</Form.Item>
|
||||
|
||||
</Col>
|
||||
<Col span={2}>
|
||||
<DeleteFilled
|
||||
style={{margin: "1rem", paddingTop: '23px'}}
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
style={{width: "100%"}}
|
||||
>
|
||||
{t("general.actions.add")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorters Section
|
||||
* @param sorters
|
||||
* @param form
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
function SortersSection({sorters, form}) {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<Card type='inner' title={t('reportcenter.labels.advanced_filters_sorters')} style={{marginTop: '10px'}}>
|
||||
<Form.List name={["sorters"]}>
|
||||
{(fields, {add, remove, move}) => {
|
||||
return (
|
||||
<div>
|
||||
Sorters
|
||||
{fields.map((field, index) => (
|
||||
<Form.Item key={field.key}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={11}>
|
||||
<Form.Item
|
||||
key={`${index}field`}
|
||||
label={t('reportcenter.labels.advanced_filters_sorter_field')}
|
||||
name={[field.name, "field"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
options={
|
||||
sorters.map((f) => ({
|
||||
value: f.name,
|
||||
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
|
||||
}))
|
||||
}
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={11}>
|
||||
<Form.Item
|
||||
key={`${index}direction`}
|
||||
label={t('reportcenter.labels.advanced_filters_sorter_direction')}
|
||||
name={[field.name, "direction"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
options={getOrderOperatorsByType()}
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<Col span={2}>
|
||||
<DeleteFilled
|
||||
style={{margin: "1rem", paddingTop: '23px'}}
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
style={{width: "100%"}}
|
||||
>
|
||||
{t("general.actions.add")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Filters
|
||||
* @param templateId
|
||||
* @param form
|
||||
* @param bodyshop
|
||||
* @returns {JSX.Element|null}
|
||||
* @constructor
|
||||
*/
|
||||
function RenderFilters({templateId, form, bodyshop}) {
|
||||
const [state, setState] = useState(null);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const {t} = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
setIsLoading(true);
|
||||
const data = await fetchFilterData({name: templateId});
|
||||
if (data?.success) {
|
||||
setState(data.data);
|
||||
} else {
|
||||
setState(null);
|
||||
}
|
||||
setIsLoading(false);
|
||||
};
|
||||
const fetch = useCallback(async () => {
|
||||
// Reset all the filters and Sorters.
|
||||
form.resetFields(['filters']);
|
||||
form.resetFields(['sorters']);
|
||||
form.resetFields(['defaultSorters']);
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
const data = await fetchFilterData({name: templateId});
|
||||
|
||||
// We have Success
|
||||
if (data?.success) {
|
||||
if (data?.data?.sorters && data?.data?.sorters.length > 0) {
|
||||
const defaultSorters = data?.data?.sorters.filter((sorter) => sorter.hasOwnProperty('default')).map((sorter) => {
|
||||
return {
|
||||
field: sorter.name,
|
||||
direction: sorter.default.direction
|
||||
};
|
||||
}).sort((a, b) => a.default.order - b.default.order);
|
||||
|
||||
form.setFieldValue('defaultSorters', JSON.stringify(defaultSorters));
|
||||
}
|
||||
// Set the state
|
||||
setState(data.data);
|
||||
}
|
||||
// Something went wrong fetching filter data
|
||||
else {
|
||||
setState(null);
|
||||
}
|
||||
setIsLoading(false);
|
||||
}, [templateId, form]);
|
||||
|
||||
useEffect(() => {
|
||||
if (templateId) {
|
||||
fetch();
|
||||
|
||||
}
|
||||
}, [templateId]);
|
||||
}, [templateId, fetch]);
|
||||
|
||||
const filters = useMemo(() => state?.filters || [], [state]);
|
||||
const sorters = useMemo(() => state?.sorters || [], [state]);
|
||||
|
||||
// Conditional display of filters and sorters
|
||||
if (!templateId) return null;
|
||||
if (isLoading) return <LoadingSkeleton/>;
|
||||
if (!state) return null;
|
||||
|
||||
// Filters and Sorters data available
|
||||
return (
|
||||
<div style={{marginTop: '10px'}}>
|
||||
<Checkbox
|
||||
@@ -56,215 +356,11 @@ function RenderFilters({templateId, form}) {
|
||||
/>
|
||||
{visible && (
|
||||
<div>
|
||||
{state.filters && state.filters.length > 0 && (
|
||||
<Card type='inner' title={ t('reportcenter.labels.advanced_filters_filters')} style={{marginTop: '10px'}}>
|
||||
<Form.List name={["filters"]}>
|
||||
{(fields, {add, remove, move}) => {
|
||||
return (
|
||||
<div>
|
||||
{fields.map((field, index) => (
|
||||
<Form.Item key={field.key}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={10}>
|
||||
<Form.Item
|
||||
key={`${index}field`}
|
||||
label="field"
|
||||
name={[field.name, "field"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
options={
|
||||
state.filters
|
||||
? state.filters.map((f) => {
|
||||
return {
|
||||
value: f.name,
|
||||
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
|
||||
}
|
||||
})
|
||||
: []
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item dependencies={[['filters', field.name, "field"]]}>
|
||||
{
|
||||
() => {
|
||||
const name = form.getFieldValue(['filters', field.name, "field"]);
|
||||
const type = state.filters.find(f => f.name === name)?.type;
|
||||
|
||||
return <Form.Item
|
||||
key={`${index}operator`}
|
||||
label="operator"
|
||||
name={[field.name, "operator"]}
|
||||
dependencies={[]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select options={getOperatorsByType(type)}/>
|
||||
</Form.Item>
|
||||
}
|
||||
}
|
||||
</Form.Item>
|
||||
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item dependencies={[['filters', field.name, "field"]]}>
|
||||
{
|
||||
() => {
|
||||
const name = form.getFieldValue(['filters', field.name, "field"]);
|
||||
const type = state.filters.find(f => f.name === name)?.type;
|
||||
|
||||
return <Form.Item
|
||||
key={`${index}value`}
|
||||
label="value"
|
||||
name={[field.name, "value"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{type === 'number' ?
|
||||
<InputNumber
|
||||
onChange={(value) => {
|
||||
form.setFieldsValue({[field.name]: {value: parseInt(value)}});
|
||||
}}
|
||||
/>
|
||||
:
|
||||
<Input
|
||||
onChange={(value) => {
|
||||
form.setFieldsValue({[field.name]: {value: value.toString()}});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</Form.Item>
|
||||
}
|
||||
}
|
||||
</Form.Item>
|
||||
|
||||
</Col>
|
||||
<Col span={2}>
|
||||
<DeleteFilled
|
||||
style={{margin: "1rem"}}
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
style={{width: "100%"}}
|
||||
>
|
||||
{t("general.actions.add")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
|
||||
</Card>
|
||||
{filters.length > 0 && (
|
||||
<FiltersSection filters={filters} form={form} bodyshop={bodyshop}/>
|
||||
)}
|
||||
{state.sorters && state.sorters.length > 0 && (
|
||||
<Card type='inner' title={ t('reportcenter.labels.advanced_filters_sorters')} style={{marginTop: '10px'}}>
|
||||
<Form.List name={["sorters"]}>
|
||||
{(fields, {add, remove, move}) => {
|
||||
return (
|
||||
<div>
|
||||
Sorters
|
||||
{fields.map((field, index) => (
|
||||
<Form.Item key={field.key}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={11}>
|
||||
<Form.Item
|
||||
key={`${index}field`}
|
||||
label="field"
|
||||
name={[field.name, "field"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
options={
|
||||
state.sorters
|
||||
? state.sorters.map((f) => ({
|
||||
value: f.name,
|
||||
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={11}>
|
||||
<Form.Item
|
||||
key={`${index}direction`}
|
||||
label="direction"
|
||||
name={[field.name, "direction"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
options={[
|
||||
{value: "desc", label: "Descending"},
|
||||
{value: "asc", label: "Ascending"},
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<Col span={2}>
|
||||
<DeleteFilled
|
||||
style={{margin: "1rem"}}
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
style={{width: "100%"}}
|
||||
>
|
||||
{t("general.actions.add")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
</Card>
|
||||
{sorters.length > 0 && (
|
||||
<SortersSection sorters={sorters} form={form}/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import {uniqBy} from "lodash";
|
||||
|
||||
/**
|
||||
* Get value from path
|
||||
* @param obj
|
||||
* @param path
|
||||
* @returns {*}
|
||||
*/
|
||||
const getValueFromPath = (obj, path) => path.split('.').reduce((prev, curr) => prev?.[curr], obj);
|
||||
|
||||
/**
|
||||
* Valid internal reflections
|
||||
* Note: This is intended for future functionality
|
||||
* @type {{special: string[], bodyshop: [{name: string, type: string}]}}
|
||||
*/
|
||||
const VALID_INTERNAL_REFLECTIONS = {
|
||||
bodyshop: [
|
||||
{
|
||||
name: 'md_ro_statuses.statuses',
|
||||
type: 'kv-to-v'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate options
|
||||
* @param bodyshop
|
||||
* @param path
|
||||
* @param labelPath
|
||||
* @param valuePath
|
||||
* @returns {{label: *, value: *}[]}
|
||||
*/
|
||||
const generateOptionsFromObject = (bodyshop, path, labelPath, valuePath) => {
|
||||
const options = getValueFromPath(bodyshop, path);
|
||||
return uniqBy(Object.values(options).map((value) => ({
|
||||
label: value[labelPath],
|
||||
value: value[valuePath],
|
||||
})), 'value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate special reflections
|
||||
* @param bodyshop
|
||||
* @param finalPath
|
||||
* @returns {{label: *, value: *}[]|{label: *, value: *}[]|{label: string, value: *}[]|*[]}
|
||||
*/
|
||||
const generateSpecialReflections = (bodyshop, finalPath) => {
|
||||
switch (finalPath) {
|
||||
case 'cost_centers':
|
||||
return generateOptionsFromObject(bodyshop, 'md_responsibility_centers.costs', 'name', 'name');
|
||||
// Special case because Categories is an Array, not an Object.
|
||||
case 'categories':
|
||||
const catOptions = getValueFromPath(bodyshop, 'md_categories');
|
||||
return uniqBy(catOptions.map((value) => ({
|
||||
label: value,
|
||||
value: value,
|
||||
})), 'value');
|
||||
case 'insurance_companies':
|
||||
return generateOptionsFromObject(bodyshop, 'md_ins_cos', 'name', 'name');
|
||||
case 'employee_teams':
|
||||
return generateOptionsFromObject(bodyshop, 'employee_teams', 'name', 'id');
|
||||
// Special case because Employees uses a concatenation of first_name and last_name
|
||||
case 'employees':
|
||||
const employeesOptions = getValueFromPath(bodyshop, 'employees');
|
||||
return uniqBy(Object.values(employeesOptions).map((value) => ({
|
||||
label: `${value.first_name} ${value.last_name}`,
|
||||
value: value.id,
|
||||
})), 'value');
|
||||
case 'last_names':
|
||||
return generateOptionsFromObject(bodyshop, 'employees', 'last_name', 'last_name');
|
||||
case 'first_names':
|
||||
return generateOptionsFromObject(bodyshop, 'employees', 'first_name', 'first_name');
|
||||
case 'job_statuses':
|
||||
const statusOptions = getValueFromPath(bodyshop, 'md_ro_statuses.statuses');
|
||||
return Object.values(statusOptions).map((value) => ({
|
||||
label: value,
|
||||
value
|
||||
}));
|
||||
default:
|
||||
console.error('Invalid Special reflection provided by Report Filters');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate bodyshop reflections
|
||||
* @param bodyshop
|
||||
* @param finalPath
|
||||
* @returns {{label: *, value: *}[]|*[]}
|
||||
*/
|
||||
const generateBodyshopReflections = (bodyshop, finalPath) => {
|
||||
const options = getValueFromPath(bodyshop, finalPath);
|
||||
const reflectionRenderer = VALID_INTERNAL_REFLECTIONS.bodyshop.find(reflection => reflection.name === finalPath);
|
||||
if (reflectionRenderer?.type === 'kv-to-v') {
|
||||
return Object.values(options).map((value) => ({
|
||||
label: value,
|
||||
value
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate internal reflections based on the path and bodyshop
|
||||
* @param bodyshop
|
||||
* @param upperPath
|
||||
* @param finalPath
|
||||
* @returns {{label: *, value: *}[]|[]|{label: *, value: *}[]|{label: string, value: *}[]|{label: *, value: *}[]|*[]}
|
||||
*/
|
||||
const generateInternalReflections = ({bodyshop, upperPath, finalPath}) => {
|
||||
switch (upperPath) {
|
||||
case 'special':
|
||||
return generateSpecialReflections(bodyshop, finalPath);
|
||||
case 'bodyshop':
|
||||
return generateBodyshopReflections(bodyshop, finalPath);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export {generateInternalReflections,}
|
||||
@@ -16,9 +16,11 @@ import EmployeeSearchSelect from "../employee-search-select/employee-search-sele
|
||||
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
|
||||
import "./report-center-modal.styles.scss";
|
||||
import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component";
|
||||
import {selectBodyshop} from "../../redux/user/user.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
reportCenterModal: selectReportCenter,
|
||||
reportCenterModal: selectReportCenter,
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
@@ -28,7 +30,7 @@ export default connect(
|
||||
mapDispatchToProps
|
||||
)(ReportCenterModalComponent);
|
||||
|
||||
export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
export function ReportCenterModalComponent({reportCenterModal, bodyshop}) {
|
||||
const [form] = Form.useForm();
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
@@ -64,22 +66,28 @@ export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
const end = values.dates ? values.dates[1] : null;
|
||||
const { id } = values;
|
||||
|
||||
await GenerateDocument(
|
||||
{
|
||||
const templateConfig = {
|
||||
name: values.key,
|
||||
variables: {
|
||||
...(start
|
||||
? { start: moment(start).startOf("day").format("YYYY-MM-DD") }
|
||||
: {}),
|
||||
...(end ? { end: moment(end).endOf("day").format("YYYY-MM-DD") } : {}),
|
||||
...(start ? { starttz: moment(start).startOf("day") } : {}),
|
||||
...(end ? { endtz: moment(end).endOf("day") } : {}),
|
||||
...(start
|
||||
? {start: moment(start).startOf("day").format("YYYY-MM-DD")}
|
||||
: {}),
|
||||
...(end ? {end: moment(end).endOf("day").format("YYYY-MM-DD")} : {}),
|
||||
...(start ? {starttz: moment(start).startOf("day")} : {}),
|
||||
...(end ? {endtz: moment(end).endOf("day")} : {}),
|
||||
|
||||
...(id ? { id: id } : {}),
|
||||
...(id ? {id: id} : {}),
|
||||
},
|
||||
filters: values.filters,
|
||||
sorters: values.sorters,
|
||||
},
|
||||
};
|
||||
|
||||
if (_.isString(values.defaultSorters) && !_.isEmpty(values.defaultSorters)) {
|
||||
templateConfig.defaultSorters = JSON.parse(values.defaultSorters);
|
||||
}
|
||||
|
||||
await GenerateDocument(
|
||||
templateConfig,
|
||||
{
|
||||
to: values.to,
|
||||
subject: Templates[values.key]?.subject,
|
||||
@@ -117,7 +125,8 @@ export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
value={search}
|
||||
/>
|
||||
<Form.Item
|
||||
<Form.Item name="defaultSorters" hidden/>
|
||||
<Form.Item
|
||||
name="key"
|
||||
label={t("reportcenter.labels.key")}
|
||||
// className="radio-group-columns"
|
||||
@@ -181,7 +190,7 @@ export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
<ReportCenterModalFiltersSortersComponent form={form} />
|
||||
<ReportCenterModalFiltersSortersComponent form={form} bodyshop={bodyshop} />
|
||||
<Form.Item style={{margin: 0, padding: 0}} dependencies={["key"]}>
|
||||
{() => {
|
||||
const key = form.getFieldValue("key");
|
||||
@@ -236,6 +245,9 @@ export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
{() => {
|
||||
const key = form.getFieldValue("key");
|
||||
const datedisable = Templates[key] && Templates[key].datedisable;
|
||||
|
||||
// TODO: MERGE NOTE, Ranges turns to presets in DatePicker.RangePicker
|
||||
|
||||
if (datedisable !== true) {
|
||||
return (
|
||||
<Form.Item
|
||||
@@ -250,7 +262,7 @@ export function ReportCenterModalComponent({reportCenterModal}) {
|
||||
>
|
||||
<DatePicker.RangePicker
|
||||
format="MM/DD/YYYY"
|
||||
presets={DatePickerRanges}
|
||||
ranges={DatePickerRanges}
|
||||
/>
|
||||
</Form.Item>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user