tachybase_todo/packages/core/utils/src/assign.ts

116 lines
2.7 KiB
TypeScript
Raw Normal View History

2021-12-06 21:23:34 +08:00
import deepmerge from 'deepmerge';
import lodash from 'lodash';
feat(filter-blocks): support filter-blocks (#1505) * refactor: audit log (#1516) * refactor: audit-log * refactor: audit-log fix view action * refactor: audit-log view fix * refactor(audit-log): collection field fix * refactor: audit-log view field fix * refactor(audit-log): support fixedBlock * refactor(audit-log): i18n fix * feat(filter-blocks): support form-block * feat(filter-blocks): add FilterProvider * feat: filter data blocks * perf: use useMemo * refactor: rename * feat: collect filter params * refactor: rename * refactor: remove useless code * feat: add 'Connect data blocks' option * feat: support 'x-filter-targets' to save data-blocks * refactor: extract Form.FilterFormDesigner * feat: extract FormItem.FilterFormDesigner * refactor: extract common editing options * feat: support to set operator * feat: use operator created by user * fix: improve loading * fix: merge prev params * feat: support reset * refactor: rename * chore: left a TODO * feat: add Table.FilterDesigner * feat: support filter-table * refactor: reduce code * feat: handle click event of table row * feat: support to connect association collection * feat: support Collapse * feat: show empty * refactor: optimize readability * fix: keep state as latest * fix: highlight row on selected * feat: highlight data block on hover * fix: avoid misuse * chore: reduce code * fix(Table): support to cancel select * fix(Collapse): merge multiple filter params * chore: make to pass CI * feat: merge all filter params * refactor: remove useless code * fix: undefined * fix(Form): fix bug with association fields * chore: fix typo * fix: use title * chore: avoid infinite loops * test: cancel comments * fix: make ci normal * fix: filter down non-association fields * fix: fix page crash * fix: use correct operator * fix: avoid infinte loops * style: optimize style on hover * fix: avoid crash * chore: optimize empty description * fix: avoid targetKey empty * refactor: use getTargetKey instead * fix: filter out unfilterable fields * refactor: avoid to invoke hook multiple times * refactor: reduce the judgment conditions of component * fix: group fields in the right way * fix: fix error of type * fix: fix error on no FilterBlockProvider * fix(Table): fix fexed-block bug * chore: reduce gap * fix(Form): use AssociationSelect by default * fix: remove g2plot blocks * fix(Form): remove 'Display association fields' * fix(Table): use radio * fix(Table): no need Actions * fix: fix template problem * fix(Table): keep only 'filter' and 'refresh' * fix: use collection name as identifier for data blocks * fix: make sure all fields are editable * fix(Form): remove custom actions * fix(Details): display empty component on no data * feat(Form): support association fields * refactor: rename * feat(Form): support for deep-level association fields * Revert "fix(Table): keep only 'filter' and 'refresh'" This reverts commit 61a1d101a7d15223cfd3523adb33567fff545568. * Revert "fix(Table): no need Actions" This reverts commit 8314629e92fb3b5b7ec1c97904a42c76c43e4d4a. * Revert "fix(Table): use radio" This reverts commit c6f009740e1835f9762653a721ff64f52d0994cf. * feat(Table): highlight row on selected * feat: support to cacel highlight * fix: type error * feat: remove Table from filter list * fix(Table): highlight rows problem * refactor: remove usless code * refactor(Collapse): detach from Table * fix(Table): highlighting row problem * fix: translate problem * fix(Collapse): fix error of useProps * fix(Table): avoid undefined * Update Details.tsx * Update DetailsBlockProvider.tsx * refactor: rename target.name to target.uid * fix: add translate * style: add padding --------- Co-authored-by: anuoua <anuoua@gmail.com> Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-20 17:40:16 +08:00
import { isPlainObject } from './common';
2021-12-06 21:23:34 +08:00
type MergeStrategyType = 'merge' | 'deepMerge' | 'overwrite' | 'andMerge' | 'orMerge' | 'intersect' | 'union';
type MergeStrategyFunc = (x: any, y: any) => any;
export type MergeStrategy = MergeStrategyType | MergeStrategyFunc;
export interface MergeStrategies {
[key: string]: MergeStrategy;
}
function getEnumerableOwnPropertySymbols(target: any): any[] {
return Object.getOwnPropertySymbols
? Object.getOwnPropertySymbols(target).filter((symbol) => target.propertyIsEnumerable(symbol))
: [];
}
function getKeys(target: any) {
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target));
}
export const mergeStrategies = new Map<MergeStrategyType, MergeStrategyFunc>();
mergeStrategies.set('overwrite', (_, y) => {
if (typeof y === 'string') {
y = y.split(',');
}
2021-12-06 21:23:34 +08:00
return y;
});
mergeStrategies.set('andMerge', (x, y) => {
if (!x && !y) {
return;
}
if (!x) {
return y;
}
if (!y) {
return x;
}
return {
$and: [x, y],
};
});
mergeStrategies.set('orMerge', (x, y) => {
if (!x && !y) {
return;
}
if (!x) {
return y;
}
if (!y) {
return x;
}
return {
$or: [x, y],
};
});
mergeStrategies.set('deepMerge', (x, y) => {
return isPlainObject(x) && isPlainObject(y)
? deepmerge(x, y, {
feat(filter-blocks): support filter-blocks (#1505) * refactor: audit log (#1516) * refactor: audit-log * refactor: audit-log fix view action * refactor: audit-log view fix * refactor(audit-log): collection field fix * refactor: audit-log view field fix * refactor(audit-log): support fixedBlock * refactor(audit-log): i18n fix * feat(filter-blocks): support form-block * feat(filter-blocks): add FilterProvider * feat: filter data blocks * perf: use useMemo * refactor: rename * feat: collect filter params * refactor: rename * refactor: remove useless code * feat: add 'Connect data blocks' option * feat: support 'x-filter-targets' to save data-blocks * refactor: extract Form.FilterFormDesigner * feat: extract FormItem.FilterFormDesigner * refactor: extract common editing options * feat: support to set operator * feat: use operator created by user * fix: improve loading * fix: merge prev params * feat: support reset * refactor: rename * chore: left a TODO * feat: add Table.FilterDesigner * feat: support filter-table * refactor: reduce code * feat: handle click event of table row * feat: support to connect association collection * feat: support Collapse * feat: show empty * refactor: optimize readability * fix: keep state as latest * fix: highlight row on selected * feat: highlight data block on hover * fix: avoid misuse * chore: reduce code * fix(Table): support to cancel select * fix(Collapse): merge multiple filter params * chore: make to pass CI * feat: merge all filter params * refactor: remove useless code * fix: undefined * fix(Form): fix bug with association fields * chore: fix typo * fix: use title * chore: avoid infinite loops * test: cancel comments * fix: make ci normal * fix: filter down non-association fields * fix: fix page crash * fix: use correct operator * fix: avoid infinte loops * style: optimize style on hover * fix: avoid crash * chore: optimize empty description * fix: avoid targetKey empty * refactor: use getTargetKey instead * fix: filter out unfilterable fields * refactor: avoid to invoke hook multiple times * refactor: reduce the judgment conditions of component * fix: group fields in the right way * fix: fix error of type * fix: fix error on no FilterBlockProvider * fix(Table): fix fexed-block bug * chore: reduce gap * fix(Form): use AssociationSelect by default * fix: remove g2plot blocks * fix(Form): remove 'Display association fields' * fix(Table): use radio * fix(Table): no need Actions * fix: fix template problem * fix(Table): keep only 'filter' and 'refresh' * fix: use collection name as identifier for data blocks * fix: make sure all fields are editable * fix(Form): remove custom actions * fix(Details): display empty component on no data * feat(Form): support association fields * refactor: rename * feat(Form): support for deep-level association fields * Revert "fix(Table): keep only 'filter' and 'refresh'" This reverts commit 61a1d101a7d15223cfd3523adb33567fff545568. * Revert "fix(Table): no need Actions" This reverts commit 8314629e92fb3b5b7ec1c97904a42c76c43e4d4a. * Revert "fix(Table): use radio" This reverts commit c6f009740e1835f9762653a721ff64f52d0994cf. * feat(Table): highlight row on selected * feat: support to cacel highlight * fix: type error * feat: remove Table from filter list * fix(Table): highlight rows problem * refactor: remove usless code * refactor(Collapse): detach from Table * fix(Table): highlighting row problem * fix: translate problem * fix(Collapse): fix error of useProps * fix(Table): avoid undefined * Update Details.tsx * Update DetailsBlockProvider.tsx * refactor: rename target.name to target.uid * fix: add translate * style: add padding --------- Co-authored-by: anuoua <anuoua@gmail.com> Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-20 17:40:16 +08:00
arrayMerge: (x, y) => y,
})
2021-12-06 21:23:34 +08:00
: y;
});
mergeStrategies.set('merge', (x, y) => {
return isPlainObject(x) && isPlainObject(y) ? Object.assign(x, y) : y;
});
mergeStrategies.set('union', (x, y) => {
if (typeof x === 'string') {
x = x.split(',');
}
if (typeof y === 'string') {
y = y.split(',');
}
return lodash.uniq((x || []).concat(y || [])).filter(Boolean);
2021-12-06 21:23:34 +08:00
});
feat(filter-blocks): support filter-blocks (#1505) * refactor: audit log (#1516) * refactor: audit-log * refactor: audit-log fix view action * refactor: audit-log view fix * refactor(audit-log): collection field fix * refactor: audit-log view field fix * refactor(audit-log): support fixedBlock * refactor(audit-log): i18n fix * feat(filter-blocks): support form-block * feat(filter-blocks): add FilterProvider * feat: filter data blocks * perf: use useMemo * refactor: rename * feat: collect filter params * refactor: rename * refactor: remove useless code * feat: add 'Connect data blocks' option * feat: support 'x-filter-targets' to save data-blocks * refactor: extract Form.FilterFormDesigner * feat: extract FormItem.FilterFormDesigner * refactor: extract common editing options * feat: support to set operator * feat: use operator created by user * fix: improve loading * fix: merge prev params * feat: support reset * refactor: rename * chore: left a TODO * feat: add Table.FilterDesigner * feat: support filter-table * refactor: reduce code * feat: handle click event of table row * feat: support to connect association collection * feat: support Collapse * feat: show empty * refactor: optimize readability * fix: keep state as latest * fix: highlight row on selected * feat: highlight data block on hover * fix: avoid misuse * chore: reduce code * fix(Table): support to cancel select * fix(Collapse): merge multiple filter params * chore: make to pass CI * feat: merge all filter params * refactor: remove useless code * fix: undefined * fix(Form): fix bug with association fields * chore: fix typo * fix: use title * chore: avoid infinite loops * test: cancel comments * fix: make ci normal * fix: filter down non-association fields * fix: fix page crash * fix: use correct operator * fix: avoid infinte loops * style: optimize style on hover * fix: avoid crash * chore: optimize empty description * fix: avoid targetKey empty * refactor: use getTargetKey instead * fix: filter out unfilterable fields * refactor: avoid to invoke hook multiple times * refactor: reduce the judgment conditions of component * fix: group fields in the right way * fix: fix error of type * fix: fix error on no FilterBlockProvider * fix(Table): fix fexed-block bug * chore: reduce gap * fix(Form): use AssociationSelect by default * fix: remove g2plot blocks * fix(Form): remove 'Display association fields' * fix(Table): use radio * fix(Table): no need Actions * fix: fix template problem * fix(Table): keep only 'filter' and 'refresh' * fix: use collection name as identifier for data blocks * fix: make sure all fields are editable * fix(Form): remove custom actions * fix(Details): display empty component on no data * feat(Form): support association fields * refactor: rename * feat(Form): support for deep-level association fields * Revert "fix(Table): keep only 'filter' and 'refresh'" This reverts commit 61a1d101a7d15223cfd3523adb33567fff545568. * Revert "fix(Table): no need Actions" This reverts commit 8314629e92fb3b5b7ec1c97904a42c76c43e4d4a. * Revert "fix(Table): use radio" This reverts commit c6f009740e1835f9762653a721ff64f52d0994cf. * feat(Table): highlight row on selected * feat: support to cacel highlight * fix: type error * feat: remove Table from filter list * fix(Table): highlight rows problem * refactor: remove usless code * refactor(Collapse): detach from Table * fix(Table): highlighting row problem * fix: translate problem * fix(Collapse): fix error of useProps * fix(Table): avoid undefined * Update Details.tsx * Update DetailsBlockProvider.tsx * refactor: rename target.name to target.uid * fix: add translate * style: add padding --------- Co-authored-by: anuoua <anuoua@gmail.com> Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-20 17:40:16 +08:00
mergeStrategies.set('intersect', (x, y) =>
(() => {
if (typeof x === 'string') {
x = x.split(',');
}
if (typeof y === 'string') {
y = y.split(',');
}
if (!Array.isArray(x) || x.length === 0) {
return y || [];
}
if (!Array.isArray(y) || y.length === 0) {
return x || [];
}
return x.filter((v) => y.includes(v));
})().filter(Boolean),
);
2021-12-06 21:23:34 +08:00
export function assign(target: any, source: any, strategies: MergeStrategies = {}) {
getKeys(source).forEach((sourceKey) => {
const strategy = strategies[sourceKey];
let func = mergeStrategies.get('deepMerge');
if (typeof strategy === 'function') {
func = strategy;
} else if (typeof strategy === 'string' && mergeStrategies.has(strategy as any)) {
func = mergeStrategies.get(strategy as any);
}
target[sourceKey] = func(target[sourceKey], source[sourceKey]);
});
return target;
}