fix(form): editing form for library objects
This commit is contained in:
parent
61e6b3fa0f
commit
32093949c7
|
@ -9,21 +9,19 @@ import { useStore } from '~/store'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import AttachmentInput from '~/components/common/AttachmentInput.vue'
|
|
||||||
import useEditConfigs from '~/composables/moderation/useEditConfigs'
|
|
||||||
import TagsSelector from '~/components/library/TagsSelector.vue'
|
|
||||||
import EditList from '~/components/library/EditList.vue'
|
|
||||||
import EditCard from '~/components/library/EditCard.vue'
|
|
||||||
import Layout from '~/components/ui/Layout.vue'
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
import Button from '~/components/ui/Button.vue'
|
import Button from '~/components/ui/Button.vue'
|
||||||
import Link from '~/components/ui/Link.vue'
|
|
||||||
import Section from '~/components/ui/Section.vue'
|
|
||||||
import Spacer from '~/components/ui/Spacer.vue'
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
import Input from '~/components/ui/Input.vue'
|
import Input from '~/components/ui/Input.vue'
|
||||||
import Textarea from "~/components/ui/Textarea.vue"
|
import Textarea from "~/components/ui/Textarea.vue"
|
||||||
import Pills from "~/components/ui/Pills.vue"
|
import Pills from "~/components/ui/Pills.vue"
|
||||||
import Alert from "~/components/ui/Alert.vue"
|
import Alert from "~/components/ui/Alert.vue"
|
||||||
|
|
||||||
|
import AttachmentInput from '~/components/common/AttachmentInput.vue'
|
||||||
|
import useEditConfigs from '~/composables/moderation/useEditConfigs'
|
||||||
|
import EditList from '~/components/library/EditList.vue'
|
||||||
|
import EditCard from '~/components/library/EditCard.vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
objectType: EditObjectType
|
objectType: EditObjectType
|
||||||
object: EditObject
|
object: EditObject
|
||||||
|
@ -147,14 +145,17 @@ const resetField = (fieldId: string) => {
|
||||||
:obj="submittedMutation"
|
:obj="submittedMutation"
|
||||||
:current-state="currentState"
|
:current-state="currentState"
|
||||||
/>
|
/>
|
||||||
<Link
|
<Button
|
||||||
solid primary
|
solid primary
|
||||||
@click.prevent="submittedMutation = null"
|
@click.prevent="submittedMutation = null"
|
||||||
>
|
>
|
||||||
{{ t('components.library.EditForm.button.new') }}
|
{{ t('components.library.EditForm.button.new') }}
|
||||||
</Link>
|
</Button>
|
||||||
</Alert>
|
</Alert>
|
||||||
<div v-else>
|
<Layout gap-32 v-else>
|
||||||
|
|
||||||
|
<!-- Previous edits -->
|
||||||
|
|
||||||
<edit-list
|
<edit-list
|
||||||
:filters="editListFilters"
|
:filters="editListFilters"
|
||||||
:url="mutationsUrl"
|
:url="mutationsUrl"
|
||||||
|
@ -188,7 +189,10 @@ const resetField = (fieldId: string) => {
|
||||||
</empty-state>
|
</empty-state>
|
||||||
</template>
|
</template>
|
||||||
</edit-list>
|
</edit-list>
|
||||||
<Layout form
|
|
||||||
|
<!-- Add new edits -->
|
||||||
|
|
||||||
|
<form style="display: contents;"
|
||||||
@submit.prevent="submit()"
|
@submit.prevent="submit()"
|
||||||
>
|
>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
|
@ -213,14 +217,13 @@ const resetField = (fieldId: string) => {
|
||||||
>
|
>
|
||||||
{{ t('components.library.EditForm.message.noPermission') }}
|
{{ t('components.library.EditForm.message.noPermission') }}
|
||||||
</Alert>
|
</Alert>
|
||||||
<template v-if="values">
|
<Layout stack gap-8
|
||||||
<div
|
v-if="values"
|
||||||
v-for="fieldConfig in config.fields"
|
v-for="fieldConfig in config.fields"
|
||||||
:key="fieldConfig.id"
|
:key="fieldConfig.id"
|
||||||
class="ui field"
|
class="ui field"
|
||||||
>
|
>
|
||||||
<template v-if="fieldConfig.type === 'text'">
|
<template v-if="fieldConfig.type === 'text'">
|
||||||
<Spacer :size="64"/>
|
|
||||||
<Input
|
<Input
|
||||||
:id="fieldConfig.id"
|
:id="fieldConfig.id"
|
||||||
v-model="values[fieldConfig.id]"
|
v-model="values[fieldConfig.id]"
|
||||||
|
@ -261,8 +264,8 @@ const resetField = (fieldId: string) => {
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="fieldConfig.type === 'content'">
|
<template v-else-if="fieldConfig.type === 'content'">
|
||||||
<label :for="fieldConfig.id">{{ fieldConfig.label }}</label>
|
<Textarea
|
||||||
<content-form
|
:label="fieldConfig.label"
|
||||||
v-model="values[fieldConfig.id].text"
|
v-model="values[fieldConfig.id].text"
|
||||||
:field-id="fieldConfig.id"
|
:field-id="fieldConfig.id"
|
||||||
:rows="3"
|
:rows="3"
|
||||||
|
@ -270,7 +273,6 @@ const resetField = (fieldId: string) => {
|
||||||
</template>
|
</template>
|
||||||
<!-- TODO: Style Attachment Input -->
|
<!-- TODO: Style Attachment Input -->
|
||||||
<template v-else-if="fieldConfig.type === 'attachment'">
|
<template v-else-if="fieldConfig.type === 'attachment'">
|
||||||
<Spacer />
|
|
||||||
<attachment-input
|
<attachment-input
|
||||||
:id="fieldConfig.id"
|
:id="fieldConfig.id"
|
||||||
v-model="values[fieldConfig.id]"
|
v-model="values[fieldConfig.id]"
|
||||||
|
@ -283,7 +285,6 @@ const resetField = (fieldId: string) => {
|
||||||
</attachment-input>
|
</attachment-input>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="fieldConfig.type === 'tags'">
|
<template v-else-if="fieldConfig.type === 'tags'">
|
||||||
<Spacer/>
|
|
||||||
<Pills
|
<Pills
|
||||||
:id="fieldConfig.id"
|
:id="fieldConfig.id"
|
||||||
:label="fieldConfig.label"
|
:label="fieldConfig.label"
|
||||||
|
@ -292,7 +293,6 @@ const resetField = (fieldId: string) => {
|
||||||
required="fieldConfig.required"
|
required="fieldConfig.required"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
class="ui tiny basic left floated button"
|
|
||||||
icon="bi-x"
|
icon="bi-x"
|
||||||
form="noop"
|
form="noop"
|
||||||
@click.prevent="values[fieldConfig.id] = []"
|
@click.prevent="values[fieldConfig.id] = []"
|
||||||
|
@ -301,39 +301,36 @@ const resetField = (fieldId: string) => {
|
||||||
</Button>
|
</Button>
|
||||||
</Pills>
|
</Pills>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="fieldValuesChanged(fieldConfig.id)">
|
<Button low-height
|
||||||
<Button
|
|
||||||
tiny
|
|
||||||
alignSelf="end"
|
alignSelf="end"
|
||||||
icon="bi-arrow-counterclockwise"
|
icon="bi-arrow-counterclockwise"
|
||||||
form="noop"
|
form="noop"
|
||||||
|
:disabled="fieldValuesChanged(fieldConfig.id) ? undefined : true"
|
||||||
@click.prevent="resetField(fieldConfig.id)"
|
@click.prevent="resetField(fieldConfig.id)"
|
||||||
>
|
>
|
||||||
{{ t('components.library.EditForm.button.reset') }}
|
{{ t('components.library.EditForm.button.reset') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<Spacer/>
|
<Spacer/>
|
||||||
<Textarea
|
<Textarea
|
||||||
id="change-summary"
|
id="change-summary"
|
||||||
v-model="summary"
|
v-model="summary"
|
||||||
name="change-summary"
|
name="change-summary"
|
||||||
rows="3"
|
initialLines="3"
|
||||||
:label="t('components.library.EditForm.label.summary')"
|
:label="t('components.library.EditForm.label.summary')"
|
||||||
:placeholder="labels.summaryPlaceholder"
|
:placeholder="labels.summaryPlaceholder"
|
||||||
/>
|
>
|
||||||
<Button
|
<Button
|
||||||
v-if="objectType === 'track'"
|
v-if="objectType === 'track'"
|
||||||
:to="{name: 'library.tracks.detail', params: {id: object.id }}"
|
:to="{name: 'library.tracks.detail', params: {id: object.id }}"
|
||||||
>
|
>
|
||||||
{{ t('components.library.EditForm.button.cancel') }}
|
{{ t('components.library.EditForm.button.cancel') }}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Textarea>
|
||||||
<Button
|
<Button
|
||||||
:class="['ui', 'right', 'floated', 'success', 'button']"
|
:class="['ui', 'right', 'floated', 'success', 'button']"
|
||||||
:isLoading="isLoading"
|
:isLoading="isLoading"
|
||||||
primary
|
primary
|
||||||
type="submit"
|
|
||||||
:disabled="isLoading || !mutationPayload"
|
:disabled="isLoading || !mutationPayload"
|
||||||
>
|
>
|
||||||
<span v-if="canEdit">
|
<span v-if="canEdit">
|
||||||
|
@ -343,6 +340,6 @@ const resetField = (fieldId: string) => {
|
||||||
{{ t('components.library.EditForm.button.suggest') }}
|
{{ t('components.library.EditForm.button.suggest') }}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
</form>
|
||||||
</Layout>
|
</Layout>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
> .pill-content {
|
> .pill-content {
|
||||||
padding: 0.45em 0.75em 0.55em 0.75em;
|
padding: 0.45em 0.75em 0.55em 0.75em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
min-width: 28px;
|
||||||
|
border-radius: inherit;
|
||||||
|
&:focus-visible, &:focus {
|
||||||
|
outline: 2px solid var(--focus-ring-color);
|
||||||
|
outline-offset: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .pill-image {
|
> .pill-image {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Album, Artist, Content, Track, Actor } from '~/types'
|
import type { Album, Content, Track, Actor } from '~/types'
|
||||||
|
|
||||||
import { i18n } from '~/init/locale'
|
import { i18n } from '~/init/locale'
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ export interface EditableConfigField extends ConfigField {
|
||||||
id: EditObjectType
|
id: EditObjectType
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EditObject = (Partial<Artist> | Partial<Album> | Partial<Track>) & { attributed_to: Actor }
|
export type EditObject = (Partial<Album> | Partial<Track>) & { attributed_to: Actor }
|
||||||
export type EditObjectType = 'artist' | 'album' | 'track'
|
export type EditObjectType = 'album' | 'track'
|
||||||
type Configs = Record<EditObjectType, { fields: (EditableConfigField|ConfigField)[] }>
|
type Configs = Record<EditObjectType, { fields: (EditableConfigField|ConfigField)[] }>
|
||||||
|
|
||||||
const getContentValueRepr = (val: Content) => val.text
|
const getContentValueRepr = (val: Content) => val.text
|
||||||
|
@ -48,25 +48,15 @@ export default (): Configs => {
|
||||||
type: 'tags',
|
type: 'tags',
|
||||||
required: true,
|
required: true,
|
||||||
label: t('composables.moderation.useEditConfigs.tags.label'),
|
label: t('composables.moderation.useEditConfigs.tags.label'),
|
||||||
getValue: (obj) => { return obj.tags },
|
getValue: (obj) => ({
|
||||||
|
current: obj.tags || [],
|
||||||
|
others: [],
|
||||||
|
custom: [],
|
||||||
|
}),
|
||||||
getValueRepr: (tags: string[]) => tags.slice().sort().join('\n')
|
getValueRepr: (tags: string[]) => tags.slice().sort().join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
artist: {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
id: 'name',
|
|
||||||
type: 'text',
|
|
||||||
required: true,
|
|
||||||
label: t('composables.moderation.useEditConfigs.artist.name'),
|
|
||||||
getValue: (artist) => (artist as Artist).name
|
|
||||||
},
|
|
||||||
description,
|
|
||||||
cover,
|
|
||||||
tags
|
|
||||||
]
|
|
||||||
},
|
|
||||||
album: {
|
album: {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue