diff --git a/package-lock.json b/package-lock.json index 8fe8f8fd..eafb200c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@sentry/vue": "^10.32.1", "@tailwindcss/vite": "^4.1.18", "@tanstack/vue-table": "^8.21.3", + "@tanstack/vue-virtual": "^3.13.18", "@types/jest": "^30.0.0", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", @@ -5645,9 +5646,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.13.14", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.14.tgz", - "integrity": "sha512-b5Uvd8J2dc7ICeX9SRb/wkCxWk7pUwN214eEPAQsqrsktSKTCmyLxOQWSMgogBByXclZeAdgZ3k4o0fIYUIBqQ==", + "version": "3.13.18", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.18.tgz", + "integrity": "sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg==", "dev": true, "license": "MIT", "funding": { @@ -5676,13 +5677,13 @@ } }, "node_modules/@tanstack/vue-virtual": { - "version": "3.13.14", - "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.13.14.tgz", - "integrity": "sha512-dLKQCWj0uu6Rc1OsTGiClpH75hyf92MvJ9YALAzWdblwImSFnxfXD0mu8yOI7PlxiDAcDA5Pq0Q47YvADAfyfg==", + "version": "3.13.18", + "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.13.18.tgz", + "integrity": "sha512-6pT8HdHtTU5Z+t906cGdCroUNA5wHjFXsNss9gwk7QAr1VNZtz9IQCs2Nhx0gABK48c+OocHl2As+TMg8+Hy4A==", "dev": true, "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.13.14" + "@tanstack/virtual-core": "3.13.18" }, "funding": { "type": "github", diff --git a/package.json b/package.json index 6a419ba8..62945355 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@sentry/vue": "^10.32.1", "@tailwindcss/vite": "^4.1.18", "@tanstack/vue-table": "^8.21.3", + "@tanstack/vue-virtual": "^3.13.18", "@types/jest": "^30.0.0", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", diff --git a/src/components/ui/command/Command.vue b/src/components/ui/command/Command.vue new file mode 100644 index 00000000..4f4ee931 --- /dev/null +++ b/src/components/ui/command/Command.vue @@ -0,0 +1,102 @@ + + + + + + + diff --git a/src/components/ui/command/CommandDialog.vue b/src/components/ui/command/CommandDialog.vue new file mode 100644 index 00000000..78cc14bf --- /dev/null +++ b/src/components/ui/command/CommandDialog.vue @@ -0,0 +1,35 @@ + + + + + + + {{ title }} + {{ description }} + + + + + + + diff --git a/src/components/ui/command/CommandEmpty.vue b/src/components/ui/command/CommandEmpty.vue new file mode 100644 index 00000000..f049f4b1 --- /dev/null +++ b/src/components/ui/command/CommandEmpty.vue @@ -0,0 +1,29 @@ + + + + + + + diff --git a/src/components/ui/command/CommandGroup.vue b/src/components/ui/command/CommandGroup.vue new file mode 100644 index 00000000..e861409f --- /dev/null +++ b/src/components/ui/command/CommandGroup.vue @@ -0,0 +1,47 @@ + + + + + + {{ heading }} + + + + diff --git a/src/components/ui/command/CommandInput.vue b/src/components/ui/command/CommandInput.vue new file mode 100644 index 00000000..e0c60ad1 --- /dev/null +++ b/src/components/ui/command/CommandInput.vue @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/src/components/ui/command/CommandItem.vue b/src/components/ui/command/CommandItem.vue new file mode 100644 index 00000000..4b984dde --- /dev/null +++ b/src/components/ui/command/CommandItem.vue @@ -0,0 +1,84 @@ + + + + { + filterState.search = ''; + } + "> + + + diff --git a/src/components/ui/command/CommandList.vue b/src/components/ui/command/CommandList.vue new file mode 100644 index 00000000..ac2956e7 --- /dev/null +++ b/src/components/ui/command/CommandList.vue @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/src/components/ui/command/CommandSeparator.vue b/src/components/ui/command/CommandSeparator.vue new file mode 100644 index 00000000..2d989710 --- /dev/null +++ b/src/components/ui/command/CommandSeparator.vue @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/components/ui/command/CommandShortcut.vue b/src/components/ui/command/CommandShortcut.vue new file mode 100644 index 00000000..7c6d18c5 --- /dev/null +++ b/src/components/ui/command/CommandShortcut.vue @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/components/ui/dialog/Dialog.vue b/src/components/ui/dialog/Dialog.vue new file mode 100644 index 00000000..7fe5e9e0 --- /dev/null +++ b/src/components/ui/dialog/Dialog.vue @@ -0,0 +1,18 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogClose.vue b/src/components/ui/dialog/DialogClose.vue new file mode 100644 index 00000000..ee710169 --- /dev/null +++ b/src/components/ui/dialog/DialogClose.vue @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogContent.vue b/src/components/ui/dialog/DialogContent.vue new file mode 100644 index 00000000..e4bc487f --- /dev/null +++ b/src/components/ui/dialog/DialogContent.vue @@ -0,0 +1,58 @@ + + + + + + + + + + + Close + + + + diff --git a/src/components/ui/dialog/DialogDescription.vue b/src/components/ui/dialog/DialogDescription.vue new file mode 100644 index 00000000..d1601217 --- /dev/null +++ b/src/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,24 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogFooter.vue b/src/components/ui/dialog/DialogFooter.vue new file mode 100644 index 00000000..ee1f11f1 --- /dev/null +++ b/src/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogHeader.vue b/src/components/ui/dialog/DialogHeader.vue new file mode 100644 index 00000000..de228b82 --- /dev/null +++ b/src/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogOverlay.vue b/src/components/ui/dialog/DialogOverlay.vue new file mode 100644 index 00000000..f271b7af --- /dev/null +++ b/src/components/ui/dialog/DialogOverlay.vue @@ -0,0 +1,28 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogScrollContent.vue b/src/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 00000000..eef37eff --- /dev/null +++ b/src/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,62 @@ + + + + + + { + const originalEvent = event.detail.originalEvent; + const target = originalEvent.target; + if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) { + event.preventDefault(); + } + } + "> + + + + + Close + + + + + diff --git a/src/components/ui/dialog/DialogTitle.vue b/src/components/ui/dialog/DialogTitle.vue new file mode 100644 index 00000000..0434b6ff --- /dev/null +++ b/src/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,24 @@ + + + + + + + diff --git a/src/components/ui/dialog/DialogTrigger.vue b/src/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 00000000..d0516a0c --- /dev/null +++ b/src/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/components/ui/virtual-combobox/VirtualCombobox.vue b/src/components/ui/virtual-combobox/VirtualCombobox.vue new file mode 100644 index 00000000..4cf7ebd8 --- /dev/null +++ b/src/components/ui/virtual-combobox/VirtualCombobox.vue @@ -0,0 +1,217 @@ + + + + + + + + + {{ selectionSummaryText || placeholder }} + + + + + + ✕ + + ▾ + + + + + + + + + + + + + + + {{ virtualListEntries[virtualRow.index].group.label }} + + + + + + + + + {{ virtualListEntries[virtualRow.index].item.label }} + + + ✓ + + + + + + + + + Nothing found + + + + + +