From 9dcc5321176fd56b07b1f7cab42b331f6cfc8a0e Mon Sep 17 00:00:00 2001 From: Chika Date: Wed, 16 Sep 2020 20:34:49 +0300 Subject: [PATCH] table management && filters/options to table value --- src/client/hocs/withStore.js | 18 +++++- src/client/hooks/useOptions.js | 17 +++++- src/client/hooks/useStatus.js | 10 +++ src/client/hooks/useValue.js | 12 ++-- .../stores/CalculationStore/Data/index.js | 5 ++ .../stores/CalculationStore/Data/tables.js | 41 +++++++++++++ .../stores/CalculationStore/Data/values.js | 37 +++++++++++ src/client/stores/CalculationStore/index.ts | 61 ++++--------------- src/client/tools/clone.js | 7 +++ src/core/config/initialTables.ts | 10 +++ src/core/types/stores.ts | 28 +++++++-- src/core/types/tables.ts | 5 +- 12 files changed, 185 insertions(+), 66 deletions(-) create mode 100644 src/client/stores/CalculationStore/Data/index.js create mode 100644 src/client/stores/CalculationStore/Data/tables.js create mode 100644 src/client/stores/CalculationStore/Data/values.js create mode 100644 src/client/tools/clone.js diff --git a/src/client/hocs/withStore.js b/src/client/hocs/withStore.js index 03f08c0..e697e26 100644 --- a/src/client/hocs/withStore.js +++ b/src/client/hocs/withStore.js @@ -1,10 +1,11 @@ import { useOptions } from 'client/hooks/useOptions'; -import { useStatus } from 'client/hooks/useStatus'; +import { useStatus, useTableStatus } from 'client/hooks/useStatus'; import { useStoreValue, useTableValue } from 'client/hooks/useValue'; import { useValidation } from 'client/hooks/useValidation'; import { observer } from 'mobx-react'; import React from 'react'; import { useStores } from 'client/hooks/useStores'; +import { useTableOptions } from 'client/hooks/useOptions'; export const withStoreValue = Component => ({ name, @@ -68,9 +69,22 @@ export const withTableValue = Component => ({ rowIndex, propName, }); + const { status } = useTableStatus({ tableName, rowIndex, propName }); + const { options, filter } = useTableOptions({ + tableName, + rowIndex, + propName, + }); return ( - + ); }; return observer(ComponentWithStore); diff --git a/src/client/hooks/useOptions.js b/src/client/hooks/useOptions.js index 8e0d474..da01fe7 100644 --- a/src/client/hooks/useOptions.js +++ b/src/client/hooks/useOptions.js @@ -7,6 +7,21 @@ export const useOptions = elementName => { return { options, - filter + filter, }; }; + +export const useTableOptions = ({ tableName, rowIndex, propName }) => { + const { calculationStore } = useStores(); + const options = + calculationStore.tables[tableName].options && + calculationStore.tables[tableName].options[rowIndex] + ? calculationStore.tables[tableName].options[rowIndex][propName] + : undefined; + const filter = + calculationStore.tables[tableName].filter && + calculationStore.tables[tableName].filter[rowIndex] + ? calculationStore.tables[tableName].filter[rowIndex][propName] + : undefined; + return { options, filter }; +}; diff --git a/src/client/hooks/useStatus.js b/src/client/hooks/useStatus.js index d1c017d..f97c4ca 100644 --- a/src/client/hooks/useStatus.js +++ b/src/client/hooks/useStatus.js @@ -6,3 +6,13 @@ export const useStatus = elementName => { return { status }; }; + +export const useTableStatus = ({ tableName, rowIndex, propName }) => { + const { calculationStore } = useStores(); + const status = + calculationStore.tables[tableName].status && + calculationStore.tables[tableName].status[rowIndex] + ? calculationStore.tables[tableName].status[rowIndex][propName] + : undefined; + return { status }; +}; diff --git a/src/client/hooks/useValue.js b/src/client/hooks/useValue.js index 7149275..69ff6b3 100644 --- a/src/client/hooks/useValue.js +++ b/src/client/hooks/useValue.js @@ -50,11 +50,13 @@ export const useTableValue = ({ tableName, rowIndex, propName }) => { // set value to store useEffect(() => { - calculationStore.setTableValue( - tableName, - rowIndex, - propName, - debouncedValue + calculationStore.setTableRow( + { + target: 'values', + tableName, + rowIndex, + }, + { [propName]: debouncedValue }, ); }, [calculationStore, debouncedValue, propName, rowIndex, tableName]); diff --git a/src/client/stores/CalculationStore/Data/index.js b/src/client/stores/CalculationStore/Data/index.js new file mode 100644 index 0000000..822bfab --- /dev/null +++ b/src/client/stores/CalculationStore/Data/index.js @@ -0,0 +1,5 @@ +import { tablesActions, tablesData } from './tables'; +import { valuesActions, valuesData } from './values'; + +export { valuesData, valuesActions, tablesData, tablesActions }; + diff --git a/src/client/stores/CalculationStore/Data/tables.js b/src/client/stores/CalculationStore/Data/tables.js new file mode 100644 index 0000000..4a543e8 --- /dev/null +++ b/src/client/stores/CalculationStore/Data/tables.js @@ -0,0 +1,41 @@ +import { cloneObject } from 'client/tools/clone'; +import initialTables from 'core/config/initialTables'; + +const tablesData = { + tables: initialTables, +}; + +const tablesActions = { + setTableRow({ tableName, rowIndex, target }, values) { + if (this.tables[tableName][target][rowIndex]) { + if (values && Object.keys(values).length > 0) { + for (let prop in values) { + this.tables[tableName][target][rowIndex][prop] = values[prop]; + } + } + } + }, + + insertTableRow({ tableName, rowIndex, row }) { + const targetTable = this.tables[tableName]; + if (!rowIndex) { + rowIndex = targetTable.values.length; + } + targetTable.values.splice(rowIndex, 0, row); + + const params = cloneObject(row, undefined); + if (targetTable.options) targetTable.options.splice(rowIndex, 0, params); + if (targetTable.filters) targetTable.filters.splice(rowIndex, 0, params); + if (targetTable.statuses) targetTable.statuses.splice(rowIndex, 0, params); + }, + + deleteTableRow(tableName, rowIndex) { + const targetTable = this.tables[tableName]; + targetTable.values.splice(rowIndex, 1); + targetTable.options.splice(rowIndex, 1); + targetTable.filters.splice(rowIndex, 1); + targetTable.statuses.splice(rowIndex, 1); + }, +}; + +export { tablesData, tablesActions }; diff --git a/src/client/stores/CalculationStore/Data/values.js b/src/client/stores/CalculationStore/Data/values.js new file mode 100644 index 0000000..c36dc9c --- /dev/null +++ b/src/client/stores/CalculationStore/Data/values.js @@ -0,0 +1,37 @@ +import initialOptions from 'core/config/initialOptions'; +import initialStatuses from 'core/config/initialStatuses'; +import initialValues from 'core/config/initialValues'; + +const valuesData = { + values: initialValues, + statuses: initialStatuses, + validations: {}, + options: initialOptions, + filters: {}, +}; + +const valuesActions = { + getValue(sourceValueName) { + return this.values[sourceValueName]; + }, + setValue(sourceValueName, newValue) { + this.values[sourceValueName] = newValue; + }, + + getStatus(elementName) { + return this.statuses[elementName]; + }, + setStatus(elementName, status) { + this.statuses[elementName] = status; + }, + + getValidation(elementName) { + return this.validations[elementName]; + }, + setValidation(elementName, validation) { + this.validations[elementName] = validation; + }, +}; + +export { valuesData, valuesActions }; + diff --git a/src/client/stores/CalculationStore/index.ts b/src/client/stores/CalculationStore/index.ts index 54bd715..77fc22c 100644 --- a/src/client/stores/CalculationStore/index.ts +++ b/src/client/stores/CalculationStore/index.ts @@ -1,63 +1,24 @@ import assignProperties from 'client/tools/assignProps'; -import initialOptions from 'core/config/initialOptions'; -import initialStatuses from 'core/config/initialStatuses'; -import initialValues from 'core/config/initialValues'; -import { ElementsNames } from 'core/types/elements'; -import { Status } from 'core/types/statuses'; -import { ValuesNames } from 'core/types/values'; +import { ICalculationStore } from 'core/types/stores'; import { autorun, observable, reaction, when } from 'mobx'; import CommonStore from '../CommonStore'; +import { + valuesData, + valuesActions, + tablesData, + tablesActions, +} from './Data/index'; import autorunEffects from './Effects/autorun'; import computedEffects from './Effects/computed'; import reactionEffects from './Effects/reaction'; import whenEffects from './Effects/when'; -import { ICalculationStore } from 'core/types/stores'; -import initialTables from 'core/config/initialTables'; const CalculationStore: ICalculationStore = observable( assignProperties( - { - values: initialValues, - getValue(sourceValueName: ValuesNames) { - return this.values[sourceValueName]; - }, - setValue(sourceValueName: ValuesNames, newValue: any) { - this.values[sourceValueName] = newValue; - }, - - statuses: initialStatuses, - getStatus(elementName: ElementsNames) { - return this.statuses[elementName]; - }, - - setStatus(elementName: ElementsNames, status: Status) { - this.statuses[elementName] = status; - }, - - validations: {}, - getValidation(elementName: ElementsNames) { - return this.validations[elementName]; - }, - setValidation(elementName: ElementsNames, validation: boolean) { - this.validations[elementName] = validation; - }, - options: initialOptions, - filters: {}, - }, - { - tables: initialTables, - setTableValue( - tableName: string, - rowIndex: number, - propName: string, - value: any, - ) { - this.tables[tableName].values[rowIndex][propName] = value; - }, - deleteTableRow(tableName: string, rowIndex: number) { - this.tables[tableName].values.splice(rowIndex, 1); - }, - }, + valuesData, + valuesActions, + tablesData, + tablesActions, computedEffects, ), ); diff --git a/src/client/tools/clone.js b/src/client/tools/clone.js new file mode 100644 index 0000000..5dee719 --- /dev/null +++ b/src/client/tools/clone.js @@ -0,0 +1,7 @@ +export function cloneObject(targetObj, replaceValue) { + let res = Object.assign({}, targetObj); + for (let prop in targetObj) { + res[prop] = replaceValue; + } + return res; +} diff --git a/src/core/config/initialTables.ts b/src/core/config/initialTables.ts index c275589..fb69148 100644 --- a/src/core/config/initialTables.ts +++ b/src/core/config/initialTables.ts @@ -11,6 +11,16 @@ const initialTables: IStoreTable = { number: '10', }, ], + statuses: [ + { + fruit: undefined, + number: undefined, + }, + { + fruit: undefined, + number: undefined, + }, + ], }, }; diff --git a/src/core/types/stores.ts b/src/core/types/stores.ts index 7eb0957..6874d35 100644 --- a/src/core/types/stores.ts +++ b/src/core/types/stores.ts @@ -1,4 +1,9 @@ -import { IStoreTable } from './tables'; +import { + IStoreTable, + TableNames, + TableValuesNames, + TableTargets, +} from './tables'; import { TValues, ValuesNames } from './values'; import { TElements, ElementsNames } from './elements'; import { TStatuses, Status } from './statuses'; @@ -20,11 +25,22 @@ export interface ICalculationStore { setValidation: (elementName: ElementsNames, validation: boolean) => void; tables: IStoreTable; - setTableValue: ( - tableName: string, - rowIndex: number, - propName: string, - value: any + setTableRow: ( + { + tableName, + rowIndex, + target, + }: { tableName: TableNames; rowIndex: number; target: TableTargets }, + values: { [prop in TableValuesNames]?: any }, ) => void; + insertTableRow: ({ + tableName: TableNames, + rowIndex, + row, + }: { + tableName: TableNames; + rowIndex?: number; + row: { [prop in TableValuesNames]?: any }; + }) => void; deleteTableRow: (tableName: string, rowIndex: number) => void; } diff --git a/src/core/types/tables.ts b/src/core/types/tables.ts index 3ebd909..ddc96cd 100644 --- a/src/core/types/tables.ts +++ b/src/core/types/tables.ts @@ -1,6 +1,7 @@ import { Status } from './statuses'; export type TableNames = 'fruitTable'; export type TableValuesNames = 'fruit' | 'number'; +export type TableTargets = 'values' | 'options' | 'statuses' | 'filters'; export type TTableValues = { [propName in TableValuesNames]?: T; @@ -10,7 +11,7 @@ export type IStoreTable = { [tableName in TableNames]: { values: TTableValues[]; options?: TTableValues[]; - status?: TTableValues[]; - filter?: TTableValues[]; + statuses?: TTableValues[]; + filters?: TTableValues[]; }; };