Newer
Older
<template>
<FormTable class="tw-max-w-3xl">
<FormGroup :label="t('noteEditor.title')" :errors="title.errors" :is-saving="title.isSaving">
<template #default="attrs">
<input
:placeholder="t('noteEditor.titlePlaceholder')"
required
v-bind="attrs"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/>
<p v-if="note.slug" class="tw-text-xs tw-text-gray-400 tw-mt-1 tw-mb-0">
{{ t('slug') }}: {{ note.slug }}
</p>
</template>
</FormGroup>
<FormGroup
:label="t('noteEditor.summary')"
:errors="summary.errors"
:is-saving="summary.isSaving"
>
<template #default="attrs">
<textarea
ref="summaryEl"
v-model="summary.value"
class="tw-resize-none tw-overflow-hidden tw-min-h-[3.55rem]"
:placeholder="t('noteEditor.summaryPlaceholder')"
v-bind="attrs"
@blur="summary.save()"
/>
</template>
</FormGroup>
<FormGroup
:label="t('noteEditor.content')"
:errors="content.errors"
:is-saving="content.isSaving"
>
<template #default="attrs">
<textarea
ref="contentEl"
v-model="content.value"
class="tw-resize-none tw-overflow-hidden tw-min-h-[8rem]"
rows="6"
:placeholder="t('noteEditor.contentPlaceholder')"
required
v-bind="attrs"
@blur="content.save()"
/>
</template>
</FormGroup>
<FormGroup
:label="t('noteEditor.image')"
:errors="imageId.errors"
:is-saving="imageId.isSaving"
custom-control
>
<ImagePicker v-model="imageId.value" class="tw-flex-none tw-w-min" />
</FormGroup>
<FormGroup
:label="t('noteEditor.contributors')"
:errors="contributors.errors"
:is-saving="contributors.isSaving"
>
<ComboBoxSimple v-model="contributors.value" :choices="contributors.choices" />
</FormGroup>
<FormGroup :label="t('noteEditor.topics')" :errors="topics.errors" :is-saving="topics.isSaving">
<ComboBoxSimple v-model="topics.value" :choices="topics.choices" />
</FormGroup>
<FormGroup
:label="t('noteEditor.languages')"
:errors="languages.errors"
:is-saving="languages.isSaving"
>
<ComboBoxSimple v-model="languages.value" :choices="languages.choices" />
</FormGroup>
<FormGroup :label="t('noteEditor.tags')" :errors="tags.errors" :is-saving="tags.isSaving">
<TagInput v-model="tags.value" />
</FormGroup>
<FormGroup
:label="t('noteEditor.links')"
:is-saving="links.isSaving"
:errors="getFieldErrors(links.errors, 'links')"
:has-error="links.errors.length > 0"
custom-control
>
<ALinkCollectionEditor
v-model="links.value"
:error-lists="getTreeFieldChildrenErrorsList(links.errors, 'links')"
allow-add
@save="links.save()"
/>
</FormGroup>
</FormTable>
</template>
<script lang="ts" setup>
import { useTextareaAutosize } from '@vueuse/core'
import { computed } from 'vue'
import { useI18n } from '@/i18n'
import { Note, Show, TimeSlot } from '@/types'
import { useHostStore, useLanguageStore, useNoteStore, useTopicStore } from '@/stores'
import FormGroup from '@/components/generic/FormGroup.vue'
import ImagePicker from '@/components/images/ImagePicker.vue'
import TagInput from '@/components/generic/TagInput.vue'
import ComboBoxSimple from '@/components/ComboBoxSimple.vue'
import {
getFieldErrors,
getTreeFieldChildrenErrorsList,
useAPIObjectFieldCopy,
useRelationList,
} from '@/form'
import FormTable from '@/components/generic/FormTable.vue'
import ALinkCollectionEditor from '@/components/generic/ALinkCollectionEditor.vue'
defineOptions({ compatConfig: { MODE: 3 } })
const props = defineProps<{
timeslot: TimeSlot
show: Show
note: Note
}>()
const { t } = useI18n()
const noteStore = useNoteStore()
const hostStore = useHostStore()
const languageStore = useLanguageStore()
const topicStore = useTopicStore()
const note = computed(() => props.note)
const title = useAPIObjectFieldCopy(noteStore, note, 'title', { debounce: 2 })
const summary = useAPIObjectFieldCopy(noteStore, note, 'summary', { noAutoSave: true })
const content = useAPIObjectFieldCopy(noteStore, note, 'content', { noAutoSave: true })
const tags = useAPIObjectFieldCopy(noteStore, note, 'tags')
const imageId = useAPIObjectFieldCopy(noteStore, note, 'imageId', { debounce: 0 })
const links = useAPIObjectFieldCopy(noteStore, note, 'links', { debounce: 2 })
const contributors = useRelationList(noteStore, note, 'contributorIds', hostStore)
const languages = useRelationList(noteStore, note, 'languageIds', languageStore)
const topics = useRelationList(noteStore, note, 'topicIds', topicStore)
const { textarea: summaryEl } = useTextareaAutosize({ watch: () => note.value.summary })
const { textarea: contentEl } = useTextareaAutosize({ watch: () => note.value.content })
</script>