PaymentsTable: connect rows to store

This commit is contained in:
Chika 2022-07-05 19:28:26 +03:00
parent 345245a0c9
commit 431f41edcd
7 changed files with 96 additions and 21 deletions

View File

@ -0,0 +1,14 @@
/* eslint-disable import/prefer-default-export */
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
import { useRowStatus } from 'stores/tables/payments/hooks';
import { usePaymentValue } from './hooks';
export function buildValueComponent<T>(index: number, Component: ComponentType<T>) {
return observer((props: T) => {
const [value, setValue] = usePaymentValue(index);
const status = useRowStatus(index);
return <Component value={value} setValue={setValue} status={status} {...props} />;
});
}

View File

@ -1,20 +1,25 @@
/* eslint-disable import/prefer-default-export */
import type { ColumnsType } from 'antd/lib/table';
import InputNumber from 'Elements/InputNumber';
import type { Payment } from './types';
export const columns: ColumnsType<Payment> = [
import { buildValueComponent } from './builders';
export const columns: ColumnsType<number> = [
{
key: 'num',
dataIndex: 'num',
title: '#',
width: '7%',
render: (_value, payment) => payment.num + 1,
render: (_value, _payment, index) => index + 1,
},
{
key: 'paymentRelation',
dataIndex: 'paymentRelation',
title: '% платежа',
render: (_value, payment) => <InputNumber value={payment.paymentRelation} />,
render: (_value, _payment, index) => {
const Component = buildValueComponent(index, InputNumber);
return <Component />;
},
},
];

View File

@ -0,0 +1,28 @@
/* eslint-disable import/prefer-default-export */
import { useEffect, useState } from 'react';
import { useRowValue } from 'stores/tables/payments/hooks';
import { useDebouncedCallback } from 'use-debounce';
export function usePaymentValue(index) {
const [storeValue, setStoreValue] = useRowValue(index);
const [value, setValue] = useState(storeValue);
// eslint-disable-next-line object-curly-newline
const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1000 });
useEffect(
() => {
if (storeValue !== value) {
debouncedSetStoreValue(value);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[value]
);
useEffect(() => {
setValue(storeValue);
}, [storeValue]);
return [value, setValue];
}

View File

@ -1,6 +1,7 @@
import { MAX_LEASING_PERIOD } from 'constants/values';
import Alert from 'Elements/Alert';
import Table from 'Elements/Table';
import { toJS } from 'mobx';
import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components';
@ -34,12 +35,20 @@ const PaymentsTable = observer(() => {
const store = useStore();
const { payments } = store.$tables;
const values = toJS(payments.values);
const dataSource = values.map((value, index) => ({
key: index,
num: index,
paymentRelation: value,
}));
return (
<TableWrapper>
<Table
size="small"
columns={columns}
dataSource={payments.values}
dataSource={dataSource}
pagination={{
defaultPageSize: 12,
pageSizeOptions: [12, MAX_LEASING_PERIOD],

View File

@ -1,5 +0,0 @@
export type Payment = {
key: string;
num: number;
paymentRelation: number;
};

View File

@ -0,0 +1,21 @@
import { useStore } from 'stores/hooks';
export function useRowValue(index) {
const { $tables } = useStore();
const storeValue = $tables.payments.getValue(index);
function setStoreValue(value) {
$tables.payments.setValue(index, value);
}
return [storeValue, setStoreValue];
}
export function useRowStatus(index) {
const { $tables } = useStore();
const status = $tables.payments.getStatus(index);
return status;
}

View File

@ -1,4 +1,3 @@
import type { Payment } from 'Components/Calculation/Form/Payments/PaymentsTable/types';
import type { Status } from 'Elements/types';
import type { IObservableArray } from 'mobx';
import { makeAutoObservable, observable } from 'mobx';
@ -8,34 +7,38 @@ import Validation from '../validation';
export default class PaymentsTable {
root: RootStore;
validation: Validation;
values: IObservableArray<Payment>;
values: IObservableArray<number>;
statuses: IObservableArray<Status>;
constructor(rootStore: RootStore) {
this.root = rootStore;
this.validation = new Validation();
this.values = observable<Payment>([]);
this.values = observable<number>([]);
this.statuses = observable<Status>([]);
makeAutoObservable(this);
}
getValue(num: number) {
const rowIndex = this.values.findIndex((value) => value.num === num);
return this.values[rowIndex];
getValue(index: number) {
return this.values[index];
}
setValues = (values: Payment[]) => {
setValues = (values: number[]) => {
this.values.replace(values);
};
getStatus(num: number) {
const rowIndex = this.values.findIndex((value) => value.num === num);
setValue = (index: number, value: number) => {
this.values[index] = value;
};
return this.statuses[rowIndex];
getStatus(index: number) {
return this.statuses[index];
}
setStatuses = (statuses: Status[]) => {
this.statuses.replace(statuses);
};
setStatus = (index: number, status: Status) => {
this.statuses[index] = status;
};
}