From c4d9ecb39eacb0c9ea28c99f833291eac11d4328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Pocrnji=C4=8D?= Date: Mon, 5 Jan 2026 18:27:35 +0100 Subject: [PATCH] Admin panel updated with shadcn-vue components --- .../Controllers/Admin/PackageController.php | 2 +- .../Controllers/ClientCaseContoller.original | Bin 125202 -> 0 bytes .../Controllers/ImportTemplateController.php | 1 + app/Models/Contract.php | 1 + .../Import/Handlers/ContractHandler.php | 103 +- app/Services/Import/ImportServiceV2.php | 2 - database/seeders/ImportEntitiesV2Seeder.php | 28 +- package-lock.json | 109 +- package.json | 4 +- .../js/Components/ui/progress/Progress.vue | 34 + resources/js/Components/ui/progress/index.js | 1 + resources/js/Layouts/AdminLayout.vue | 221 ++-- .../js/Pages/Admin/DocumentSettings/Edit.vue | 251 ++-- .../js/Pages/Admin/DocumentSettings/Index.vue | 116 +- .../js/Pages/Admin/DocumentTemplates/Edit.vue | 609 ++++----- .../Pages/Admin/DocumentTemplates/Index.vue | 316 ++--- .../js/Pages/Admin/DocumentTemplates/Show.vue | 467 ++++--- resources/js/Pages/Admin/EmailLogs/Index.vue | 321 +++-- resources/js/Pages/Admin/EmailLogs/Show.vue | 161 ++- .../js/Pages/Admin/EmailTemplates/Edit.vue | 1117 ++++++++++------- .../js/Pages/Admin/EmailTemplates/Index.vue | 131 +- resources/js/Pages/Admin/Index.vue | 118 +- .../js/Pages/Admin/MailProfiles/Index.vue | 528 ++++---- resources/js/Pages/Admin/Packages/Index.vue | 922 ++++++++------ resources/js/Pages/Admin/Packages/Show.vue | 427 ++++--- .../js/Pages/Admin/Permissions/Create.vue | 172 ++- resources/js/Pages/Admin/Permissions/Edit.vue | 195 ++- .../js/Pages/Admin/Permissions/Index.vue | 190 ++- resources/js/Pages/Admin/SmsLogs/Index.vue | 363 ++++-- resources/js/Pages/Admin/SmsLogs/Show.vue | 262 +++- .../js/Pages/Admin/SmsProfiles/Index.vue | 371 +++--- resources/js/Pages/Admin/SmsSenders/Index.vue | 274 ++-- .../js/Pages/Admin/SmsTemplates/Edit.vue | 421 ++++--- .../js/Pages/Admin/SmsTemplates/Index.vue | 312 ++--- resources/js/Pages/Admin/Users/Index.vue | 558 ++++---- resources/js/Pages/Imports/Import.vue | 16 +- .../Templates/Partials/BasicTemplateInfo.vue | 23 +- 37 files changed, 5407 insertions(+), 3740 deletions(-) delete mode 100644 app/Http/Controllers/ClientCaseContoller.original create mode 100644 resources/js/Components/ui/progress/Progress.vue create mode 100644 resources/js/Components/ui/progress/index.js diff --git a/app/Http/Controllers/Admin/PackageController.php b/app/Http/Controllers/Admin/PackageController.php index e510d20..f507c4f 100644 --- a/app/Http/Controllers/Admin/PackageController.php +++ b/app/Http/Controllers/Admin/PackageController.php @@ -25,7 +25,7 @@ public function index(Request $request): Response { $packages = Package::query() ->latest('id') - ->paginate(20); + ->paginate(25); // Minimal lookups for create form (active only) $profiles = \App\Models\SmsProfile::query() ->where('active', true) diff --git a/app/Http/Controllers/ClientCaseContoller.original b/app/Http/Controllers/ClientCaseContoller.original deleted file mode 100644 index 72cc781259b53688e65ab8af39b35fd4f354cd3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125202 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 diff --git a/app/Http/Controllers/ImportTemplateController.php b/app/Http/Controllers/ImportTemplateController.php index dbca0e7..9341f8b 100644 --- a/app/Http/Controllers/ImportTemplateController.php +++ b/app/Http/Controllers/ImportTemplateController.php @@ -657,6 +657,7 @@ public function applyToImport(Request $request, ImportTemplate $template, Import $import->update([ 'import_template_id' => $template->id, + 'reactivate' => $template->reactivate, 'meta' => $merged, ]); }); diff --git a/app/Models/Contract.php b/app/Models/Contract.php index be845a7..ade64e3 100644 --- a/app/Models/Contract.php +++ b/app/Models/Contract.php @@ -29,6 +29,7 @@ class Contract extends Model 'end_date', 'client_case_id', 'type_id', + 'active', 'description', 'meta', ]; diff --git a/app/Services/Import/Handlers/ContractHandler.php b/app/Services/Import/Handlers/ContractHandler.php index caa7e69..e8e82d8 100644 --- a/app/Services/Import/Handlers/ContractHandler.php +++ b/app/Services/Import/Handlers/ContractHandler.php @@ -46,76 +46,35 @@ public function resolve(array $mapped, array $context = []): mixed public function process(Import $import, array $mapped, array $raw, array $context = []): array { - // PHASE 4: Check for existing Contract early to prevent duplicate creation - $reference = $mapped['reference'] ?? null; - - if ($reference) { - $existingContract = $this->resolutionService->getExistingContract( - $import->client_id, - $reference - ); - - if ($existingContract) { - Log::info('ContractHandler: Found existing Contract by reference', [ - 'contract_id' => $existingContract->id, - 'reference' => $reference, - ]); - - $mode = $this->getOption('update_mode', 'update'); - - if ($mode === 'skip') { - return [ - 'action' => 'skipped', - 'entity' => $existingContract, - 'message' => 'Contract already exists (skip mode)', - ]; - } - - // Update existing contract - $payload = $this->buildPayload($mapped, $existingContract); - $payload = $this->mergeJsonFields($payload, $existingContract); - $appliedFields = $this->trackAppliedFields($existingContract, $payload); - - if (empty($appliedFields)) { - return [ - 'action' => 'skipped', - 'entity' => $existingContract, - 'message' => 'No changes detected', - ]; - } - - $existingContract->fill($payload); - $existingContract->save(); - - return [ - 'action' => 'updated', - 'entity' => $existingContract, - 'applied_fields' => $appliedFields, - ]; - } - } - + // Check for existing contract (using resolve method which handles client scoping) $existing = $this->resolve($mapped, $context); - // Check for reactivation request - $reactivate = $this->shouldReactivate($context); - - // Handle reactivation if entity is soft-deleted or inactive - if ($existing && $reactivate && $this->needsReactivation($existing)) { - $reactivated = $this->attemptReactivation($existing, $context); - if ($reactivated) { - return [ - 'action' => 'reactivated', - 'entity' => $existing, - 'message' => 'Contract reactivated', - ]; - } - } - - // Determine if we should update or skip based on mode - $mode = $this->getOption('update_mode', 'update'); - if ($existing) { + + + // Check for reactivation FIRST (before update_mode check) + $reactivate = $this->shouldReactivate($context); + + Log::info('ContractHandler: Found existing Contract', [ + 'contract_id' => $existing->id, + 'reference' => $mapped['reference'] ?? null, + 'context' => $context['import'] + ]); + + if ($reactivate && $this->needsReactivation($existing)) { + $reactivated = $this->attemptReactivation($existing, $context); + Log::info('ContractHandler: Reactivate', ['reactivated' => $reactivated]); + if ($reactivated) { + return [ + 'action' => 'reactivated', + 'entity' => $existing, + 'message' => 'Contract reactivated', + ]; + } + } + + // Check update mode + $mode = $this->getOption('update_mode', 'update'); if ($mode === 'skip') { return [ 'action' => 'skipped', @@ -124,12 +83,9 @@ public function process(Import $import, array $mapped, array $raw, array $contex ]; } - // Update + // Update existing contract $payload = $this->buildPayload($mapped, $existing); - - // Merge JSON fields instead of overwriting $payload = $this->mergeJsonFields($payload, $existing); - $appliedFields = $this->trackAppliedFields($existing, $payload); if (empty($appliedFields)) { @@ -200,7 +156,6 @@ protected function buildPayload(array $mapped, $model): array // Map fields according to contract schema $fieldMap = [ 'reference' => 'reference', - 'title' => 'title', 'description' => 'description', 'amount' => 'amount', 'currency' => 'currency', @@ -286,7 +241,9 @@ protected function attemptReactivation(Contract $contract, array $context): bool $contract->restore(); } - $contract->update(['active' => 1]); + $contract->active = 1; + + $contract->save(); return true; } catch (\Throwable $e) { diff --git a/app/Services/Import/ImportServiceV2.php b/app/Services/Import/ImportServiceV2.php index 7e1910c..d58aad0 100644 --- a/app/Services/Import/ImportServiceV2.php +++ b/app/Services/Import/ImportServiceV2.php @@ -100,8 +100,6 @@ public function process(Import $import, ?Authenticatable $user = null): array $rowNum++; } - $isPg = DB::connection()->getDriverName() === 'pgsql'; - // If retry mode, only process failed/invalid rows if ($isRetry) { $failedRows = ImportRow::where('import_id', $import->id) diff --git a/database/seeders/ImportEntitiesV2Seeder.php b/database/seeders/ImportEntitiesV2Seeder.php index 32d5c48..21be11f 100644 --- a/database/seeders/ImportEntitiesV2Seeder.php +++ b/database/seeders/ImportEntitiesV2Seeder.php @@ -17,11 +17,11 @@ public function run(): void 'key' => 'contracts', 'canonical_root' => 'contract', 'label' => 'Pogodbe', - 'fields' => ['reference', 'title', 'description', 'amount', 'currency', 'start_date', 'end_date', 'active'], + 'fields' => ['reference', 'start_date', 'end_date', 'description', 'type_id', 'client_case_id', 'meta'], 'field_aliases' => [], 'aliases' => ['contract', 'contracts'], 'supports_multiple' => false, - 'meta' => false, + 'meta' => true, 'rules' => [], 'ui' => ['default_field' => 'reference', 'order' => 1], 'handler_class' => \App\Services\Import\Handlers\ContractHandler::class, @@ -45,7 +45,7 @@ public function run(): void 'key' => 'accounts', 'canonical_root' => 'account', 'label' => 'Računi', - 'fields' => ['contract_id', 'reference', 'title', 'description', 'balance_amount', 'currency'], + 'fields' => ['reference', 'initial_amount', 'balance_amount', 'contract_id', 'contract_reference', 'type_id', 'active', 'description'], 'field_aliases' => [], 'aliases' => ['account', 'accounts'], 'supports_multiple' => false, @@ -75,8 +75,26 @@ public function run(): void 'key' => 'payments', 'canonical_root' => 'payment', 'label' => 'Plačila', - 'fields' => ['account_id', 'reference', 'amount', 'currency', 'paid_at', 'payment_date'], - 'field_aliases' => ['payment_date' => 'paid_at'], + 'fields' => [ + 'reference', + 'payment_nu', + 'payment_date', + 'amount', + 'type_id', + 'active', + // optional helpers for mapping by related records + 'debt_id', + 'account_id', + 'account_reference', + 'contract_reference' + ], + 'field_aliases' => [ + 'datum' => 'payment_date', + 'paid_at' => 'payment_date', + 'number' => 'payment_nu', + 'znesek' => 'amount', + 'value' => 'amount' + ], 'aliases' => ['payment', 'payments'], 'supports_multiple' => false, 'meta' => false, diff --git a/package-lock.json b/package-lock.json index 9fb72b0..67ca1eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@fortawesome/free-regular-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/vue-fontawesome": "^3.1.2", + "@guolao/vue-monaco-editor": "^1.6.0", "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.2.0", "@internationalized/date": "^3.10.0", @@ -27,9 +28,10 @@ "lodash": "^4.17.21", "lucide-vue-next": "^0.552.0", "material-design-icons-iconfont": "^6.7.0", + "monaco-editor": "^0.55.1", "preline": "^2.7.0", "quill": "^1.3.7", - "reka-ui": "^2.6.1", + "reka-ui": "^2.7.0", "tailwind-merge": "^3.4.0", "tailwindcss-animate": "^1.0.7", "tailwindcss-inner-border": "^0.2.0", @@ -879,6 +881,52 @@ "vue": ">= 3.0.0 < 4" } }, + "node_modules/@guolao/vue-monaco-editor": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@guolao/vue-monaco-editor/-/vue-monaco-editor-1.6.0.tgz", + "integrity": "sha512-w2IiJ6eJGGeuIgCK6EKZOAfhHTTUB5aZwslzwGbZ5e89Hb4avx6++GkLTW8p84Sng/arFMjLPPxSBI56cFudyQ==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.6.1", + "vue-demi": "latest" + }, + "peerDependencies": { + "@vue/composition-api": "^1.7.2", + "monaco-editor": ">=0.43.0", + "vue": "^2.6.14 || >=3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@guolao/vue-monaco-editor/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@headlessui/vue": { "version": "1.7.23", "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.23.tgz", @@ -1069,6 +1117,15 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@monaco-editor/loader": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", + "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -2309,6 +2366,13 @@ "@types/geojson": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/web-bluetooth": { "version": "0.0.21", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", @@ -3616,6 +3680,15 @@ "node": ">=8" } }, + "node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4664,6 +4737,18 @@ "vt-pbf": "^3.1.3" } }, + "node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/material-design-icons-iconfont": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-6.7.0.tgz", @@ -4736,6 +4821,16 @@ "node": ">=0.10.0" } }, + "node_modules/monaco-editor": { + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5074,9 +5169,9 @@ } }, "node_modules/reka-ui": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.6.1.tgz", - "integrity": "sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.7.0.tgz", + "integrity": "sha512-m+XmxQN2xtFzBP3OAdIafKq7C8OETo2fqfxcIIxYmNN2Ch3r5oAf6yEYCIJg5tL/yJU2mHqF70dCCekUkrAnXA==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.6.13", @@ -5386,6 +5481,12 @@ "node": ">=0.10.0" } }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, "node_modules/striptags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz", diff --git a/package.json b/package.json index b0da272..dbe40cc 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@fortawesome/free-regular-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/vue-fontawesome": "^3.1.2", + "@guolao/vue-monaco-editor": "^1.6.0", "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.2.0", "@internationalized/date": "^3.10.0", @@ -47,9 +48,10 @@ "lodash": "^4.17.21", "lucide-vue-next": "^0.552.0", "material-design-icons-iconfont": "^6.7.0", + "monaco-editor": "^0.55.1", "preline": "^2.7.0", "quill": "^1.3.7", - "reka-ui": "^2.6.1", + "reka-ui": "^2.7.0", "tailwind-merge": "^3.4.0", "tailwindcss-animate": "^1.0.7", "tailwindcss-inner-border": "^0.2.0", diff --git a/resources/js/Components/ui/progress/Progress.vue b/resources/js/Components/ui/progress/Progress.vue new file mode 100644 index 0000000..fa41c95 --- /dev/null +++ b/resources/js/Components/ui/progress/Progress.vue @@ -0,0 +1,34 @@ + + + diff --git a/resources/js/Components/ui/progress/index.js b/resources/js/Components/ui/progress/index.js new file mode 100644 index 0000000..e934a9b --- /dev/null +++ b/resources/js/Components/ui/progress/index.js @@ -0,0 +1 @@ +export { default as Progress } from "./Progress.vue"; diff --git a/resources/js/Layouts/AdminLayout.vue b/resources/js/Layouts/AdminLayout.vue index 0fbb090..cad7dc1 100644 --- a/resources/js/Layouts/AdminLayout.vue +++ b/resources/js/Layouts/AdminLayout.vue @@ -1,23 +1,23 @@ - - diff --git a/resources/js/Pages/Admin/EmailLogs/Show.vue b/resources/js/Pages/Admin/EmailLogs/Show.vue index ca27a30..db216c8 100644 --- a/resources/js/Pages/Admin/EmailLogs/Show.vue +++ b/resources/js/Pages/Admin/EmailLogs/Show.vue @@ -1,6 +1,11 @@ - + diff --git a/resources/js/Pages/Admin/SmsTemplates/Index.vue b/resources/js/Pages/Admin/SmsTemplates/Index.vue index 8fa29f3..dd8b9d7 100644 --- a/resources/js/Pages/Admin/SmsTemplates/Index.vue +++ b/resources/js/Pages/Admin/SmsTemplates/Index.vue @@ -1,10 +1,25 @@ diff --git a/resources/js/Pages/Imports/Import.vue b/resources/js/Pages/Imports/Import.vue index 28a46d9..83e18c1 100644 --- a/resources/js/Pages/Imports/Import.vue +++ b/resources/js/Pages/Imports/Import.vue @@ -751,14 +751,16 @@ async function fetchColumns() { async function applyTemplateToImport() { if (!importId.value || !form.value.import_template_id) return; - + // Find the selected template to get its UUID - const template = (props.templates || []).find((t) => t.id === form.value.import_template_id); + const template = (props.templates || []).find( + (t) => t.id === form.value.import_template_id + ); if (!template?.uuid) { - console.error('Template UUID not found'); + console.error("Template UUID not found"); return; } - + try { if (templateApplied.value) { const ok = window.confirm( @@ -1137,12 +1139,12 @@ async function fetchSimulation() { // V2 format paymentSimRows.value = Array.isArray(data?.rows) ? data.rows : []; paymentSimSummary.value = data?.summaries || null; - + // Extract unique entity types from rows for SimulationModal const entitySet = new Set(); for (const row of data?.rows || []) { - if (row.entities && typeof row.entities === 'object') { - Object.keys(row.entities).forEach(key => entitySet.add(key)); + if (row.entities && typeof row.entities === "object") { + Object.keys(row.entities).forEach((key) => entitySet.add(key)); } } paymentSimEntities.value = Array.from(entitySet); diff --git a/resources/js/Pages/Imports/Templates/Partials/BasicTemplateInfo.vue b/resources/js/Pages/Imports/Templates/Partials/BasicTemplateInfo.vue index eb71490..9508bf6 100644 --- a/resources/js/Pages/Imports/Templates/Partials/BasicTemplateInfo.vue +++ b/resources/js/Pages/Imports/Templates/Partials/BasicTemplateInfo.vue @@ -2,7 +2,13 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/Components/ui/card"; import { Label } from "@/Components/ui/label"; import { Input } from "@/Components/ui/input"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/Components/ui/select"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/Components/ui/select"; import { Checkbox } from "@/Components/ui/checkbox"; import { Button } from "@/Components/ui/button"; import AppMultiSelect from "@/Components/app/ui/AppMultiSelect.vue"; @@ -30,7 +36,7 @@ const emit = defineEmits(["save"]); - +