mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 01:56:16 +00:00
perf(users): optimize performance for rendering the user management table (#5276)
Some checks failed
auto-merge / push-commit (push) Has been cancelled
Build Docker Image / build-and-push (push) Has been cancelled
Build Pro Image / build-and-push (push) Has been cancelled
E2E / Build (push) Has been cancelled
NocoBase Backend Test / sqlite-test (20, false) (push) Has been cancelled
NocoBase Backend Test / sqlite-test (20, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, nocobase, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, nocobase, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, public, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, public, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, public, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, public, true) (push) Has been cancelled
NocoBase Backend Test / mysql-test (20, false) (push) Has been cancelled
NocoBase Backend Test / mysql-test (20, true) (push) Has been cancelled
NocoBase Backend Test / mariadb-test (20, false) (push) Has been cancelled
NocoBase Backend Test / mariadb-test (20, true) (push) Has been cancelled
NocoBase FrontEnd Test / frontend-test (18) (push) Has been cancelled
Test on Windows / build (push) Has been cancelled
E2E / Core and plugins (push) Has been cancelled
E2E / plugin-workflow (push) Has been cancelled
E2E / plugin-workflow-approval (push) Has been cancelled
E2E / plugin-data-source-main (push) Has been cancelled
E2E / Comment on PR (push) Has been cancelled
Some checks failed
auto-merge / push-commit (push) Has been cancelled
Build Docker Image / build-and-push (push) Has been cancelled
Build Pro Image / build-and-push (push) Has been cancelled
E2E / Build (push) Has been cancelled
NocoBase Backend Test / sqlite-test (20, false) (push) Has been cancelled
NocoBase Backend Test / sqlite-test (20, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, nocobase, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, nocobase, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, public, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (public, 20, public, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, nocobase, true) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, public, false) (push) Has been cancelled
NocoBase Backend Test / postgres-test (user_schema, 20, public, true) (push) Has been cancelled
NocoBase Backend Test / mysql-test (20, false) (push) Has been cancelled
NocoBase Backend Test / mysql-test (20, true) (push) Has been cancelled
NocoBase Backend Test / mariadb-test (20, false) (push) Has been cancelled
NocoBase Backend Test / mariadb-test (20, true) (push) Has been cancelled
NocoBase FrontEnd Test / frontend-test (18) (push) Has been cancelled
Test on Windows / build (push) Has been cancelled
E2E / Core and plugins (push) Has been cancelled
E2E / plugin-workflow (push) Has been cancelled
E2E / plugin-workflow-approval (push) Has been cancelled
E2E / plugin-data-source-main (push) Has been cancelled
E2E / Comment on PR (push) Has been cancelled
* perf(users): optimize render performance of the user management table * fix: bug
This commit is contained in:
parent
00301815d5
commit
f032c732f1
@ -7,27 +7,88 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { SchemaComponent, SchemaComponentContext, useSchemaComponentContext } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import {
|
||||
SchemaComponent,
|
||||
SchemaComponentContext,
|
||||
useActionContext,
|
||||
useCollection,
|
||||
useCollectionRecordData,
|
||||
useDataBlockRequest,
|
||||
useDataBlockResource,
|
||||
useSchemaComponentContext,
|
||||
} from '@nocobase/client';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { usersSchema } from './schemas/users';
|
||||
import { Card } from 'antd';
|
||||
import { UserRolesField } from './UserRolesField';
|
||||
import { useUsersTranslation } from './locale';
|
||||
import { useFilterActionProps } from './hooks';
|
||||
import { PasswordField } from './PasswordField';
|
||||
import { App } from 'antd';
|
||||
import { useForm } from '@formily/react';
|
||||
import { createForm } from '@formily/core';
|
||||
|
||||
const useCancelActionProps = () => {
|
||||
const { setVisible } = useActionContext();
|
||||
return {
|
||||
type: 'default',
|
||||
onClick() {
|
||||
setVisible(false);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useSubmitActionProps = () => {
|
||||
const { setVisible } = useActionContext();
|
||||
const { message } = App.useApp();
|
||||
const form = useForm();
|
||||
const resource = useDataBlockResource();
|
||||
const { runAsync } = useDataBlockRequest();
|
||||
const { t } = useUsersTranslation();
|
||||
const collection = useCollection();
|
||||
|
||||
return {
|
||||
type: 'primary',
|
||||
async onClick() {
|
||||
await form.submit();
|
||||
const values = form.values;
|
||||
console.log('values:', values);
|
||||
if (values[collection.filterTargetKey]) {
|
||||
await resource.update({
|
||||
values,
|
||||
filterByTk: values[collection.filterTargetKey],
|
||||
});
|
||||
} else {
|
||||
await resource.create({ values });
|
||||
}
|
||||
await runAsync();
|
||||
message.success(t('Saved successfully'));
|
||||
setVisible(false);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useEditFormProps = () => {
|
||||
const recordData = useCollectionRecordData();
|
||||
const form = useMemo(
|
||||
() =>
|
||||
createForm({
|
||||
initialValues: recordData,
|
||||
}),
|
||||
[recordData],
|
||||
);
|
||||
return {
|
||||
form,
|
||||
};
|
||||
};
|
||||
|
||||
export const UsersManagement: React.FC = () => {
|
||||
const { t } = useUsersTranslation();
|
||||
const scCtx = useSchemaComponentContext();
|
||||
return (
|
||||
<SchemaComponentContext.Provider value={{ ...scCtx, designable: false }}>
|
||||
<Card>
|
||||
<SchemaComponent
|
||||
schema={usersSchema}
|
||||
scope={{ t, useFilterActionProps }}
|
||||
components={{ UserRolesField, PasswordField }}
|
||||
/>
|
||||
</Card>
|
||||
<SchemaComponent
|
||||
schema={usersSchema}
|
||||
scope={{ t, useCancelActionProps, useSubmitActionProps, useEditFormProps }}
|
||||
components={{ PasswordField }}
|
||||
/>
|
||||
</SchemaComponentContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -132,26 +132,28 @@ export const usersSchema: ISchema = {
|
||||
properties: {
|
||||
block1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-component': 'CardItem',
|
||||
'x-component-props': {
|
||||
heightMode: 'fullHeight',
|
||||
},
|
||||
'x-decorator': 'TableBlockProvider',
|
||||
'x-decorator-props': {
|
||||
collection: userCollection,
|
||||
resourceName: 'users',
|
||||
request: {
|
||||
resource: 'users',
|
||||
action: 'list',
|
||||
params: {
|
||||
pageSize: 50,
|
||||
appends: [],
|
||||
},
|
||||
dataSource: 'main',
|
||||
rowKey: 'id',
|
||||
collection: 'users',
|
||||
action: 'list',
|
||||
params: {
|
||||
pageSize: 20,
|
||||
},
|
||||
},
|
||||
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
marginBottom: 16,
|
||||
marginBottom: 'var(--nb-spacing)',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
@ -166,18 +168,28 @@ export const usersSchema: ISchema = {
|
||||
},
|
||||
'x-align': 'left',
|
||||
},
|
||||
refresh: {
|
||||
type: 'void',
|
||||
title: '{{ t("Refresh") }}',
|
||||
'x-action': 'refresh',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
icon: 'ReloadOutlined',
|
||||
},
|
||||
'x-use-component-props': 'useRefreshActionProps',
|
||||
},
|
||||
delete: {
|
||||
type: 'void',
|
||||
title: '{{ t("Delete") }}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useBulkDestroyAction }}',
|
||||
confirm: {
|
||||
title: "{{t('Delete users')}}",
|
||||
content: "{{t('Are you sure you want to delete it?')}}",
|
||||
},
|
||||
icon: 'DeleteOutlined',
|
||||
},
|
||||
'x-use-component-props': 'useBulkDestroyActionProps',
|
||||
},
|
||||
create: {
|
||||
type: 'void',
|
||||
@ -191,7 +203,7 @@ export const usersSchema: ISchema = {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator': 'FormV2',
|
||||
title: '{{t("Add user")}}',
|
||||
properties: {
|
||||
nickname: {
|
||||
@ -232,17 +244,15 @@ export const usersSchema: ISchema = {
|
||||
cancel: {
|
||||
title: '{{t("Cancel")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useCancelActionProps',
|
||||
},
|
||||
submit: {
|
||||
title: '{{t("Submit")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ cm.useCreateAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useSubmitActionProps',
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -253,21 +263,21 @@ export const usersSchema: ISchema = {
|
||||
},
|
||||
},
|
||||
table: {
|
||||
type: 'void',
|
||||
type: 'array',
|
||||
'x-uid': 'input',
|
||||
'x-component': 'Table.Void',
|
||||
'x-component': 'TableV2',
|
||||
'x-component-props': {
|
||||
rowKey: 'id',
|
||||
rowSelection: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
useDataSource: '{{ cm.useDataSourceFromRAC }}',
|
||||
},
|
||||
'x-use-component-props': 'useTableBlockProps',
|
||||
properties: {
|
||||
column1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Table.Column.Decorator',
|
||||
'x-component': 'Table.Column',
|
||||
'x-decorator': 'TableV2.Column.Decorator',
|
||||
'x-component': 'TableV2.Column',
|
||||
properties: {
|
||||
nickname: {
|
||||
type: 'number',
|
||||
@ -278,8 +288,8 @@ export const usersSchema: ISchema = {
|
||||
},
|
||||
column2: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Table.Column.Decorator',
|
||||
'x-component': 'Table.Column',
|
||||
'x-decorator': 'TableV2.Column.Decorator',
|
||||
'x-component': 'TableV2.Column',
|
||||
properties: {
|
||||
username: {
|
||||
type: 'string',
|
||||
@ -290,8 +300,8 @@ export const usersSchema: ISchema = {
|
||||
},
|
||||
column3: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Table.Column.Decorator',
|
||||
'x-component': 'Table.Column',
|
||||
'x-decorator': 'TableV2.Column.Decorator',
|
||||
'x-component': 'TableV2.Column',
|
||||
properties: {
|
||||
email: {
|
||||
type: 'string',
|
||||
@ -302,20 +312,28 @@ export const usersSchema: ISchema = {
|
||||
},
|
||||
column4: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Table.Column.Decorator',
|
||||
'x-component': 'Table.Column',
|
||||
'x-decorator': 'TableV2.Column.Decorator',
|
||||
'x-component': 'TableV2.Column',
|
||||
title: '{{t("Roles")}}',
|
||||
properties: {
|
||||
roles: {
|
||||
type: 'array',
|
||||
'x-component': 'UserRolesField',
|
||||
'x-component': 'CollectionField',
|
||||
'x-component-props': {
|
||||
mode: 'Tag',
|
||||
enableLink: false,
|
||||
ellipsis: true,
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
'x-collection-field': 'users.roles',
|
||||
},
|
||||
},
|
||||
},
|
||||
column5: {
|
||||
type: 'void',
|
||||
title: '{{t("Actions")}}',
|
||||
'x-component': 'Table.Column',
|
||||
'x-component': 'TableV2.Column',
|
||||
'x-decorator': 'TableV2.Column.ActionBar',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
@ -337,23 +355,8 @@ export const usersSchema: ISchema = {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: (options) => {
|
||||
const record = useRecord();
|
||||
const result = useRequest(() => Promise.resolve({ data: record }), {
|
||||
...options,
|
||||
manual: true,
|
||||
});
|
||||
const ctx = useActionContext();
|
||||
useEffect(() => {
|
||||
if (ctx.visible) {
|
||||
result.run();
|
||||
}
|
||||
}, [ctx.visible]);
|
||||
return result;
|
||||
},
|
||||
},
|
||||
'x-decorator': 'FormV2',
|
||||
'x-use-decorator-props': 'useEditFormProps',
|
||||
title: '{{t("Edit profile")}}',
|
||||
properties: {
|
||||
nickname: {
|
||||
@ -389,17 +392,15 @@ export const usersSchema: ISchema = {
|
||||
cancel: {
|
||||
title: '{{t("Cancel")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useCancelActionProps',
|
||||
},
|
||||
submit: {
|
||||
title: '{{t("Submit")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ cm.useUpdateAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useSubmitActionProps',
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -420,7 +421,8 @@ export const usersSchema: ISchema = {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator': 'FormV2',
|
||||
'x-use-decorator-props': 'useEditFormProps',
|
||||
title: '{{t("Change password")}}',
|
||||
properties: {
|
||||
password: {
|
||||
@ -438,17 +440,15 @@ export const usersSchema: ISchema = {
|
||||
cancel: {
|
||||
title: '{{t("Cancel")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useCancelActionProps',
|
||||
},
|
||||
submit: {
|
||||
title: '{{t("Submit")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ cm.useUpdateAction }}',
|
||||
},
|
||||
'x-use-component-props': 'useSubmitActionProps',
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -468,8 +468,8 @@ export const usersSchema: ISchema = {
|
||||
title: "{{t('Delete')}}",
|
||||
content: "{{t('Are you sure you want to delete it?')}}",
|
||||
},
|
||||
useAction: '{{cm.useDestroyAction}}',
|
||||
},
|
||||
'x-use-component-props': 'useDestroyActionProps',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -48,7 +48,7 @@ export const listExcludeRole = async (ctx: Context, next: Next) => {
|
||||
const [rows, count] = await repo.findAndCount({
|
||||
context: ctx,
|
||||
offset: (page - 1) * pageSize,
|
||||
limit: pageSize,
|
||||
limit: +pageSize,
|
||||
filter,
|
||||
});
|
||||
ctx.body = {
|
||||
|
Loading…
Reference in New Issue
Block a user