mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-23 04:34:15 -04:00
(nouns) use same styling on <NounsTemplatesTable>, extract <NounsTable> to not repeat styling
This commit is contained in:
parent
7870951f49
commit
9d4900fde8
@ -1,12 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ComponentExposed } from 'vue-component-type-helpers';
|
|
||||||
|
|
||||||
import type Table from '~/components/Table.vue';
|
|
||||||
import type NounsSubmitForm from '~/components/nouns/NounsSubmitForm.vue';
|
import type NounsSubmitForm from '~/components/nouns/NounsSubmitForm.vue';
|
||||||
import { Noun } from '~/src/classes.ts';
|
import { Noun } from '~/src/classes.ts';
|
||||||
import type { NounRaw } from '~/src/classes.ts';
|
import type { NounRaw } from '~/src/classes.ts';
|
||||||
import { buildDict } from '~/src/helpers.ts';
|
import { buildDict } from '~/src/helpers.ts';
|
||||||
import { availableGenders } from '~/src/nouns.ts';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
load?: boolean;
|
load?: boolean;
|
||||||
@ -16,7 +12,7 @@ const { $translator: translator } = useNuxtApp();
|
|||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const filter = useFilterWithCategory();
|
const filter = useFilterWithCategory();
|
||||||
|
|
||||||
const dictionarytable = useTemplateRef<ComponentExposed<typeof Table>>('dictionarytable');
|
const dictionarytable = useTemplateRef('dictionarytable');
|
||||||
watch(filter, () => {
|
watch(filter, () => {
|
||||||
if (dictionarytable.value) {
|
if (dictionarytable.value) {
|
||||||
dictionarytable.value.reset();
|
dictionarytable.value.reset();
|
||||||
@ -114,90 +110,71 @@ defineExpose({ loadNouns });
|
|||||||
@submit-clicked="form?.focus()"
|
@submit-clicked="form?.focus()"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Table
|
<NounsTable
|
||||||
ref="dictionarytable"
|
ref="dictionarytable"
|
||||||
:class="[config.nouns.nonbinary ? 'nouns-table-nonbinary' : '']"
|
:class="[config.nouns.nonbinary ? 'nouns-table-nonbinary' : '']"
|
||||||
:data="visibleNouns"
|
:nouns="visibleNouns"
|
||||||
:marked="(el) => !el.approved"
|
:marked="(el) => !el.approved"
|
||||||
fixed
|
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #buttons="{ noun }">
|
||||||
<div v-for="gender in availableGenders(config)" :key="gender" class="d-none d-md-block bold">
|
<ul class="d-flex flex-wrap flex-md-column list-unstyled list-btn-concise mb-0">
|
||||||
<NounsGenderLabel :gender="gender" />
|
<template v-if="$isGranted('nouns')">
|
||||||
</div>
|
<li v-if="noun.author" class="small">
|
||||||
</template>
|
<nuxt-link
|
||||||
|
:to="`/@${noun.author}`"
|
||||||
<template #row="{ el: noun }">
|
class="btn btn-concise btn-outline-dark btn-sm m-1"
|
||||||
<NounsDictionaryEntry
|
>
|
||||||
:noun="noun"
|
<Icon v="user" />
|
||||||
:base="noun.base && nouns[noun.base] ? nouns[noun.base] : undefined"
|
<span class="btn-label">
|
||||||
>
|
<T>crud.author</T><T>quotation.colon</T>
|
||||||
<template #buttons>
|
@{{ noun.author }}
|
||||||
<ul class="d-flex flex-wrap flex-md-column list-unstyled list-btn-concise mb-0">
|
</span>
|
||||||
<template v-if="$isGranted('nouns')">
|
</nuxt-link>
|
||||||
<li v-if="noun.author" class="small">
|
</li>
|
||||||
<nuxt-link
|
<li v-if="!noun.approved">
|
||||||
:to="`/@${noun.author}`"
|
<button class="btn btn-concise btn-success btn-sm m-1" @click="approve(noun)">
|
||||||
class="btn btn-concise btn-outline-dark btn-sm m-1"
|
<Icon v="check" />
|
||||||
>
|
<span class="btn-label"><T>crud.approve</T></span>
|
||||||
<Icon v="user" />
|
</button>
|
||||||
<span class="btn-label">
|
</li>
|
||||||
<T>crud.author</T><T>quotation.colon</T>
|
<li v-else @click="hide(noun)">
|
||||||
@{{ noun.author }}
|
<button class="btn btn-concise btn-outline-secondary btn-sm m-1">
|
||||||
</span>
|
<Icon v="times" />
|
||||||
</nuxt-link>
|
<span class="btn-label"><T>crud.hide</T></span>
|
||||||
</li>
|
</button>
|
||||||
<li v-if="!noun.approved">
|
</li>
|
||||||
<button class="btn btn-concise btn-success btn-sm m-1" @click="approve(noun)">
|
<li>
|
||||||
<Icon v="check" />
|
<button class="btn btn-concise btn-outline-danger btn-sm m-1" @click="remove(noun)">
|
||||||
<span class="btn-label"><T>crud.approve</T></span>
|
<Icon v="trash" />
|
||||||
</button>
|
<span class="btn-label"><T>crud.remove</T></span>
|
||||||
</li>
|
</button>
|
||||||
<li v-else @click="hide(noun)">
|
</li>
|
||||||
<button class="btn btn-concise btn-outline-secondary btn-sm m-1">
|
|
||||||
<Icon v="times" />
|
|
||||||
<span class="btn-label"><T>crud.hide</T></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button class="btn btn-concise btn-outline-danger btn-sm m-1" @click="remove(noun)">
|
|
||||||
<Icon v="trash" />
|
|
||||||
<span class="btn-label"><T>crud.remove</T></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<li>
|
|
||||||
<button class="btn btn-concise btn-outline-primary btn-sm m-1" @click="edit(noun)">
|
|
||||||
<Icon v="pen" />
|
|
||||||
<span class="btn-label">
|
|
||||||
<T v-if="$isGranted('nouns')">crud.edit</T>
|
|
||||||
<T v-else>nouns.edit</T>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
:href="`/api/nouns/${noun.id}.png`"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
class="btn btn-concise btn-outline-primary btn-sm m-1"
|
|
||||||
>
|
|
||||||
<Icon v="image" />
|
|
||||||
<span class="btn-label">
|
|
||||||
<T>nouns.image</T>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
</template>
|
||||||
</NounsDictionaryEntry>
|
<li>
|
||||||
|
<button class="btn btn-concise btn-outline-primary btn-sm m-1" @click="edit(noun)">
|
||||||
|
<Icon v="pen" />
|
||||||
|
<span class="btn-label">
|
||||||
|
<T v-if="$isGranted('nouns')">crud.edit</T>
|
||||||
|
<T v-else>nouns.edit</T>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
:href="`/api/nouns/${noun.id}.png`"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="btn btn-concise btn-outline-primary btn-sm m-1"
|
||||||
|
>
|
||||||
|
<Icon v="image" />
|
||||||
|
<span class="btn-label">
|
||||||
|
<T>nouns.image</T>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
</NounsTable>
|
||||||
<template #empty>
|
|
||||||
<Icon v="search" />
|
|
||||||
<T>nouns.empty</T>
|
|
||||||
</template>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<AdPlaceholder :phkey="['content-1', 'content-mobile-1']" />
|
<AdPlaceholder :phkey="['content-1', 'content-mobile-1']" />
|
||||||
|
|
||||||
@ -208,42 +185,3 @@ defineExpose({ loadNouns });
|
|||||||
</template>
|
</template>
|
||||||
</Loading>
|
</Loading>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "assets/variables";
|
|
||||||
|
|
||||||
:deep(.row-header) {
|
|
||||||
grid-template-columns: 1fr 1fr 1fr 3em;
|
|
||||||
|
|
||||||
.nouns-table-nonbinary & {
|
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr 3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.row-content) {
|
|
||||||
grid:
|
|
||||||
"mascLabel masc mascPl"
|
|
||||||
"femLabel fem femPl"
|
|
||||||
"neutrLabel neutr neutrPl"
|
|
||||||
"nbLabel nb nbPl"
|
|
||||||
"sources sources sources"
|
|
||||||
"buttons buttons buttons"
|
|
||||||
/ auto 1fr 1fr;
|
|
||||||
|
|
||||||
@include media-breakpoint-up('md', $grid-breakpoints) {
|
|
||||||
grid:
|
|
||||||
"masc fem neutr buttons"
|
|
||||||
"mascPl femPl neutrPl buttons"
|
|
||||||
"sources sources sources buttons"
|
|
||||||
/ 1fr 1fr 1fr 3em;
|
|
||||||
|
|
||||||
.nouns-table-nonbinary & {
|
|
||||||
grid:
|
|
||||||
"masc fem neutr nb buttons"
|
|
||||||
"mascPl femPl neutrPl nbPl buttons"
|
|
||||||
"sources sources sources sources buttons"
|
|
||||||
/ 1fr 1fr 1fr 1fr 3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
84
components/nouns/NounsTable.vue
Normal file
84
components/nouns/NounsTable.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<script setup lang="ts" generic="T extends Partial<Noun> & MinimalNoun & { id: string }">
|
||||||
|
import type { MinimalNoun, Noun } from '~/src/classes.ts';
|
||||||
|
import { availableGenders } from '~/src/nouns.ts';
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
nouns: T[];
|
||||||
|
marked?: (element: T) => boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const config = useConfig();
|
||||||
|
|
||||||
|
const table = useTemplateRef('table');
|
||||||
|
defineExpose({
|
||||||
|
reset() {
|
||||||
|
table.value?.reset();
|
||||||
|
},
|
||||||
|
focus() {
|
||||||
|
table.value?.focus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Table ref="table" :data="nouns" :marked fixed>
|
||||||
|
<template #header>
|
||||||
|
<div v-for="gender in availableGenders(config)" :key="gender" class="d-none d-md-block bold">
|
||||||
|
<NounsGenderLabel :gender="gender" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #row="{ el: noun }">
|
||||||
|
<NounsTableEntry :noun>
|
||||||
|
<template #buttons>
|
||||||
|
<ul class="list-unstyled list-btn-concise">
|
||||||
|
<slot name="buttons" :noun="noun"></slot>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</NounsTableEntry>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #empty>
|
||||||
|
<Icon v="search" />
|
||||||
|
<T>nouns.empty</T>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "assets/variables";
|
||||||
|
|
||||||
|
:deep(.row-header) {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 3em;
|
||||||
|
|
||||||
|
.nouns-table-nonbinary & {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.row-content) {
|
||||||
|
grid:
|
||||||
|
"mascLabel masc mascPl"
|
||||||
|
"femLabel fem femPl"
|
||||||
|
"neutrLabel neutr neutrPl"
|
||||||
|
"nbLabel nb nbPl"
|
||||||
|
"sources sources sources"
|
||||||
|
"buttons buttons buttons"
|
||||||
|
/ auto 1fr 1fr;
|
||||||
|
|
||||||
|
@include media-breakpoint-up('md', $grid-breakpoints) {
|
||||||
|
grid:
|
||||||
|
"masc fem neutr buttons"
|
||||||
|
"mascPl femPl neutrPl buttons"
|
||||||
|
"sources sources sources buttons"
|
||||||
|
/ 1fr 1fr 1fr 3em;
|
||||||
|
|
||||||
|
.nouns-table-nonbinary & {
|
||||||
|
grid:
|
||||||
|
"masc fem neutr nb buttons"
|
||||||
|
"mascPl femPl neutrPl nbPl buttons"
|
||||||
|
"sources sources sources sources buttons"
|
||||||
|
/ 1fr 1fr 1fr 1fr 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,9 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Noun } from '~/src/classes.ts';
|
import type { MinimalNoun, Noun } from '~/src/classes.ts';
|
||||||
import { genders } from '~/src/nouns.ts';
|
import { genders } from '~/src/nouns.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
noun: Noun;
|
noun: Partial<Noun> & MinimalNoun;
|
||||||
base?: Noun;
|
base?: Noun;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ const numerus = computed(() => {
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="noun.sourcesData.length" style="grid-area: sources">
|
<div v-if="noun.sourcesData?.length" style="grid-area: sources">
|
||||||
<p><strong><T>sources.referenced</T><T>quotation.colon</T></strong></p>
|
<p><strong><T>sources.referenced</T><T>quotation.colon</T></strong></p>
|
||||||
<ul class="list-unstyled mb-0">
|
<ul class="list-unstyled mb-0">
|
||||||
<li v-for="source in noun.sourcesData" :key="source.id">
|
<li v-for="source in noun.sourcesData" :key="source.id">
|
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { MinimalNoun } from '~/src/classes.ts';
|
import type { MinimalNoun } from '~/src/classes.ts';
|
||||||
import { nounTemplates } from '~/src/data.ts';
|
import { nounTemplates } from '~/src/data.ts';
|
||||||
import { availableGenders, gendersWithNumerus } from '~/src/nouns.ts';
|
import { gendersWithNumerus } from '~/src/nouns.ts';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
templateBase?: string;
|
templateBase?: string;
|
||||||
@ -11,15 +11,6 @@ const props = withDefaults(defineProps<{
|
|||||||
filter: '',
|
filter: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const config = useConfig();
|
|
||||||
|
|
||||||
const numerus = computed(() => {
|
|
||||||
if (config.nouns.plurals) {
|
|
||||||
return [false, true];
|
|
||||||
}
|
|
||||||
return [false];
|
|
||||||
});
|
|
||||||
|
|
||||||
const templates = computed((): (MinimalNoun & { id: string })[] => {
|
const templates = computed((): (MinimalNoun & { id: string })[] => {
|
||||||
return nounTemplates.filter((template) => {
|
return nounTemplates.filter((template) => {
|
||||||
for (const field of gendersWithNumerus) {
|
for (const field of gendersWithNumerus) {
|
||||||
@ -39,33 +30,11 @@ const templates = computed((): (MinimalNoun & { id: string })[] => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Table :data="templates" fixed>
|
<NounsTable :nouns="templates">
|
||||||
<template #header>
|
<template #buttons="{ noun }">
|
||||||
<th v-for="gender in availableGenders(config)" :key="gender" class="text-nowrap">
|
<ul class="list-unstyled list-btn-concise">
|
||||||
<NounsGenderLabel :gender="gender" />
|
<slot name="buttons" :template="noun"></slot>
|
||||||
</th>
|
</ul>
|
||||||
<th></th>
|
|
||||||
</template>
|
</template>
|
||||||
<template #row="{ el: template }">
|
</NounsTable>
|
||||||
<td v-for="gender in availableGenders(config)" :key="gender">
|
|
||||||
<NounsItem
|
|
||||||
v-for="plural in numerus"
|
|
||||||
:key="plural ? 'plural' : 'singular'"
|
|
||||||
:noun="template"
|
|
||||||
:gender
|
|
||||||
:plural
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul class="list-unstyled list-btn-concise">
|
|
||||||
<slot name="buttons" :template="template"></slot>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #empty>
|
|
||||||
<Icon v="search" />
|
|
||||||
<T>nouns.empty</T>
|
|
||||||
</template>
|
|
||||||
</Table>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -13,6 +13,8 @@ definePageMeta({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NounsNav = useLocaleComponent('nouns', 'NounsNav');
|
||||||
|
|
||||||
const { $translator: translator } = useNuxtApp();
|
const { $translator: translator } = useNuxtApp();
|
||||||
useSimpleHead({
|
useSimpleHead({
|
||||||
title: translator.translate('nouns.headerLonger'),
|
title: translator.translate('nouns.headerLonger'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user