Skip to content

Commit b35ea06

Browse files
committed
Config form tabs
1 parent 7b468f3 commit b35ea06

File tree

2 files changed

+114
-68
lines changed

2 files changed

+114
-68
lines changed

src/components/TabsBar.vue

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script setup lang="ts">
2+
import { defineProps } from "vue";
3+
4+
defineProps<{
5+
tabs: { key: string; label: string }[];
6+
}>();
7+
8+
defineModel<string>();
9+
</script>
10+
11+
<template>
12+
<nav>
13+
<ul class="my-4 flex gap-4">
14+
<li
15+
v-for="tab in tabs"
16+
:key="tab.key"
17+
class="py-2 text-lg font-medium hover:underline underline-offset-4 decoration-2 hover:text-sborange-600 cursor-pointer"
18+
:class="{ underline: tab.key == modelValue }"
19+
@click="$emit('update:modelValue', tab.key)"
20+
>
21+
{{ tab.label }}
22+
</li>
23+
</ul>
24+
</nav>
25+
</template>

src/corpus/config/CorpusConfiguration.vue

Lines changed: 89 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import type { FormKitOptionsList } from "@formkit/inputs";
33
import type { AxiosError } from "axios";
4-
import { computed } from "vue";
4+
import { computed, ref } from "vue";
55
import { useI18n } from "vue-i18n";
66
import { useRouter } from "vue-router";
77
import { FormKit } from "@formkit/vue";
@@ -35,13 +35,9 @@ import {
3535
type AnalysisId,
3636
} from "@/api/analysis";
3737
import useLocale from "@/i18n/locale.composable";
38+
import TabsBar from "@/components/TabsBar.vue";
3839
39-
const router = useRouter();
40-
const corpusId = useCorpusIdParam();
41-
const { config, saveConfigOptions, extensions } = useCorpus(corpusId);
42-
const { alert, alertError } = useMessenger();
43-
const { t } = useI18n();
44-
const { th, thCompare } = useLocale();
40+
type TabKey = "metadata" | "settings" | "analyses";
4541
4642
type Form = {
4743
name: ByLang;
@@ -54,6 +50,15 @@ type Form = {
5450
analyses: Record<AnalysisId, boolean>;
5551
};
5652
53+
const router = useRouter();
54+
const corpusId = useCorpusIdParam();
55+
const { config, saveConfigOptions, extensions } = useCorpus(corpusId);
56+
const { alert, alertError } = useMessenger();
57+
const { t } = useI18n();
58+
const { th, thCompare } = useLocale();
59+
60+
const tabSelected = ref<TabKey>("metadata");
61+
5762
/** List of metadata for relevant analyses */
5863
const analyses = computedAsync(async () => {
5964
const analyses = await loadAnalysisMetdata();
@@ -152,6 +157,15 @@ async function submit(fields: Form) {
152157

153158
<template>
154159
<PendingContent :on="`corpus/${corpusId}/config`">
160+
<TabsBar
161+
:tabs="[
162+
{ key: 'metadata', label: $t('metadata') },
163+
{ key: 'settings', label: $t('settings') },
164+
{ key: 'analyses', label: $t('config.analyses') },
165+
]"
166+
v-model="tabSelected"
167+
/>
168+
155169
<!-- Using the key attribute to re-render whole form after fetching config -->
156170
<FormKitWrapper v-if="configOptions" :key="config">
157171
<FormKit
@@ -164,7 +178,10 @@ async function submit(fields: Form) {
164178
}"
165179
@submit="submit"
166180
>
167-
<LayoutSection :title="$t('metadata')">
181+
<LayoutSection
182+
:title="$t('metadata')"
183+
v-show="tabSelected == 'metadata'"
184+
>
168185
<HelpBox>
169186
<p>{{ $t("config.metadata.help") }}</p>
170187
</HelpBox>
@@ -179,7 +196,7 @@ async function submit(fields: Form) {
179196
<FormKit
180197
:name="lang3"
181198
:label="$t('name')"
182-
:value="configOptions?.name?.[lang3]"
199+
:value="configOptions.name?.[lang3]"
183200
:help="$t('metadata.name.help')"
184201
type="text"
185202
input-class="w-72"
@@ -190,7 +207,7 @@ async function submit(fields: Form) {
190207
<FormKit
191208
:name="lang3"
192209
:label="$t('description')"
193-
:value="configOptions?.description?.[lang3]"
210+
:value="configOptions.description?.[lang3]"
194211
:help="$t('metadata.description.help')"
195212
type="textarea"
196213
input-class="w-full h-20"
@@ -219,7 +236,10 @@ async function submit(fields: Form) {
219236
</FormKit>
220237
</LayoutSection>
221238

222-
<LayoutSection :title="$t('configuration')">
239+
<LayoutSection
240+
:title="$t('settings')"
241+
v-show="tabSelected == 'settings'"
242+
>
223243
<HelpBox>
224244
<p>{{ $t("config.configuration.help") }}</p>
225245
</HelpBox>
@@ -246,7 +266,7 @@ async function submit(fields: Form) {
246266
name="textAnnotation"
247267
:label="$t('config.text_annotation')"
248268
type="text"
249-
:value="configOptions?.textAnnotation"
269+
:value="configOptions.textAnnotation"
250270
validation="required:trim|matches:/^[^<>\s]*$/"
251271
input-class="w-40 font-mono"
252272
:help="$t('config.text_annotation.help')"
@@ -259,7 +279,7 @@ async function submit(fields: Form) {
259279
v-if="!['mp3', 'ogg', 'wav'].includes((value as Form).format)"
260280
name="sentenceSegmenter"
261281
:label="$t('segmenter_sentence')"
262-
:value="configOptions?.sentenceSegmenter || ''"
282+
:value="configOptions.sentenceSegmenter || ''"
263283
type="radio"
264284
:options="segmenterOptions"
265285
:help="$t('segmenter_sentence_help')"
@@ -269,7 +289,7 @@ async function submit(fields: Form) {
269289
name="datetimeFrom"
270290
type="date"
271291
:label="`${$t('timespan')}: ${$t('timespan_from')}`"
272-
:value="configOptions?.datetime?.from"
292+
:value="configOptions.datetime?.from"
273293
:max="(value as Form).datetimeTo"
274294
validation="onlyif:datetimeTo"
275295
:validation-messages="{
@@ -280,69 +300,70 @@ async function submit(fields: Form) {
280300
name="datetimeTo"
281301
type="date"
282302
:label="`${$t('timespan')}: ${$t('timespan_to')}`"
283-
:value="configOptions?.datetime?.to"
303+
:value="configOptions.datetime?.to"
284304
:min="(value as Form).datetimeFrom"
285305
validation="onlyif:datetimeFrom"
286306
:validation-messages="{
287307
onlyif: $t('config.datetime.validate_both'),
288308
}"
289309
:help="$t('timespan_help')"
290310
/>
311+
</LayoutSection>
291312

292-
<LayoutSection :title="$t('config.analyses')">
293-
<HelpBox>
294-
<i18n-t keypath="config.analyses.info" scope="global">
295-
<template #custom_config>
296-
<router-link
297-
:to="`/library/corpus/${corpusId}/config/custom`"
298-
>
299-
{{ $t("config.custom") }}
300-
</router-link>
301-
</template>
302-
</i18n-t>
303-
</HelpBox>
313+
<LayoutSection
314+
:title="$t('config.analyses')"
315+
v-show="tabSelected == 'analyses'"
316+
>
317+
<HelpBox>
318+
<i18n-t keypath="config.analyses.info" scope="global">
319+
<template #custom_config>
320+
<router-link :to="`/library/corpus/${corpusId}/config/custom`">
321+
{{ $t("config.custom") }}
322+
</router-link>
323+
</template>
324+
</i18n-t>
325+
</HelpBox>
304326

305-
<FormKit type="group" name="analyses">
306-
<table class="my-2 striped">
307-
<thead>
308-
<tr>
309-
<th>{{ $t("description") }}</th>
310-
<th>{{ $t("identifier") }}</th>
311-
<th>{{ $t("config.analyses.task") }}</th>
312-
</tr>
313-
</thead>
314-
<tbody v-for="(group, unit) in analyses" :key="unit">
315-
<tr>
316-
<th colspan="5" class="text-lg pt-4!">
317-
{{ $t("config.analyses.unit") }}:
318-
{{ $t(`config.analyses.unit.${unit}`) }}
319-
</th>
320-
</tr>
321-
<tr v-for="analysis in group" :key="analysis.id">
322-
<td>
323-
<FormKit
324-
:name="analysis.id"
325-
:label="th(analysis.name)"
326-
:value="configOptions?.analyses[analysis.id]"
327-
type="checkbox"
328-
:help="th(analysis.short_description)"
329-
/>
330-
</td>
331-
<td>
332-
<a
333-
:href="$t('config.analyses.url', [analysis.id])"
334-
target="_blank"
335-
class="whitespace-nowrap"
336-
>
337-
{{ analysis.id }}
338-
</a>
339-
</td>
340-
<td>{{ th(analysis.task) }}</td>
341-
</tr>
342-
</tbody>
343-
</table>
344-
</FormKit>
345-
</LayoutSection>
327+
<FormKit type="group" name="analyses">
328+
<table class="my-2 striped">
329+
<thead>
330+
<tr>
331+
<th>{{ $t("description") }}</th>
332+
<th>{{ $t("identifier") }}</th>
333+
<th>{{ $t("config.analyses.task") }}</th>
334+
</tr>
335+
</thead>
336+
<tbody v-for="(group, unit) in analyses" :key="unit">
337+
<tr>
338+
<th colspan="5" class="text-lg pt-4!">
339+
{{ $t("config.analyses.unit") }}:
340+
{{ $t(`config.analyses.unit.${unit}`) }}
341+
</th>
342+
</tr>
343+
<tr v-for="analysis in group" :key="analysis.id">
344+
<td>
345+
<FormKit
346+
:name="analysis.id"
347+
:label="th(analysis.name)"
348+
:value="configOptions.analyses[analysis.id]"
349+
type="checkbox"
350+
:help="th(analysis.short_description)"
351+
/>
352+
</td>
353+
<td>
354+
<a
355+
:href="$t('config.analyses.url', [analysis.id])"
356+
target="_blank"
357+
class="whitespace-nowrap"
358+
>
359+
{{ analysis.id }}
360+
</a>
361+
</td>
362+
<td>{{ th(analysis.task) }}</td>
363+
</tr>
364+
</tbody>
365+
</table>
366+
</FormKit>
346367
</LayoutSection>
347368
</FormKit>
348369
</FormKitWrapper>

0 commit comments

Comments
 (0)