perf(bi): optimize performance of chart filter block (#3316)
* perf: add useMemo * fix: bug * fix: bug * chore: remove memo
This commit is contained in:
parent
5f55f4d8db
commit
f803105e69
@ -54,12 +54,12 @@ export const Cascader = connect(
|
|||||||
<Space split={'/'}>
|
<Space split={'/'}>
|
||||||
{labels.map((label, index) => {
|
{labels.map((label, index) => {
|
||||||
if (selectedOptions[index]) {
|
if (selectedOptions[index]) {
|
||||||
return <span key={label}>{label}</span>;
|
return <span key={index}>{label}</span>;
|
||||||
}
|
}
|
||||||
const item = toArr(value)
|
const item = toArr(value)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.find((item) => item[fieldNames.value] === label);
|
.find((item) => item[fieldNames.value] === label);
|
||||||
return <span key={label}>{item?.[fieldNames.label] || label}</span>;
|
return <span key={index}>{item?.[fieldNames.label] || label}</span>;
|
||||||
})}
|
})}
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
@ -15,8 +15,7 @@ export class Table extends AntdChart {
|
|||||||
key: item,
|
key: item,
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
const rowKey = columns[0]?.dataIndex;
|
const dataSource = data.map((item: any, index: number) => {
|
||||||
const dataSource = data.map((item: any) => {
|
|
||||||
Object.keys(item).map((key: string) => {
|
Object.keys(item).map((key: string) => {
|
||||||
const props = fieldProps[key];
|
const props = fieldProps[key];
|
||||||
if (props?.interface === 'percent') {
|
if (props?.interface === 'percent') {
|
||||||
@ -30,6 +29,7 @@ export class Table extends AntdChart {
|
|||||||
item[key] = props.transformer(item[key]);
|
item[key] = props.transformer(item[key]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
item._key = index;
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
const pageSize = advanced?.pagination?.pageSize || 10;
|
const pageSize = advanced?.pagination?.pageSize || 10;
|
||||||
@ -47,7 +47,7 @@ export class Table extends AntdChart {
|
|||||||
scroll: {
|
scroll: {
|
||||||
x: 'max-content',
|
x: 'max-content',
|
||||||
},
|
},
|
||||||
rowKey,
|
rowKey: '_key',
|
||||||
...general,
|
...general,
|
||||||
...advanced,
|
...advanced,
|
||||||
};
|
};
|
||||||
|
@ -205,8 +205,10 @@ export const ChartConfigure: React.FC<{
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
width={'95%'}
|
width={'95%'}
|
||||||
bodyStyle={{
|
styles={{
|
||||||
background: 'rgba(128, 128, 128, 0.08)',
|
body: {
|
||||||
|
background: 'rgba(128, 128, 128, 0.08)',
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FormProvider form={form}>
|
<FormProvider form={form}>
|
||||||
@ -411,7 +413,8 @@ ChartConfigure.Data = function Data() {
|
|||||||
const error = service?.error;
|
const error = service?.error;
|
||||||
return !error ? (
|
return !error ? (
|
||||||
<Table
|
<Table
|
||||||
dataSource={data}
|
dataSource={data.map((item, index) => ({ ...item, _key: index }))}
|
||||||
|
rowKey="_key"
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
columns={Object.keys(data[0] || {}).map((col) => {
|
columns={Object.keys(data[0] || {}).map((col) => {
|
||||||
const field = getField(fields, col.split('.'));
|
const field = getField(fields, col.split('.'));
|
||||||
|
@ -312,9 +312,9 @@ export const querySchema: ISchema = {
|
|||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
enum: '{{ filterOptions }}',
|
||||||
'x-component': 'Filter',
|
'x-component': 'Filter',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
options: '{{ filterOptions }}',
|
|
||||||
dynamicComponent: 'FilterDynamicComponent',
|
dynamicComponent: 'FilterDynamicComponent',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
useGlobalTheme,
|
useGlobalTheme,
|
||||||
useSchemaInitializerItem,
|
useSchemaInitializerItem,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import React, { useCallback, useContext, useMemo } from 'react';
|
import React, { memo, useCallback, useContext, useMemo } from 'react';
|
||||||
import { lang, useChartsTranslation } from '../locale';
|
import { lang, useChartsTranslation } from '../locale';
|
||||||
import { Schema, SchemaOptionsContext, observer, useField, useFieldSchema, useForm } from '@formily/react';
|
import { Schema, SchemaOptionsContext, observer, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
@ -92,7 +92,7 @@ export const ChartFilterFormItem = observer(
|
|||||||
|
|
||||||
export const ChartFilterCustomItemInitializer: React.FC<{
|
export const ChartFilterCustomItemInitializer: React.FC<{
|
||||||
insert?: any;
|
insert?: any;
|
||||||
}> = (props) => {
|
}> = memo((props) => {
|
||||||
const { locale } = useContext(ConfigProvider.ConfigContext);
|
const { locale } = useContext(ConfigProvider.ConfigContext);
|
||||||
const { t: lang } = useChartsTranslation();
|
const { t: lang } = useChartsTranslation();
|
||||||
const t = useMemoizedFn(lang);
|
const t = useMemoizedFn(lang);
|
||||||
@ -214,7 +214,7 @@ export const ChartFilterCustomItemInitializer: React.FC<{
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
return <SchemaInitializerItem {...itemConfig} {...props} onClick={handleClick} />;
|
return <SchemaInitializerItem {...itemConfig} {...props} onClick={handleClick} />;
|
||||||
};
|
});
|
||||||
|
|
||||||
export const chartFilterItemInitializers = new SchemaInitializer({
|
export const chartFilterItemInitializers = new SchemaInitializer({
|
||||||
name: 'ChartFilterItemInitializers',
|
name: 'ChartFilterItemInitializers',
|
||||||
@ -232,16 +232,19 @@ export const chartFilterItemInitializers = new SchemaInitializer({
|
|||||||
const { getChartCollections } = useChartData();
|
const { getChartCollections } = useChartData();
|
||||||
const { getChartFilterFields } = useChartFilter();
|
const { getChartFilterFields } = useChartFilter();
|
||||||
const collections = getChartCollections();
|
const collections = getChartCollections();
|
||||||
return collections.map((name: any) => {
|
|
||||||
const collection = getCollection(name);
|
return useMemo(() => {
|
||||||
const fields = getChartFilterFields(collection);
|
return collections.map((name: any) => {
|
||||||
return {
|
const collection = getCollection(name);
|
||||||
name: collection.key,
|
const fields = getChartFilterFields(collection);
|
||||||
type: 'subMenu',
|
return {
|
||||||
title: collection.title,
|
name: collection.key,
|
||||||
children: fields,
|
type: 'subMenu',
|
||||||
};
|
title: collection.title,
|
||||||
});
|
children: fields,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [collections]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -412,26 +412,28 @@ export const useChartFilterSourceFields = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const collections = getChartCollections();
|
const collections = getChartCollections();
|
||||||
const options = [];
|
return useMemo(() => {
|
||||||
collections.forEach((name) => {
|
const options = [];
|
||||||
const collection = getCollection(name);
|
collections.forEach((name) => {
|
||||||
const children = [];
|
const collection = getCollection(name);
|
||||||
const fields = getCollectionFields(collection);
|
const children = [];
|
||||||
fields.forEach((field) => {
|
const fields = getCollectionFields(collection);
|
||||||
const option = field2option(field, 1);
|
fields.forEach((field) => {
|
||||||
if (option) {
|
const option = field2option(field, 1);
|
||||||
children.push(option);
|
if (option) {
|
||||||
|
children.push(option);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (children.length) {
|
||||||
|
options.push({
|
||||||
|
value: name,
|
||||||
|
label: t(collection.title),
|
||||||
|
children,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (children.length) {
|
return options;
|
||||||
options.push({
|
}, [collections]);
|
||||||
value: name,
|
|
||||||
label: t(collection.title),
|
|
||||||
children,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFieldComponents = () => {
|
export const useFieldComponents = () => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ArrayField } from '@formily/core';
|
import { ArrayField } from '@formily/core';
|
||||||
import { ISchema, Schema, useForm } from '@formily/react';
|
import { ISchema, Schema, useForm } from '@formily/react';
|
||||||
import { CollectionFieldOptions, useACLRoleContext, useCollectionManager } from '@nocobase/client';
|
import { CollectionFieldOptions, useACLRoleContext, useCollectionManager } from '@nocobase/client';
|
||||||
import { useContext } from 'react';
|
import { useContext, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ChartConfigContext } from '../configure';
|
import { ChartConfigContext } from '../configure';
|
||||||
import formatters from '../block/formatters';
|
import formatters from '../block/formatters';
|
||||||
@ -51,43 +51,47 @@ export const useFieldsWithAssociation = (collection?: string) => {
|
|||||||
const { getCollectionFields, getInterface } = useCollectionManager();
|
const { getCollectionFields, getInterface } = useCollectionManager();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const fields = useFields(collection);
|
const fields = useFields(collection);
|
||||||
return fields.map((field) => {
|
return useMemo(
|
||||||
const filterable = getInterface(field.interface)?.filterable;
|
() =>
|
||||||
const label = Schema.compile(field.uiSchema?.title || field.name, { t });
|
fields.map((field) => {
|
||||||
if (!(filterable && (filterable?.nested || filterable?.children?.length))) {
|
const filterable = getInterface(field.interface)?.filterable;
|
||||||
return { ...field, label };
|
const label = Schema.compile(field.uiSchema?.title || field.name, { t });
|
||||||
}
|
if (!(filterable && (filterable?.nested || filterable?.children?.length))) {
|
||||||
let targetFields = [];
|
return { ...field, label };
|
||||||
if (filterable?.nested) {
|
}
|
||||||
const nestedFields = (getCollectionFields(field.target) || [])
|
let targetFields = [];
|
||||||
.filter((targetField) => {
|
if (filterable?.nested) {
|
||||||
return targetField.interface;
|
const nestedFields = (getCollectionFields(field.target) || [])
|
||||||
})
|
.filter((targetField) => {
|
||||||
.map((targetField) => ({
|
return targetField.interface;
|
||||||
...targetField,
|
})
|
||||||
key: `${field.name}.${targetField.name}`,
|
.map((targetField) => ({
|
||||||
label: `${label} / ${Schema.compile(targetField.uiSchema?.title || targetField.name, { t })}`,
|
...targetField,
|
||||||
value: `${field.name}.${targetField.name}`,
|
key: `${field.name}.${targetField.name}`,
|
||||||
}));
|
label: `${label} / ${Schema.compile(targetField.uiSchema?.title || targetField.name, { t })}`,
|
||||||
targetFields = [...targetFields, ...nestedFields];
|
value: `${field.name}.${targetField.name}`,
|
||||||
}
|
}));
|
||||||
|
targetFields = [...targetFields, ...nestedFields];
|
||||||
|
}
|
||||||
|
|
||||||
if (filterable?.children?.length) {
|
if (filterable?.children?.length) {
|
||||||
const children = filterable.children.map((child: any) => ({
|
const children = filterable.children.map((child: any) => ({
|
||||||
...child,
|
...child,
|
||||||
key: `${field.name}.${child.name}`,
|
key: `${field.name}.${child.name}`,
|
||||||
label: `${label} / ${Schema.compile(child.schema?.title || child.title || child.name, { t })}`,
|
label: `${label} / ${Schema.compile(child.schema?.title || child.title || child.name, { t })}`,
|
||||||
value: `${field.name}.${child.name}`,
|
value: `${field.name}.${child.name}`,
|
||||||
}));
|
}));
|
||||||
targetFields = [...targetFields, ...children];
|
targetFields = [...targetFields, ...children];
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...field,
|
...field,
|
||||||
label,
|
label,
|
||||||
targetFields,
|
targetFields,
|
||||||
};
|
};
|
||||||
});
|
}),
|
||||||
|
[fields],
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useChartFields = (fields: FieldOption[]) => (field: any) => {
|
export const useChartFields = (fields: FieldOption[]) => (field: any) => {
|
||||||
@ -139,7 +143,7 @@ export const useCollectionOptions = () => {
|
|||||||
value: collection.name,
|
value: collection.name,
|
||||||
key: collection.name,
|
key: collection.name,
|
||||||
}));
|
}));
|
||||||
return Schema.compile(options, { t });
|
return useMemo(() => Schema.compile(options, { t }), [options]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useOrderFieldsOptions = (defaultOptions: any[], fields: FieldOption[]) => (field: any) => {
|
export const useOrderFieldsOptions = (defaultOptions: any[], fields: FieldOption[]) => (field: any) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user