From dad34a527391d986764bfd1cb00cc2c469ed7bfb Mon Sep 17 00:00:00 2001 From: DaxServer Date: Sun, 28 Sep 2025 12:36:34 +0200 Subject: [PATCH] feat(data-processing): add column header menu The changes introduce a new `ColumnHeaderMenu` component that provides a dropdown menu with various options for the column header. This includes: - Sorting the column in ascending or descending order - Filtering the column - Grouping by the column - Applying common text transformations to the column cells (trim whitespace, collapse consecutive whitespace, convert to uppercase) The component is added to the `DataTabPanel` component, where it is displayed next to the column header if the column is not a primary key. This provides users with more control and flexibility over the data processing features. --- frontend/.eslintrc-auto-import.json | 2 + frontend/auto-imports.d.ts | 7 ++ frontend/components.d.ts | 2 + frontend/eslint.config.ts | 2 + .../components/ColumnHeaderMenu.vue | 108 ++++++++++++++++++ .../components/DataTabPanel.vue | 6 + frontend/vite.config.ts | 10 ++ 7 files changed, 137 insertions(+) create mode 100644 frontend/src/features/data-processing/components/ColumnHeaderMenu.vue diff --git a/frontend/.eslintrc-auto-import.json b/frontend/.eslintrc-auto-import.json index 4cd6714..74f0c0c 100644 --- a/frontend/.eslintrc-auto-import.json +++ b/frontend/.eslintrc-auto-import.json @@ -36,6 +36,7 @@ "Label": true, "MaybeRef": true, "MaybeRefOrGetter": true, + "MenuItem": true, "PageState": true, "ProjectColumn": true, "ProjectFile": true, @@ -58,6 +59,7 @@ "StatementSchema1": true, "StatementSchemaMapping": true, "TermsSchemaMapping": true, + "TieredMenu": true, "TransformationFunction": true, "TransformationParameter": true, "TransformationRule": true, diff --git a/frontend/auto-imports.d.ts b/frontend/auto-imports.d.ts index af02e37..e3a495b 100644 --- a/frontend/auto-imports.d.ts +++ b/frontend/auto-imports.d.ts @@ -9,6 +9,7 @@ declare global { const ApiKey: typeof import('./src/core/plugins/api')['ApiKey'] const ApiPlugin: typeof import('./src/core/plugins/api')['ApiPlugin'] const EffectScope: typeof import('vue')['EffectScope'] + const MenuItem: typeof import('primevue/menuitem')['MenuItem'] const ValidationMessages: typeof import('./src/shared/types/wikibase-schema')['ValidationMessages'] const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] const api: typeof import('./src/core/plugins/api')['api'] @@ -359,9 +360,15 @@ declare global { export type { FileUploadUploaderEvent } from 'primevue/fileupload' import('primevue/fileupload') // @ts-ignore + export type { MenuItem } from 'primevue/menuitem' + import('primevue/menuitem') + // @ts-ignore export type { PageState } from 'primevue/paginator' import('primevue/paginator') // @ts-ignore + export type { TieredMenu } from 'primevue/tieredmenu' + import('primevue/tieredmenu') + // @ts-ignore export type { UUID } from 'crypto' import('crypto') // @ts-ignore diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 67ae2e8..c412eb1 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -15,6 +15,7 @@ declare module 'vue' { Chip: typeof import('primevue/chip')['default'] ClaimEditor: typeof import('./src/features/wikibase-schema/components/ClaimEditor.vue')['default'] Column: typeof import('primevue/column')['default'] + ColumnHeaderMenu: typeof import('./src/features/data-processing/components/ColumnHeaderMenu.vue')['default'] ColumnPalette: typeof import('./src/features/data-processing/components/ColumnPalette.vue')['default'] ConfirmDialog: typeof import('primevue/confirmdialog')['default'] CreateProject: typeof import('./src/features/project-management/pages/CreateProject.vue')['default'] @@ -54,6 +55,7 @@ declare module 'vue' { Tag: typeof import('primevue/tag')['default'] TermSection: typeof import('./src/features/wikibase-schema/components/TermSection.vue')['default'] TermsEditor: typeof import('./src/features/wikibase-schema/components/TermsEditor.vue')['default'] + TieredMenu: typeof import('primevue/tieredmenu')['default'] Toast: typeof import('primevue/toast')['default'] ToggleSwitch: typeof import('primevue/toggleswitch')['default'] ValidationDisplay: typeof import('./src/features/wikibase-schema/components/ValidationDisplay.vue')['default'] diff --git a/frontend/eslint.config.ts b/frontend/eslint.config.ts index 3e35779..84ead7e 100644 --- a/frontend/eslint.config.ts +++ b/frontend/eslint.config.ts @@ -2,6 +2,7 @@ import js from '@eslint/js' import prettierConfig from 'eslint-config-prettier' import pluginVue from 'eslint-plugin-vue' import { defineConfig } from 'eslint/config' +import globals from 'globals' import tseslint from 'typescript-eslint' import vueParser from 'vue-eslint-parser' import autoImportGlobals from './.eslintrc-auto-import.json' @@ -35,6 +36,7 @@ export default defineConfig( extraFileExtensions: ['.vue'], }, globals: { + ...globals.browser, ...autoImportGlobals.globals, }, }, diff --git a/frontend/src/features/data-processing/components/ColumnHeaderMenu.vue b/frontend/src/features/data-processing/components/ColumnHeaderMenu.vue new file mode 100644 index 0000000..e846b4f --- /dev/null +++ b/frontend/src/features/data-processing/components/ColumnHeaderMenu.vue @@ -0,0 +1,108 @@ + + + diff --git a/frontend/src/features/data-processing/components/DataTabPanel.vue b/frontend/src/features/data-processing/components/DataTabPanel.vue index a56cb65..b24103b 100644 --- a/frontend/src/features/data-processing/components/DataTabPanel.vue +++ b/frontend/src/features/data-processing/components/DataTabPanel.vue @@ -58,6 +58,12 @@ onUnmounted(() => clearProject()) v-if="col.pk" class="pi pi-key text-blue-600" /> + {{ col.header }} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 6084a9a..dd83f9e 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -34,11 +34,21 @@ export default defineConfig({ imports: ['FileUploadUploaderEvent'], type: true, }, + { + from: 'primevue/menuitem', + imports: ['MenuItem'], + type: true, + }, { from: 'primevue/paginator', imports: ['PageState'], type: true, }, + { + from: 'primevue/tieredmenu', + imports: ['TieredMenu'], + type: true, + }, { from: 'primevue/useconfirm', imports: ['useConfirm'],