merge feature/tables-split
This commit is contained in:
parent
9fdb540ede
commit
9439c39f5b
@ -6,7 +6,7 @@ import {
|
||||
withValue,
|
||||
} from 'client/hocs/Calculation';
|
||||
import { ElementType } from 'core/types/Calculation/Store/elements';
|
||||
import { omit } from 'lodash';
|
||||
import { pick } from 'lodash';
|
||||
import elementsActions from './elements/actions';
|
||||
import elementsComponents from './elements/components';
|
||||
import elementsComputedValues from './elements/computedValues';
|
||||
@ -23,7 +23,7 @@ export function buildElement(elementName, elementProps = {}) {
|
||||
case ElementType.Table: {
|
||||
return withTable(Component)({
|
||||
name: elementName,
|
||||
...omit(tables[elementName], ['columns', 'rows', 'options']),
|
||||
...pick(tables[elementName], ['options', 'callbacks', 'params']),
|
||||
});
|
||||
}
|
||||
case ElementType.Action: {
|
||||
|
||||
@ -14,7 +14,7 @@ const { PERIODS_NUMBER } = valuesConstants;
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
name: 'paymentRelation',
|
||||
title: 'Соотношение платежа',
|
||||
title: '% платежа',
|
||||
Component: InputNumber,
|
||||
props: {
|
||||
min: '0.01',
|
||||
@ -124,8 +124,10 @@ const callbacks: TableColumnCallbacks = {
|
||||
};
|
||||
|
||||
const features: TableColumnFeatures = {
|
||||
numerize: {
|
||||
columnTitle: 'Номер платежа',
|
||||
numerize: true,
|
||||
split: {
|
||||
rowsNumber: 12,
|
||||
columnsNumber: 3,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -37,9 +37,7 @@ const columns: TableColumn[] = [
|
||||
];
|
||||
|
||||
const features: TableColumnFeatures = {
|
||||
numerize: {
|
||||
columnTitle: 'Номер',
|
||||
},
|
||||
numerize: true,
|
||||
};
|
||||
|
||||
const params = { features };
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
import colors from 'client/UIKit/colors';
|
||||
import { Box } from 'client/UIKit/grid';
|
||||
import mq from 'client/UIKit/mq';
|
||||
import { pick } from 'lodash';
|
||||
import { toJS } from 'mobx';
|
||||
import { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const TableWrapper = styled(Box)`
|
||||
const TableStyles = styled(Box)`
|
||||
overflow-x: auto;
|
||||
table {
|
||||
width: 100%;
|
||||
${mq.laptop`
|
||||
width: 100%;
|
||||
overflow-x: none;
|
||||
`}
|
||||
table-layout: fixed;
|
||||
@ -59,56 +62,132 @@ const TableWrapper = styled(Box)`
|
||||
}
|
||||
`;
|
||||
|
||||
const TablesGrid = styled(Box)`
|
||||
display: ${props => props.split && 'grid'};
|
||||
grid-template-columns: 1fr;
|
||||
${mq.laptop`
|
||||
grid-gap: 10px;
|
||||
grid-template-columns: repeat(${props =>
|
||||
props?.split?.columnsNumber || '2'}, 1fr);
|
||||
`}
|
||||
`;
|
||||
|
||||
function buildHead(features, columns) {
|
||||
return () => (
|
||||
<thead>
|
||||
<tr>
|
||||
{features?.numerize && <th>{features.numerize.columnTitle || '#'}</th>}
|
||||
{columns.map(column => (
|
||||
<th key={column.name}>{column.title}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
);
|
||||
}
|
||||
|
||||
function buildBody(
|
||||
tableName,
|
||||
features,
|
||||
rows,
|
||||
columnsProps,
|
||||
withTableValue,
|
||||
partNumber,
|
||||
rowsNumber,
|
||||
) {
|
||||
return () => (
|
||||
<tbody>
|
||||
{rows.map((row, rowIndex) => {
|
||||
const partRowIndex = rowIndex + partNumber * rowsNumber;
|
||||
return (
|
||||
<tr key={row.name}>
|
||||
{features?.numerize && <td>{partRowIndex + 1}</td>}
|
||||
{Object.keys(row).map(propName => {
|
||||
const CellComponent = columnsProps[propName].Component;
|
||||
const Cell = withTableValue(CellComponent)({
|
||||
tableName,
|
||||
rowIndex: partRowIndex,
|
||||
propName,
|
||||
...columnsProps[propName].props,
|
||||
});
|
||||
return (
|
||||
<td key={propName}>
|
||||
<Cell />
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
);
|
||||
}
|
||||
|
||||
const useColumnsProps = columns =>
|
||||
useMemo(
|
||||
() =>
|
||||
columns.reduce((acc, col) => {
|
||||
acc[col.name] = pick(col, ['Component', 'props']);
|
||||
return acc;
|
||||
}, {}),
|
||||
[columns],
|
||||
);
|
||||
|
||||
const useSplit = (split, rows) => {
|
||||
return useMemo(() => {
|
||||
if (!split) {
|
||||
return {
|
||||
partsNumber: 1,
|
||||
};
|
||||
}
|
||||
const { rowsNumber } = split;
|
||||
if (rows?.length) {
|
||||
return { partsNumber: Math.ceil(rows?.length / rowsNumber), rowsNumber };
|
||||
}
|
||||
}, [rows?.length]);
|
||||
};
|
||||
|
||||
const Table = ({
|
||||
name: tableName,
|
||||
columns,
|
||||
rows,
|
||||
columns,
|
||||
params: { features },
|
||||
withTableValue,
|
||||
}) => {
|
||||
return (
|
||||
<TableWrapper>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{features && features.numerize && (
|
||||
<th>{features.numerize.columnTitle || '#'}</th>
|
||||
)}
|
||||
{columns.map(({ title }, ci) => {
|
||||
return <th key={ci}>{title}</th>;
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, ri) => {
|
||||
const rowProps = Object.keys(row);
|
||||
return (
|
||||
<tr key={ri}>
|
||||
{features && features.numerize && <td>{ri + 1}</td>}
|
||||
{rowProps.map((rowPropName, ki) => {
|
||||
const columnIndex = columns.findIndex(
|
||||
c => c.name === rowPropName,
|
||||
);
|
||||
const { Component } = columns[columnIndex];
|
||||
const Element = withTableValue(Component)({
|
||||
tableName,
|
||||
rowIndex: ri,
|
||||
propName: rowPropName,
|
||||
...columns[columnIndex].props,
|
||||
});
|
||||
return (
|
||||
<td key={ki}>
|
||||
<Element />
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</TableWrapper>
|
||||
);
|
||||
const split = useSplit(features?.split, rows);
|
||||
const rowsNumber = features?.split?.rowsNumber || rows?.length;
|
||||
const columnsProps = useColumnsProps(columns);
|
||||
|
||||
const Head = buildHead(features, columns);
|
||||
const tables = useMemo(() => {
|
||||
let tables = [];
|
||||
for (const partNumber of Array.from(Array(split.partsNumber).keys())) {
|
||||
const a = 0 + rowsNumber * partNumber;
|
||||
const b = rowsNumber + rowsNumber * partNumber;
|
||||
|
||||
const rowsPart = toJS(rows).slice(a, b);
|
||||
|
||||
const Body = buildBody(
|
||||
tableName,
|
||||
features,
|
||||
rowsPart,
|
||||
columnsProps,
|
||||
withTableValue,
|
||||
partNumber,
|
||||
rowsNumber,
|
||||
);
|
||||
tables.push(
|
||||
<TableStyles key={partNumber.toString()}>
|
||||
<table>
|
||||
<Head />
|
||||
<Body />
|
||||
</table>
|
||||
</TableStyles>,
|
||||
);
|
||||
}
|
||||
return tables;
|
||||
}, [rows.length]);
|
||||
|
||||
return <TablesGrid split={features?.split}>{tables}</TablesGrid>;
|
||||
};
|
||||
|
||||
export default Table;
|
||||
|
||||
@ -31,7 +31,7 @@ const withTableValue = callbacks => Component => ({
|
||||
tableName,
|
||||
rowIndex,
|
||||
propName,
|
||||
columnCallback: callbacks && callbacks[propName],
|
||||
columnCallback: callbacks?.[propName],
|
||||
});
|
||||
const { status } = useTableStatus({ tableName, rowIndex, propName });
|
||||
const { validateStatus, message } = useTableValidation({
|
||||
|
||||
@ -2,8 +2,8 @@ import { useStores } from '../useStores';
|
||||
|
||||
export const useOptions = elementName => {
|
||||
const { calculationStore } = useStores();
|
||||
const options = calculationStore.options[elementName] || [];
|
||||
const filter = calculationStore.filters[elementName];
|
||||
const options = calculationStore?.options?.[elementName] || [];
|
||||
const filter = calculationStore?.filters?.[elementName];
|
||||
|
||||
return {
|
||||
options: filter ? filter(options) : options,
|
||||
@ -13,11 +13,9 @@ export const useOptions = elementName => {
|
||||
export const useTableOptions = ({ tableName, rowIndex, propName }) => {
|
||||
const { calculationStore } = useStores();
|
||||
const options =
|
||||
(calculationStore.tables[tableName].options &&
|
||||
calculationStore.tables[tableName].options[propName]) ||
|
||||
[];
|
||||
calculationStore?.tables?.[tableName]?.options?.[propName] || [];
|
||||
const filter =
|
||||
calculationStore.tables[tableName].rows[rowIndex][propName].filter;
|
||||
calculationStore?.tables?.[tableName]?.rows?.[rowIndex]?.[propName]?.filter;
|
||||
|
||||
return {
|
||||
options: filter ? filter(options) : options,
|
||||
|
||||
@ -91,7 +91,8 @@ export const useTableValidation = ({
|
||||
const { calculationStore } = useStores();
|
||||
|
||||
const validationStatus =
|
||||
calculationStore.tables[tableName].rows[rowIndex][propName]?.validation;
|
||||
calculationStore?.tables?.[tableName]?.rows?.[rowIndex]?.[propName]
|
||||
?.validation;
|
||||
useEffect(() => {
|
||||
setValidation(validationStatus);
|
||||
}, [validationStatus]);
|
||||
|
||||
@ -44,8 +44,8 @@ export const useTableValue = ({
|
||||
const [currentValue, setCurrentValue] = useState(undefined);
|
||||
|
||||
//get row value from store
|
||||
const targetTable = calculationStore.tables[tableName];
|
||||
const sourceValue = targetTable.rows[rowIndex][propName].value;
|
||||
const targetTable = calculationStore?.tables?.[tableName];
|
||||
const sourceValue = targetTable?.rows?.[rowIndex]?.[propName]?.value;
|
||||
useEffect(() => {
|
||||
if (sourceValue !== undefined) {
|
||||
setCurrentValue(sourceValue);
|
||||
|
||||
@ -12,7 +12,10 @@ const tablesActions = {
|
||||
|
||||
getTableRowValues(tableName, rowIndex, paramName) {
|
||||
let values = {};
|
||||
const row = this.tables[tableName].rows[rowIndex];
|
||||
const row = this?.tables?.[tableName]?.rows?.[rowIndex];
|
||||
if (!row) {
|
||||
return values;
|
||||
}
|
||||
const keys = Object.keys(row);
|
||||
|
||||
let overridedValue;
|
||||
@ -41,7 +44,7 @@ const tablesActions = {
|
||||
|
||||
setTableRows(tableName, startIndex, override) {
|
||||
return rows => {
|
||||
if (this.tables[tableName] && this.tables[tableName].rows)
|
||||
if (this?.tables[tableName]?.rows)
|
||||
for (
|
||||
let i = startIndex, j = 0;
|
||||
i < startIndex + rows.length;
|
||||
|
||||
@ -15,7 +15,6 @@ import {
|
||||
TableNames,
|
||||
TableProps,
|
||||
TableValuesNames,
|
||||
TCellCallback,
|
||||
} from './tables';
|
||||
import { ResultValuesNames, TValue, TValues, ValuesNames } from './values';
|
||||
|
||||
@ -111,10 +110,8 @@ interface ICalculationTables {
|
||||
override?: boolean,
|
||||
) => ({
|
||||
options,
|
||||
callbacks,
|
||||
}: {
|
||||
options?: TableProps<(IBaseOption & TCRMEntity)[]>;
|
||||
callbacks?: TableProps<TCellCallback>;
|
||||
}) => void;
|
||||
}
|
||||
|
||||
|
||||
@ -51,9 +51,7 @@ export type TableColumn = {
|
||||
};
|
||||
|
||||
export type TableColumnFeatures = {
|
||||
numerize?: {
|
||||
columnTitle?: string;
|
||||
};
|
||||
[feature: string]: any;
|
||||
};
|
||||
|
||||
export type TableParams = {
|
||||
|
||||
Reference in New Issue
Block a user