mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00
221 lines
8.6 KiB
Vue
221 lines
8.6 KiB
Vue
<template>
|
||
<section v-if="$user()">
|
||
<div v-if="afterSubmit" class="alert alert-success text-center">
|
||
<p>
|
||
<T>nouns.submit.thanks</T>
|
||
</p>
|
||
<p>
|
||
<button class="btn btn-success" @click="afterSubmit = false">
|
||
<Icon v="plus" />
|
||
<T>nouns.submit.another</T>
|
||
</button>
|
||
</p>
|
||
</div>
|
||
<form v-else @submit.prevent="submit">
|
||
<div class="row">
|
||
<div v-if="$config.nouns.plurals" class="col-12 col-md text-nowrap mt-md-4">
|
||
<label><strong>⋅ <T>nouns.singular</T></strong></label>
|
||
</div>
|
||
<div v-for="gender in genders" :key="gender" class="col-6 col-sm">
|
||
<label><strong><NounGenderLabel :gender="gender" /></strong></label>
|
||
<ListInput
|
||
v-model="form[gender]"
|
||
:maxlength="36"
|
||
:minitems="1"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div v-if="$config.nouns.plurals" class="row">
|
||
<div class="col-12 col-md text-nowrap">
|
||
<label><strong>⁖ <T>nouns.plural</T></strong></label>
|
||
</div>
|
||
<div v-for="gender in genders" :key="gender" class="col-6 col-sm">
|
||
<label class="d-md-none"><strong><NounGenderLabel :gender="gender" /></strong></label>
|
||
<ListInput
|
||
v-model="form[`${gender}Pl`]"
|
||
:maxlength="36"
|
||
:minitems="$config.nouns.pluralsRequired ? 1 : 0"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div v-if="$isGranted('sources')" class="form-group">
|
||
<label><strong><T>sources.referenced</T><T>quotation.colon</T></strong></label>
|
||
<ListInput v-model="form.sources" />
|
||
</div>
|
||
<div v-if="form.base" class="alert alert-info">
|
||
<Icon v="info-circle" />
|
||
<T>nouns.editing</T>
|
||
<button class="btn btn-sm float-end" @click="form.base = null">
|
||
<Icon v="times" />
|
||
</button>
|
||
</div>
|
||
|
||
<template v-if="$config.nouns.templates?.enabled">
|
||
<a v-if="!templateVisible" href="#" class="btn btn-outline-primary w-100 mb-3" @click.prevent="templateVisible = true">
|
||
<Icon v="copy" />
|
||
<T>nouns.template.header</T>
|
||
</a>
|
||
<div v-else class="card mb-3">
|
||
<a href="#" class="card-header" @click.prevent="templateVisible = false">
|
||
<Icon v="copy" />
|
||
<T>nouns.template.header</T>
|
||
</a>
|
||
<div class="card-body">
|
||
<div class="input-group mb-3 bg-white">
|
||
<span class="input-group-text">
|
||
<Icon v="scroll-old" />
|
||
</span>
|
||
<input
|
||
v-model="templateBase"
|
||
class="form-control form-control-sm border-primary"
|
||
autofocus
|
||
:placeholder="$t('nouns.template.root')"
|
||
>
|
||
<template v-if="$config.nouns.templates.filter">
|
||
<span class="input-group-text">
|
||
<Icon v="filter" />
|
||
</span>
|
||
<input
|
||
ref="templateFilter"
|
||
v-model="templateFilter"
|
||
class="form-control form-control-sm border-primary"
|
||
:placeholder="$t('crud.filterLong')"
|
||
>
|
||
<button
|
||
v-if="templateFilter"
|
||
class="btn btn-sm btn-outline-danger"
|
||
@click="templateFilter = ''; $tRefs.templateFilter?.focus()"
|
||
>
|
||
<Icon v="times" />
|
||
</button>
|
||
</template>
|
||
</div>
|
||
<NounTemplatesTable :template-base="templateBase" :filter="templateFilter">
|
||
<template #buttons="{ template }">
|
||
<li>
|
||
<button
|
||
type="button"
|
||
class="btn btn-concise btn-outline-primary btn-sm"
|
||
:disabled="!templateBase"
|
||
@click="applyTemplate(template)"
|
||
>
|
||
<Icon v="copy" />
|
||
<span class="btn-label"><T>nouns.template.apply</T></span>
|
||
</button>
|
||
</li>
|
||
</template>
|
||
</NounTemplatesTable>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<button class="btn btn-primary w-100" :disabled="submitting">
|
||
<template v-if="submitting">
|
||
<Icon v="circle-notch fa-spin" />
|
||
</template>
|
||
<template v-else>
|
||
<Icon v="plus" />
|
||
<T>nouns.submit.actionLong</T>
|
||
</template>
|
||
</button>
|
||
<p class="small text-muted mt-1">
|
||
<T>nouns.submit.moderation</T>
|
||
</p>
|
||
<ul v-if="Object.keys(abbreviations).length > 0" class="small text-muted">
|
||
<li v-for="(meaning, abbr) in abbreviations">
|
||
{{ abbr }} – {{ meaning }}
|
||
</li>
|
||
</ul>
|
||
</form>
|
||
</section>
|
||
<section v-else class="text-center">
|
||
<div class="alert alert-info">
|
||
<T>crud.loginRequired</T>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
import Vue from 'vue';
|
||
import { abbreviations } from '../src/data.ts';
|
||
import { genders } from '../src/classes.ts';
|
||
import type { Noun, MinimalNoun } from '../src/classes.ts';
|
||
import type { Config } from '../locale/config.ts';
|
||
|
||
interface Refs {
|
||
templateFilter: HTMLInputElement | undefined;
|
||
}
|
||
|
||
const emptyForm = (config: Config): MinimalNoun => {
|
||
return {
|
||
masc: [''],
|
||
fem: [''],
|
||
neutr: [''],
|
||
mascPl: config.nouns.pluralsRequired ? [''] : [],
|
||
femPl: config.nouns.pluralsRequired ? [''] : [],
|
||
neutrPl: config.nouns.pluralsRequired ? [''] : [],
|
||
sources: [],
|
||
base: null,
|
||
};
|
||
};
|
||
|
||
export default Vue.extend({
|
||
data() {
|
||
return {
|
||
form: emptyForm(this.$config),
|
||
submitting: false,
|
||
afterSubmit: false,
|
||
templateBase: '',
|
||
templateFilter: '',
|
||
templateVisible: false,
|
||
abbreviations,
|
||
genders,
|
||
};
|
||
},
|
||
computed: {
|
||
$tRefs(): Refs {
|
||
return this.$refs as unknown as Refs;
|
||
},
|
||
},
|
||
methods: {
|
||
async applyTemplate(template: MinimalNoun): Promise<void> {
|
||
if (JSON.stringify(this.form) !== JSON.stringify(emptyForm(this.$config))) {
|
||
await this.$confirm(this.$t('nouns.template.overwrite'));
|
||
}
|
||
this.form = template;
|
||
this.templateVisible = false;
|
||
this.$nextTick(() => {
|
||
this.$el.scrollIntoView();
|
||
});
|
||
},
|
||
async submit() {
|
||
this.submitting = true;
|
||
try {
|
||
await this.$post('/nouns/submit', this.form);
|
||
|
||
this.afterSubmit = true;
|
||
this.form = emptyForm(this.$config);
|
||
this.templateVisible = false;
|
||
this.templateBase = '';
|
||
} finally {
|
||
this.submitting = false;
|
||
}
|
||
},
|
||
edit(word: Noun): void {
|
||
this.form = {
|
||
masc: word.masc,
|
||
fem: word.fem,
|
||
neutr: word.neutr,
|
||
mascPl: word.mascPl,
|
||
femPl: word.femPl,
|
||
neutrPl: word.neutrPl,
|
||
sources: word.sources,
|
||
base: word.id,
|
||
};
|
||
this.afterSubmit = false;
|
||
this.$el.scrollIntoView();
|
||
},
|
||
},
|
||
});
|
||
</script>
|