Skip to content
Snippets Groups Projects
Commit dcdc54fc authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

feat: add new profile selector that supports adding new profiles

refs #219
parent 4f1901b6
No related branches found
No related tags found
No related merge requests found
Pipeline #8160 passed
...@@ -235,7 +235,7 @@ ...@@ -235,7 +235,7 @@
:errors="hosts.errors" :errors="hosts.errors"
edit-permissions="program.edit__show__hosts" edit-permissions="program.edit__show__hosts"
> >
<ComboBoxSimple v-model="hosts.value" :choices="hosts.choices" :disabled="disabled" /> <AProfileSelector v-model="hosts.value" :disabled="disabled" />
</FormGroup> </FormGroup>
<FormGroup <FormGroup
...@@ -397,6 +397,7 @@ import ImagePicker from '@/components/images/ImagePicker.vue' ...@@ -397,6 +397,7 @@ import ImagePicker from '@/components/images/ImagePicker.vue'
import AFieldset from '@/components/generic/AFieldset.vue' import AFieldset from '@/components/generic/AFieldset.vue'
import APlaylistEditor from '@/components/playlist/APlaylistEditor.vue' import APlaylistEditor from '@/components/playlist/APlaylistEditor.vue'
import AUserSelector from '@/components/identities/AUserSelector.vue' import AUserSelector from '@/components/identities/AUserSelector.vue'
import AProfileSelector from '@/components/identities/AProfileSelector.vue'
const props = defineProps<{ const props = defineProps<{
show: Show show: Show
......
<template>
<ComboBoxSimple
v-bind="props"
v-model="modelValue"
v-model:searchTerm="searchTerm"
:search-provider="searchProfiles"
:resolve-choice="resolveProfileChoice"
>
<template #default="{ choice, index, activeIndex, ...itemAttrs }">
<li v-bind="itemAttrs">
{{ (choice as Host).name }}
<span
v-if="choice.id === -1 && index === activeIndex && existingSimilarResults.length > 0"
class="tw-block tw-mt-1 tw-pt-1 tw-text-sm tw-text-white/75 tw-border-t tw-border-t-black/10"
>
{{ t('profile.labels.similarSelected', { names: existingSimilarResults.join(', ') }) }}
</span>
</li>
</template>
</ComboBoxSimple>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useHostStore } from '@/stores'
import { Host } from '@/types'
import ComboBoxSimple, { ComboBoxSimpleProps } from '@/components/ComboBoxSimple.vue'
import { useI18n } from '@/i18n'
import { matchesSearch } from '@/util'
const modelValue = defineModel<null | Host | Host[]>({ required: true })
const props = defineProps<Omit<ComboBoxSimpleProps<Host>, 'choices' | 'searchProvider'>>()
const { t } = useI18n()
const hostStore = useHostStore()
const searchTerm = ref('')
const existingSimilarResults = computed(() => {
const value = Array.isArray(modelValue.value)
? modelValue.value
: modelValue.value
? [modelValue.value]
: []
return value.filter((v) => matchesSearch(v.name, searchTerm.value)).map((v) => v.name)
})
async function searchProfiles(query: string, signal: AbortSignal) {
const result = await hostStore.list(1, {
query: new URLSearchParams({ search: query, limit: '10' }),
requestInit: { signal },
})
if (query.trim()) {
result.push({ id: -1, name: t('profile.labels.createNew', { name: query }) } as Host)
}
return result
}
async function resolveProfileChoice(choice: Host | null | undefined, name: string) {
if (choice?.id === -1 && name) {
return await hostStore.create({ name, ownerIds: [] })
}
return choice ?? null
}
</script>
...@@ -68,11 +68,7 @@ ...@@ -68,11 +68,7 @@
:is-saving="contributors.isSaving" :is-saving="contributors.isSaving"
show-permissions="program.edit__note__contributors" show-permissions="program.edit__note__contributors"
> >
<ComboBoxSimple <AProfileSelector v-model="contributors.value" :disabled="disabled" />
v-model="contributors.value"
:choices="contributors.choices"
:disabled="disabled"
/>
</FormGroup> </FormGroup>
<FormGroup <FormGroup
...@@ -129,16 +125,18 @@ ...@@ -129,16 +125,18 @@
import { computed } from 'vue' import { computed } from 'vue'
import { useI18n } from '@/i18n' import { useI18n } from '@/i18n'
import { Note, Show, TimeSlot } from '@/types' import { useAPIObjectFieldCopy, useRelationList } from '@/form'
import { useHostStore, useLanguageStore, useNoteStore, useTopicStore } from '@/stores' import { useHostStore, useLanguageStore, useNoteStore, useTopicStore } from '@/stores'
import { Note, Show, TimeSlot } from '@/types'
import FormGroup from '@/components/generic/FormGroup.vue' import FormGroup from '@/components/generic/FormGroup.vue'
import ImagePicker from '@/components/images/ImagePicker.vue' import ImagePicker from '@/components/images/ImagePicker.vue'
import TagInput from '@/components/generic/TagInput.vue' import TagInput from '@/components/generic/TagInput.vue'
import ComboBoxSimple from '@/components/ComboBoxSimple.vue' import ComboBoxSimple from '@/components/ComboBoxSimple.vue'
import { useAPIObjectFieldCopy, useRelationList } from '@/form'
import FormTable from '@/components/generic/FormTable.vue' import FormTable from '@/components/generic/FormTable.vue'
import ALinkCollectionEditor from '@/components/generic/ALinkCollectionEditor.vue' import ALinkCollectionEditor from '@/components/generic/ALinkCollectionEditor.vue'
import AHTMLEditor from '@/components/generic/AHTMLEditor.vue' import AHTMLEditor from '@/components/generic/AHTMLEditor.vue'
import AProfileSelector from '@/components/identities/AProfileSelector.vue'
const props = defineProps<{ const props = defineProps<{
timeslot: TimeSlot timeslot: TimeSlot
......
...@@ -43,6 +43,8 @@ export default { ...@@ -43,6 +43,8 @@ export default {
}, },
labels: { labels: {
hasAccount: 'Hat Konto', hasAccount: 'Hat Konto',
createNew: '„%{name}“ anlegen',
similarSelected: 'Ähnliche bereits ausgewählte Profile: %{names}',
}, },
editor: { editor: {
deletion: { deletion: {
......
...@@ -43,6 +43,8 @@ export default { ...@@ -43,6 +43,8 @@ export default {
}, },
labels: { labels: {
hasAccount: 'Has account', hasAccount: 'Has account',
createNew: 'Create “%{name}”',
similarSelected: 'Similar already selected profiles: %{names}',
}, },
editor: { editor: {
deletion: { deletion: {
......
import { import {
APICreate,
APIListPaginated, APIListPaginated,
APIRemove, APIRemove,
APIRetrieve, APIRetrieve,
...@@ -23,6 +24,7 @@ export const useHostStore = defineStore('hosts', () => { ...@@ -23,6 +24,7 @@ export const useHostStore = defineStore('hosts', () => {
...base, ...base,
...APIListPaginated(api), ...APIListPaginated(api),
...APIRetrieve(api), ...APIRetrieve(api),
...APICreate(api),
...APIUpdate<Host, HostUpdateData, HostPartialUpdateData>(api), ...APIUpdate<Host, HostUpdateData, HostPartialUpdateData>(api),
...APIRemove(api), ...APIRemove(api),
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment