From c0bb9dff917cab61eada01f601e8ea305c2c80b3 Mon Sep 17 00:00:00 2001 From: YANG QIA <2013xile@gmail.com> Date: Fri, 7 Mar 2025 11:36:33 +0800 Subject: [PATCH] feat(data-vi): support nulls sorting in chart queries (#6383) --- .../src/client/configure/schemas/configure.ts | 28 +++++++++++++++---- .../src/server/query-parser/query-parser.ts | 9 +++++- .../src/server/types.ts | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/client/configure/schemas/configure.ts b/packages/plugins/@nocobase/plugin-data-visualization/src/client/configure/schemas/configure.ts index de384035008c7..8f1ebec33b930 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/client/configure/schemas/configure.ts +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/client/configure/schemas/configure.ts @@ -424,16 +424,34 @@ export const querySchema: ISchema = { order: { type: 'string', 'x-decorator': 'FormItem', - 'x-component': 'Radio.Group', + 'x-component': 'Select', 'x-component-props': { defaultValue: 'ASC', - optionType: 'button', - style: { - width: '128px', - }, }, enum: ['ASC', 'DESC'], }, + nulls: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + 'x-component-props': { + defaultValue: 'default', + }, + enum: [ + { + label: lang('Default'), + value: 'default', + }, + { + label: lang('NULLS first'), + value: 'first', + }, + { + label: lang('NULLS last'), + value: 'last', + }, + ], + }, }, { 'x-reactions': '{{ useOrderReaction }}', diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/server/query-parser/query-parser.ts b/packages/plugins/@nocobase/plugin-data-visualization/src/server/query-parser/query-parser.ts index 93c0023658736..a37e64f18194e 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/server/query-parser/query-parser.ts +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/server/query-parser/query-parser.ts @@ -84,7 +84,14 @@ export class QueryParser { orders.forEach((item: OrderProps) => { const alias = sequelize.getQueryInterface().quoteIdentifier(item.alias); const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field as string); - order.push([name, item.order || 'ASC']); + let sort = item.order || 'ASC'; + if (item.nulls === 'first') { + sort += ' NULLS FIRST'; + } + if (item.nulls === 'last') { + sort += ' NULLS LAST'; + } + order.push([name, sort]); }); return order; } diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/server/types.ts b/packages/plugins/@nocobase/plugin-data-visualization/src/server/types.ts index 6f587dbef7af5..34de4c09f73ff 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/server/types.ts +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/server/types.ts @@ -27,6 +27,7 @@ export type OrderProps = { field: string | string[]; alias?: string; order?: 'asc' | 'desc'; + nulls?: 'default' | 'first' | 'last'; }; export type QueryParams = Partial<{