Skip to content

Commit 76a1e6f

Browse files
committed
feat: tip inconsistency detection
1 parent e6a76be commit 76a1e6f

File tree

1 file changed

+80
-6
lines changed

1 file changed

+80
-6
lines changed

app/pages/translate/tips/index.vue

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,92 @@
77
/>
88

99
<UPageBody>
10-
<TipForm
11-
v-for="(tip, i) in translationStore.originals.tips"
12-
:key="i"
13-
:index="i"
14-
:tip="tip"
15-
/>
10+
<template v-if="inconsistentHeadings.length">
11+
<UAlert
12+
v-for="h in inconsistentHeadings"
13+
:key="h.heading"
14+
variant="soft"
15+
color="warning"
16+
:title="`Inconsistentie in de titel: ${h.heading}`"
17+
description="Kies de juiste vertaling voor deze titel:"
18+
:actions="
19+
h.translations.map((t) => ({
20+
label: t,
21+
onClick: () => {
22+
fixInconsistentHeading(t, h.tips);
23+
},
24+
}))
25+
"
26+
/>
27+
</template>
28+
<template v-if="loading">
29+
<div v-for="i in 12" :key="i" class="grid gap-2">
30+
<USkeleton class="h-4 w-3xs" />
31+
<USkeleton class="h-4 w-20" />
32+
<USkeleton class="h-4 w-full" />
33+
</div>
34+
</template>
35+
<template v-else>
36+
<TipForm
37+
v-for="(tip, i) in translationStore.originals.tips"
38+
:key="i"
39+
:index="i"
40+
:tip="tip"
41+
/>
42+
</template>
1643
</UPageBody>
1744
</UPage>
1845
</template>
1946
<script setup lang="ts">
2047
const translationStore = useTranslationStore();
2148
49+
const inconsistentHeadings = computed(() => {
50+
if (!translationStore.originals.tips?.length) return [];
51+
const headings: Record<string, { index: number; translation: string }[]> = {};
52+
53+
translationStore.originals.tips.forEach((tip, index) => {
54+
if (headings[tip.heading]) {
55+
headings[tip.heading]!.push({
56+
index,
57+
translation: translationStore.translations.tips?.[index]?.heading ?? "",
58+
});
59+
} else {
60+
headings[tip.heading] = [
61+
{
62+
index,
63+
translation:
64+
translationStore.translations.tips?.[index]?.heading ?? "",
65+
},
66+
];
67+
}
68+
});
69+
return Object.entries(headings)
70+
.filter(
71+
([, tips]) =>
72+
tips.length > 1 &&
73+
tips.some((t) => t.translation !== tips[0]?.translation),
74+
)
75+
.map(([heading, tips]) => ({
76+
heading,
77+
tips: tips,
78+
translations: [...new Set(tips.map((t) => t.translation))],
79+
}));
80+
});
81+
82+
const loading = ref(false);
83+
84+
const fixInconsistentHeading = async (
85+
heading: string,
86+
tips: { index: number }[],
87+
) => {
88+
loading.value = true;
89+
tips.forEach((t) => {
90+
translationStore.translations.tips![t.index]!.heading = heading;
91+
});
92+
await new Promise((resolve) => setTimeout(resolve, 100));
93+
loading.value = false;
94+
};
95+
2296
const title = "Tips";
2397
const description = "Vertaal op deze pagina de tips.";
2498

0 commit comments

Comments
 (0)