feat: registration field polish, multi-category tags, file uploads, Partner icon
- Restructure field editor dialog: move Options section to bottom with divider and subheader, fix delete button with flex layout - Change tag_category (single string) to tag_categories (JSON array) supporting multiple category selection in tag picker fields - Portal tag picker now groups tags by category with subheaders - Add generic file upload endpoint (FileUploadService + UploadController) - Replace email branding logo URL text field with ImageUploadField - Update Partner crowd type default icon to tabler-affiliate - Apply changes consistently to both field and template dialogs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -263,6 +263,21 @@ function isMultiValueType(t: RegistrationFieldType): boolean {
|
||||
return t === 'multiselect' || t === 'checkbox' || t === 'tag_picker'
|
||||
}
|
||||
|
||||
function groupedTagItems(tags: Array<{ id: string; name: string; category: string | null }>) {
|
||||
const items: Array<{ type?: string; title: string; value?: string }> = []
|
||||
let lastCategory: string | null = null
|
||||
|
||||
for (const tag of tags) {
|
||||
if (tag.category !== lastCategory) {
|
||||
items.push({ type: 'subheader', title: tag.category ?? 'Overig' })
|
||||
lastCategory = tag.category
|
||||
}
|
||||
items.push({ title: tag.name, value: tag.id })
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
function isEmptyFieldValue(value: unknown, type: RegistrationFieldType): boolean {
|
||||
if (value === undefined || value === null) return true
|
||||
if (value === '') return true
|
||||
@@ -1251,7 +1266,7 @@ async function onSubmit() {
|
||||
:error-messages="fieldErrors[field.slug]"
|
||||
/>
|
||||
|
||||
<VSelect
|
||||
<VAutocomplete
|
||||
v-else-if="field.field_type === 'tag_picker'"
|
||||
v-model="fieldFormData[field.slug] as string[]"
|
||||
variant="outlined"
|
||||
@@ -1260,9 +1275,9 @@ async function onSubmit() {
|
||||
multiple
|
||||
chips
|
||||
closable-chips
|
||||
:items="field.available_tags ?? []"
|
||||
item-title="name"
|
||||
item-value="id"
|
||||
:items="groupedTagItems(field.available_tags ?? [])"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:label="field.label + (field.is_required ? ' *' : '')"
|
||||
:hint="field.help_text ?? undefined"
|
||||
persistent-hint
|
||||
|
||||
@@ -30,7 +30,7 @@ export interface RegistrationField {
|
||||
field_type: RegistrationFieldType
|
||||
options: (string | { label: string; description?: string | null })[] | null
|
||||
normalized_options: NormalizedOption[] | null
|
||||
tag_category: string | null
|
||||
tag_categories: string[] | null
|
||||
is_required: boolean
|
||||
help_text: string | null
|
||||
display_width: FieldDisplayWidth
|
||||
|
||||
Reference in New Issue
Block a user