From 24821fde6e1acf9f53842ac6cc76df769923bc99 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Wed, 4 Mar 2026 21:55:06 +0100 Subject: [PATCH 1/5] feat: custom field ordering --- .../migration.sql | 2 + apps/api/prisma/schema/CustomField.prisma | 1 + .../customFields/customFields.router.ts | 6 +- .../services/customFields/customFieldsList.ts | 73 +++++--- .../customFields/schema/customField.schema.ts | 26 ++- .../customFieldsUnterveranstaltungOrder.ts | 54 ++++++ .../schema/customFieldsVeranstaltungOrder.ts | 44 +++++ .../CustomFields/CustomFieldsTable.vue | 13 ++ .../CustomFieldUnterveranstaltungOrder.vue | 168 ++++++++++++++++++ .../UnterveranstaltungDetail.vue | 11 ++ .../src/views/Unterveranstaltung/routes.ts | 13 ++ .../CustomFieldVeranstaltungOrder.vue | 126 +++++++++++++ .../Veranstaltungen/VeranstaltungDetail.vue | 26 ++- .../Verwaltung/Veranstaltungen/routes.ts | 13 ++ 14 files changed, 536 insertions(+), 40 deletions(-) create mode 100644 apps/api/prisma/migrations/20260304182124_custom_field_order/migration.sql create mode 100644 apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts create mode 100644 apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts create mode 100644 apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue create mode 100644 apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue diff --git a/apps/api/prisma/migrations/20260304182124_custom_field_order/migration.sql b/apps/api/prisma/migrations/20260304182124_custom_field_order/migration.sql new file mode 100644 index 00000000..79c1d2b8 --- /dev/null +++ b/apps/api/prisma/migrations/20260304182124_custom_field_order/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "CustomField" ADD COLUMN "order" INTEGER; diff --git a/apps/api/prisma/schema/CustomField.prisma b/apps/api/prisma/schema/CustomField.prisma index 0a1415df..ac05f0a7 100644 --- a/apps/api/prisma/schema/CustomField.prisma +++ b/apps/api/prisma/schema/CustomField.prisma @@ -19,6 +19,7 @@ model CustomField { id String @id @default(uuid(7)) name String description String? + order Int? type CustomFieldType required Boolean @default(false) options String[] diff --git a/apps/api/src/services/customFields/customFields.router.ts b/apps/api/src/services/customFields/customFields.router.ts index 3e38d8cc..5f861fa8 100644 --- a/apps/api/src/services/customFields/customFields.router.ts +++ b/apps/api/src/services/customFields/customFields.router.ts @@ -9,6 +9,8 @@ import { customFieldsVeranstaltungCreate } from './customFieldsVeranstaltungCrea import { customFieldsVeranstaltungDelete, customFieldsUnterveranstaltungDelete } from './customFieldsDelete.js' import { customFieldsUpdate } from './customFieldsUpdate.js' import { customFieldValuesUpdate } from './customFieldValuesUpdate.js' +import { customFieldUnterveranstaltungOrder } from './schema/customFieldsUnterveranstaltungOrder.js' +import { customFieldVeranstaltungOrder } from './schema/customFieldsVeranstaltungOrder.js' // Import Routes here - do not delete this line export const customFieldsRouter = mergeRouters( @@ -21,6 +23,8 @@ export const customFieldsRouter = mergeRouters( customFieldsUnterveranstaltungDelete, customFieldsUnterveranstaltungCreate, customFieldValuesUpdate, - customFieldsTemplates + customFieldsTemplates, + customFieldVeranstaltungOrder, + customFieldUnterveranstaltungOrder // Add Routes here - do not delete this line ) diff --git a/apps/api/src/services/customFields/customFieldsList.ts b/apps/api/src/services/customFields/customFieldsList.ts index f7d9a09c..35fbd0f9 100644 --- a/apps/api/src/services/customFields/customFieldsList.ts +++ b/apps/api/src/services/customFields/customFieldsList.ts @@ -2,7 +2,7 @@ import { z } from 'zod' import { CustomFieldPosition, CustomFieldType, Prisma } from '@prisma/client' import prisma from '../../prisma.js' -import { definePublicQueryProcedure } from '../../types/defineProcedure.js' +import { defineProtectedQueryProcedure, definePublicQueryProcedure } from '../../types/defineProcedure.js' import { calculatePagination, defineEmptyQueryResponse, @@ -10,6 +10,7 @@ import { defineTableInput, } from '../../types/defineTableProcedure.js' import { boolish } from '../../util/zod.js' +import { getGliederungRequireAdmin } from '../../util/getGliederungRequireAdmin.js' const baseFilter = z.strictObject({ entity: z.enum(['veranstaltung', 'unterveranstaltung']), @@ -23,6 +24,7 @@ export const customFieldsTable = definePublicQueryProcedure({ async handler({ input: { entity, entityId, position } }) { if (entity === 'veranstaltung') { return await prisma.customField.findMany({ + orderBy: [{ order: { sort: 'asc', nulls: 'last' } }], where: { veranstaltungId: entityId, positions: @@ -35,6 +37,14 @@ export const customFieldsTable = definePublicQueryProcedure({ }) } else if (entity === 'unterveranstaltung') { return await prisma.customField.findMany({ + orderBy: [ + { + unterveranstaltungId: { sort: 'asc', nulls: 'first' }, + }, + { + order: { sort: 'asc', nulls: 'last' }, + }, + ], where: { positions: position === undefined @@ -64,8 +74,9 @@ export const customFieldsTable = definePublicQueryProcedure({ }, }) -export const customFieldsList = definePublicQueryProcedure({ +export const customFieldsList = defineProtectedQueryProcedure({ key: 'table', + roleIds: ['ADMIN', 'GLIEDERUNG_ADMIN'], inputSchema: baseFilter.extend({ table: defineTableInput({ filter: { @@ -74,10 +85,14 @@ export const customFieldsList = definePublicQueryProcedure({ required: boolish, position: z.nativeEnum(CustomFieldPosition), }, - orderBy: ['name'], + orderBy: ['name', 'order'], }), }), - async handler({ input }) { + async handler({ ctx, input }) { + if (ctx.account.role === 'GLIEDERUNG_ADMIN') { + await getGliederungRequireAdmin(ctx.accountId) + } + const where: Prisma.CustomFieldWhereInput = { name: { contains: input.table?.filter?.name, @@ -93,6 +108,25 @@ export const customFieldsList = definePublicQueryProcedure({ }, } + if (input.entity === 'veranstaltung') { + where.veranstaltungId = input.entityId + } else if (input.entity === 'unterveranstaltung') { + where.OR = [ + { + unterveranstaltungId: input.entityId, + }, + { + veranstaltung: { + unterveranstaltungen: { + some: { + id: input.entityId, + }, + }, + }, + }, + ] + } + const total = await prisma.customField.count({ where }) const { pageIndex, pageSize, pages } = calculatePagination(total, input.table?.pagination) @@ -100,15 +134,13 @@ export const customFieldsList = definePublicQueryProcedure({ const customFields = await prisma.customField.findMany({ take: pageSize, skip: pageSize * pageIndex, - where: { - ...where, - veranstaltungId: input.entityId, - }, + where, orderBy: input.table?.orderBy, select: { id: true, name: true, description: true, + order: true, type: true, positions: true, required: true, @@ -122,27 +154,18 @@ export const customFieldsList = definePublicQueryProcedure({ const customFields = await prisma.customField.findMany({ take: pageSize, skip: pageSize * pageIndex, - where: { - ...where, - OR: [ - { - unterveranstaltungId: input.entityId, - }, - { - veranstaltung: { - unterveranstaltungen: { - some: { - id: input.entityId, - }, - }, - }, - }, - ], - }, + orderBy: [ + { + unterveranstaltungId: { sort: 'asc', nulls: 'first' }, + }, + ...(input.table?.orderBy ?? []), + ], + where, select: { id: true, name: true, description: true, + order: true, type: true, positions: true, required: true, diff --git a/apps/api/src/services/customFields/schema/customField.schema.ts b/apps/api/src/services/customFields/schema/customField.schema.ts index 8172e451..af4585c1 100644 --- a/apps/api/src/services/customFields/schema/customField.schema.ts +++ b/apps/api/src/services/customFields/schema/customField.schema.ts @@ -1,11 +1,21 @@ import { CustomFieldPosition, CustomFieldType } from '@prisma/client' import { z } from 'zod' -export const customFieldSchema = z.strictObject({ - name: z.string().min(1), - description: z.string().nullable(), - type: z.nativeEnum(CustomFieldType), - required: z.boolean(), - options: z.array(z.string()), - positions: z.nativeEnum(CustomFieldPosition).array(), -}) +export const customFieldSchema = z + .strictObject({ + name: z.string().min(1), + description: z.string().nullable(), + type: z.nativeEnum(CustomFieldType), + required: z.boolean(), + options: z.array(z.string()), + positions: z.nativeEnum(CustomFieldPosition).array().min(1), + }) + .superRefine((values, ctx) => { + const optionTypes = ['BASIC_DROPDOWN', 'BASIC_RADIO', 'BASIC_SWITCH'] as CustomFieldType[] + if (optionTypes.includes(values.type) && values.options.length === 0) { + ctx.addIssue({ + code: 'custom', + message: 'Es muss mindestens eine Auswahlmöglichkeit angegeben werden', + }) + } + }) diff --git a/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts b/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts new file mode 100644 index 00000000..8f672d27 --- /dev/null +++ b/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts @@ -0,0 +1,54 @@ +import z from 'zod' +import { defineProtectedMutateProcedure } from '../../../types/defineProcedure.js' +import { getGliederungRequireAdmin } from '../../../util/getGliederungRequireAdmin.js' +import { TRPCError } from '@trpc/server' +import prisma from '../../../prisma.js' + +export const customFieldUnterveranstaltungOrder = defineProtectedMutateProcedure({ + key: 'unterveranstaltungOrder', + roleIds: ['ADMIN', 'GLIEDERUNG_ADMIN'], + inputSchema: z.strictObject({ + unterveranstaltungId: z.uuid(), + fields: z.array(z.uuid()), + }), + handler: async ({ ctx, input }) => { + if (ctx.account.role === 'GLIEDERUNG_ADMIN') { + const gliederung = await getGliederungRequireAdmin(ctx.accountId) + if (gliederung.id !== input.unterveranstaltungId) { + throw new TRPCError({ + code: 'FORBIDDEN', + }) + } + } + + const fields = await prisma.customField.findMany({ + where: { + unterveranstaltungId: input.unterveranstaltungId, + id: { + in: input.fields, + }, + }, + }) + + if (fields.length !== input.fields.length) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'Some supplied fields do not belong to the given unterveranstaltung!', + }) + } + + await prisma.$transaction( + input.fields.map((field, index) => + prisma.customField.update({ + where: { + unterveranstaltungId: input.unterveranstaltungId, + id: field, + }, + data: { + order: index + 1, + }, + }) + ) + ) + }, +}) diff --git a/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts b/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts new file mode 100644 index 00000000..ac435865 --- /dev/null +++ b/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts @@ -0,0 +1,44 @@ +import { TRPCError } from '@trpc/server' +import z from 'zod' +import prisma from '../../../prisma.js' +import { defineProtectedMutateProcedure } from '../../../types/defineProcedure.js' + +export const customFieldVeranstaltungOrder = defineProtectedMutateProcedure({ + key: 'veranstaltungOrder', + roleIds: ['ADMIN'], + inputSchema: z.strictObject({ + veranstaltungId: z.uuid(), + fields: z.array(z.uuid()), + }), + handler: async ({ input }) => { + const fields = await prisma.customField.findMany({ + where: { + veranstaltungId: input.veranstaltungId, + id: { + in: input.fields, + }, + }, + }) + + if (fields.length !== input.fields.length) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'Some supplied fields do not belong to the given veranstaltung!', + }) + } + + await prisma.$transaction( + input.fields.map((field, index) => + prisma.customField.update({ + where: { + veranstaltungId: input.veranstaltungId, + id: field, + }, + data: { + order: index + 1, + }, + }) + ) + ) + }, +}) diff --git a/apps/frontend/src/components/CustomFields/CustomFieldsTable.vue b/apps/frontend/src/components/CustomFields/CustomFieldsTable.vue index f9bcf945..2ec38a34 100644 --- a/apps/frontend/src/components/CustomFields/CustomFieldsTable.vue +++ b/apps/frontend/src/components/CustomFields/CustomFieldsTable.vue @@ -32,6 +32,18 @@ const router = useRouter() const column = createColumnHelper() const columns = [ + column.accessor('order', { + header: 'Reihenfolge', + enableSorting: true, + cell({ getValue }) { + const order = getValue() + if (!order) { + return '-' + } + + return order + }, + }), column.accessor('name', { header: 'Name', enableColumnFilter: true, @@ -174,6 +186,7 @@ function onClick(field: CustomField) { diff --git a/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue new file mode 100644 index 00000000..d324a12e --- /dev/null +++ b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue @@ -0,0 +1,168 @@ + + + diff --git a/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue b/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue index 8c8f7e8a..6a8eecbf 100644 --- a/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue +++ b/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue @@ -371,6 +371,7 @@ const anmeldeLinkCreateModal = useTemplateRef('anmeldeLinkCreateModal') Hier können benutzerdefinierte Felder erstellt werden, welche für alle Unterveranstaltungen gelten.

+
+ Reihenfolge ändern + +
import('./CustomFields/CustomFieldUnterveranstaltungOrder.vue'), + meta: { + breadcrumbs: [ + detailCrumb, + { + text: 'Benutzerdefinierte Felder sortieren', + }, + ], + }, + }, { name: 'Unterveranstaltung Custom Field bearbeiten', path: ':unterveranstaltungId/fields/:fieldId', diff --git a/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue new file mode 100644 index 00000000..347fd5f3 --- /dev/null +++ b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue @@ -0,0 +1,126 @@ + + + diff --git a/apps/frontend/src/views/Verwaltung/Veranstaltungen/VeranstaltungDetail.vue b/apps/frontend/src/views/Verwaltung/Veranstaltungen/VeranstaltungDetail.vue index 7730e943..74d2d789 100644 --- a/apps/frontend/src/views/Verwaltung/Veranstaltungen/VeranstaltungDetail.vue +++ b/apps/frontend/src/views/Verwaltung/Veranstaltungen/VeranstaltungDetail.vue @@ -10,6 +10,7 @@ import { RocketLaunchIcon, DocumentDuplicateIcon, LinkIcon, + ChevronUpDownIcon, } from '@heroicons/vue/24/outline' import { useAsyncState } from '@vueuse/core' import { computed } from 'vue' @@ -352,12 +353,25 @@ function copyProgramLink() { Hier können benutzerdefinierte Felder erstellt werden, welche für alle Unterveranstaltungen gelten.

- - Neues Feld - +
+ + + Neues Feld + + + + Reihenfolge ändern + +
import('./CustomFields/CustomFieldVeranstaltungOrder.vue'), + meta: { + breadcrumbs: [ + detailCrumb, + { + text: 'Benutzerdefinierte Felder sortieren', + }, + ], + }, + }, { name: 'Verwaltung Custom Field bearbeiten', path: ':veranstaltungId/fields/:fieldId', From 82b0b30c1c640ab5ca58705f0c15b14e6387ebbe Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Wed, 4 Mar 2026 22:50:52 +0100 Subject: [PATCH 2/5] chore: remove unused import --- .../CustomFields/CustomFieldVeranstaltungOrder.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue index 347fd5f3..0e0d5c20 100644 --- a/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue +++ b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue @@ -2,7 +2,6 @@ import { apiClient } from '@/api' import Button from '@/components/UIComponents/Button.vue' import { useRouteTitle } from '@/composables/useRouteTitle' -import cn from '@/helpers/cn' import { CustomFieldTypeMapping, type CustomField } from '@codeanker/api' import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline' import { useMutation, useQuery } from '@tanstack/vue-query' From 0ab0d2aa4679307b7ea42bd9b2820b09ba7def51 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Wed, 4 Mar 2026 23:00:42 +0100 Subject: [PATCH 3/5] fix: zod schema --- .../schema/customFieldsUnterveranstaltungOrder.ts | 4 ++-- .../customFields/schema/customFieldsVeranstaltungOrder.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts b/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts index 8f672d27..2b0f974a 100644 --- a/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts +++ b/apps/api/src/services/customFields/schema/customFieldsUnterveranstaltungOrder.ts @@ -8,8 +8,8 @@ export const customFieldUnterveranstaltungOrder = defineProtectedMutateProcedure key: 'unterveranstaltungOrder', roleIds: ['ADMIN', 'GLIEDERUNG_ADMIN'], inputSchema: z.strictObject({ - unterveranstaltungId: z.uuid(), - fields: z.array(z.uuid()), + unterveranstaltungId: z.string().uuid(), + fields: z.array(z.string().uuid()), }), handler: async ({ ctx, input }) => { if (ctx.account.role === 'GLIEDERUNG_ADMIN') { diff --git a/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts b/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts index ac435865..3cc63732 100644 --- a/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts +++ b/apps/api/src/services/customFields/schema/customFieldsVeranstaltungOrder.ts @@ -7,8 +7,8 @@ export const customFieldVeranstaltungOrder = defineProtectedMutateProcedure({ key: 'veranstaltungOrder', roleIds: ['ADMIN'], inputSchema: z.strictObject({ - veranstaltungId: z.uuid(), - fields: z.array(z.uuid()), + veranstaltungId: z.string().uuid(), + fields: z.array(z.string().uuid()), }), handler: async ({ input }) => { const fields = await prisma.customField.findMany({ From 21c880347e8e1745a263290542a397ab905ae410 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Wed, 4 Mar 2026 23:17:45 +0100 Subject: [PATCH 4/5] chore: ui updates --- .../CustomFieldUnterveranstaltungOrder.vue | 28 ++++++++++++++++--- .../UnterveranstaltungDetail.vue | 12 +++++--- .../CustomFieldVeranstaltungOrder.vue | 25 +++++++++++++++-- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue index d324a12e..ae0387af 100644 --- a/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue +++ b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue @@ -5,10 +5,11 @@ import { useRouteTitle } from '@/composables/useRouteTitle' import cn from '@/helpers/cn' import { CustomFieldTypeMapping, type CustomField } from '@codeanker/api' import { groupBy } from '@codeanker/helpers' -import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline' +import { ArrowLeftIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline' import { useMutation, useQuery } from '@tanstack/vue-query' import { useRouteParams } from '@vueuse/router' import { computed, ref, watch } from 'vue' +import { RouterLink } from 'vue-router' const { setTitle } = useRouteTitle() setTitle('Benutzerdefinierte Felder sortieren') @@ -93,6 +94,23 @@ const { mutate, isPending } = useMutation({ diff --git a/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue b/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue index 6a8eecbf..83b18296 100644 --- a/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue +++ b/apps/frontend/src/views/Unterveranstaltung/UnterveranstaltungDetail.vue @@ -2,12 +2,14 @@ import { CameraIcon, ChatBubbleLeftRightIcon, + ChevronUpDownIcon, CodeBracketIcon, DocumentDuplicateIcon, DocumentIcon, HandRaisedIcon, LinkIcon, MegaphoneIcon, + PlusIcon, RocketLaunchIcon, SquaresPlusIcon, UserGroupIcon, @@ -373,22 +375,24 @@ const anmeldeLinkCreateModal = useTemplateRef('anmeldeLinkCreateModal')
- Neues Feld + + Neues Feld - Reihenfolge ändern + + Reihenfolge ändern
diff --git a/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue index 0e0d5c20..df07c4a2 100644 --- a/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue +++ b/apps/frontend/src/views/Verwaltung/Veranstaltungen/CustomFields/CustomFieldVeranstaltungOrder.vue @@ -3,7 +3,7 @@ import { apiClient } from '@/api' import Button from '@/components/UIComponents/Button.vue' import { useRouteTitle } from '@/composables/useRouteTitle' import { CustomFieldTypeMapping, type CustomField } from '@codeanker/api' -import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline' +import { ArrowLeftIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline' import { useMutation, useQuery } from '@tanstack/vue-query' import { useRouteParams } from '@vueuse/router' import { ref, watch } from 'vue' @@ -60,6 +60,23 @@ const { mutate, isPending } = useMutation({ From 7a0779c3932d75cd84134b7bf6e3076ea828b1a3 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Thu, 5 Mar 2026 09:18:21 +0100 Subject: [PATCH 5/5] feat: show notification --- .../CustomFieldUnterveranstaltungOrder.vue | 15 +++++++++++++++ .../CustomFieldVeranstaltungOrder.vue | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue index ae0387af..8cb874a9 100644 --- a/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue +++ b/apps/frontend/src/views/Unterveranstaltung/CustomFields/CustomFieldUnterveranstaltungOrder.vue @@ -1,5 +1,6 @@