extend payments table for unlimited

This commit is contained in:
vchikalkin 2023-04-20 13:48:44 +03:00
parent 6c3b93c914
commit b38f25a039
7 changed files with 120 additions and 11 deletions

View File

@ -1,4 +1,4 @@
import { usePaymentValue } from './hooks';
import { usePaymentSum, usePaymentValue } from './hooks';
import { useRowStatus } from '@/stores/tables/payments/hooks';
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
@ -11,3 +11,12 @@ export function buildValueComponent<T>(index: number, Component: ComponentType<T
return <Component setValue={setValue} status={status} value={value} {...props} />;
});
}
export function buildSumComponent<T>(index: number, Component: ComponentType<T>) {
return observer((props: T) => {
const [value, setValue] = usePaymentSum(index);
const status = useRowStatus(index);
return <Component setValue={setValue} status={status} value={value} {...props} />;
});
}

View File

@ -1,14 +1,22 @@
/* eslint-disable canonical/sort-keys */
import { buildValueComponent } from './builders';
import { buildSumComponent, buildValueComponent } from './builders';
import type { ColumnsType } from 'antd/lib/table';
import { parser } from 'tools/number';
import { InputNumber } from 'ui/elements';
import { createFormatter } from 'ui/elements/InputNumber';
type Payment = {
key: number;
num: number;
paymentRelation: number;
paymentSum: number;
};
const formatter = createFormatter({
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
export const columns: ColumnsType<Payment> = [
{
key: 'num',
@ -27,4 +35,14 @@ export const columns: ColumnsType<Payment> = [
return <Component max={100} min={0} precision={payment.num === 0 ? 4 : 2} step={1} />;
},
},
{
key: 'paymentSum',
dataIndex: 'paymentSum',
title: 'Сумма',
render: (_value, payment) => {
const Component = buildSumComponent(payment.num, InputNumber);
return <Component min={0} precision={2} step={1000} formatter={formatter} parser={parser} />;
},
},
];

View File

@ -1,4 +1,4 @@
import { useRowValue } from '@/stores/tables/payments/hooks';
import { useRowSum, useRowValue } from '@/stores/tables/payments/hooks';
import { useEffect, useState } from 'react';
import { useDebouncedCallback } from 'use-debounce';
@ -20,3 +20,22 @@ export function usePaymentValue(index) {
return [value, setValue];
}
export function usePaymentSum(index) {
const [storeValue, setStoreValue] = useRowSum(index);
const [value, setValue] = useState(storeValue);
const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1000 });
useEffect(() => {
if (storeValue !== value) {
debouncedSetStoreValue(value);
}
}, [value]);
useEffect(() => {
setValue(storeValue);
}, [storeValue]);
return [value, setValue];
}

View File

@ -3,9 +3,12 @@ import { useStore } from '@/stores/hooks';
import { min } from '@/styles/mq';
import { computed } from 'mobx';
import { observer } from 'mobx-react-lite';
import { createContext, useContext, useMemo, useState } from 'react';
import styled from 'styled-components';
import { Segmented } from 'ui/antd';
import { Alert, Table } from 'ui/elements';
import { Box, Flex } from 'ui/grid';
import { useDebouncedCallback } from 'use-debounce';
const Grid = styled(Flex)`
flex-direction: column;
@ -47,6 +50,8 @@ const Validation = observer(() => {
return null;
});
export const ModeContext = createContext('paymentRelation');
const SPLIT_NUMBER = 12;
function TablePart({ num }) {
@ -55,16 +60,25 @@ function TablePart({ num }) {
const values = payments.values.slice(num * SPLIT_NUMBER, num * SPLIT_NUMBER + SPLIT_NUMBER);
const dataSource = values.map((value, index) => ({
const dataSource = values.map((_, index) => ({
key: index + num * SPLIT_NUMBER,
num: index + num * SPLIT_NUMBER,
paymentRelation: value,
}));
return (
<TableWrapper>
<Table size="small" columns={columns} dataSource={dataSource} pagination={false} />
</TableWrapper>
const mode = useContext(ModeContext);
return useMemo(
() => (
<TableWrapper>
<Table
size="small"
columns={columns.filter((x) => ['num', mode].includes(x.key))}
dataSource={dataSource}
pagination={false}
/>
</TableWrapper>
),
[dataSource, mode]
);
}
@ -84,11 +98,36 @@ const TablesGroup = observer(() => {
return <TablesGroupGrid>{tables}</TablesGroupGrid>;
});
function Mode({ setMode }) {
const { $process } = useStore();
if (!$process.has('Unlimited')) {
return false;
}
return (
<Segmented
block
options={[
{ label: 'Процент', value: 'paymentRelation' },
{ label: 'Сумма', value: 'paymentSum' },
]}
onChange={(value) => setMode(value)}
/>
);
}
export default function TablePayments() {
const [mode, setMode] = useState('paymentRelation');
const debouncedSetMode = useDebouncedCallback(setMode, 300);
return (
<Grid>
<Validation />
<TablesGroup />
<ModeContext.Provider value={mode}>
<Validation />
<Mode setMode={debouncedSetMode} />
<TablesGroup />
</ModeContext.Provider>
</Grid>
);
}

View File

@ -13,6 +13,18 @@ export function useRowValue(index) {
return [storeValue, setStoreValue];
}
export function useRowSum(index) {
const { $tables } = useStore();
const storeValue = computed(() => $tables.payments.getSum(index)).get();
function setStoreValue(value) {
$tables.payments.setSum(index, value);
}
return [storeValue, setStoreValue];
}
export function useRowStatus(index) {
const { $tables } = useStore();

View File

@ -10,6 +10,7 @@ export default class PaymentsTable {
private root: RootStore;
public validation: Validation;
public values: IObservableArray<number>;
public sums: IObservableArray<number>;
private statuses: IObservableArray<Status>;
private overridedStatus: IObservableValue<Status | undefined>;
@ -23,6 +24,7 @@ export default class PaymentsTable {
);
this.values = observable<number>([]);
this.sums = observable<number>([]);
this.statuses = observable<Status>([]);
this.overridedStatus = observable.box(undefined);
@ -36,6 +38,7 @@ export default class PaymentsTable {
() => this.values.length,
(length) => {
this.statuses.length = length;
this.sums.length = length;
}
);
}
@ -52,6 +55,14 @@ export default class PaymentsTable {
this.values[index] = value;
};
public getSum(index: number) {
return this.sums[index];
}
public setSum = (index: number, sum: number) => {
this.sums[index] = sum;
};
public setValues = (values: number[]) => {
this.values.replace(values);
};

View File

@ -0,0 +1 @@
export * from 'antd';