From 8472ff9ea9e3d03f7dd1a63b0f77e99da8b8e6f6 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Thu, 19 Feb 2026 14:52:15 +0300 Subject: [PATCH 01/99] feat: add settings section and languages index component --- histoire.config.ts | 4 ++++ .../settings/languages/languages-index.story.vue | 12 ++++++++++++ src/frontend/settings/languages/languages-index.vue | 4 ++++ 3 files changed, 20 insertions(+) create mode 100644 src/frontend/settings/languages/languages-index.story.vue create mode 100644 src/frontend/settings/languages/languages-index.vue diff --git a/histoire.config.ts b/histoire.config.ts index 481140fd..e8834b66 100644 --- a/histoire.config.ts +++ b/histoire.config.ts @@ -43,6 +43,10 @@ export default defineConfig({ id: 'team', title: 'Team', }, + { + id: 'settings', + title: 'Settings', + }, { id: 'shared', title: 'Shared', diff --git a/src/frontend/settings/languages/languages-index.story.vue b/src/frontend/settings/languages/languages-index.story.vue new file mode 100644 index 00000000..4940d55e --- /dev/null +++ b/src/frontend/settings/languages/languages-index.story.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue new file mode 100644 index 00000000..dd7eba0f --- /dev/null +++ b/src/frontend/settings/languages/languages-index.vue @@ -0,0 +1,4 @@ + + \ No newline at end of file From 24e888d51d6d041f3817c39ccaa4f659c9c4e7ac Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Fri, 20 Feb 2026 08:52:03 +0300 Subject: [PATCH 02/99] feat: add source language component for language settings --- .../languages/components/source-lang.vue | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/frontend/settings/languages/components/source-lang.vue diff --git a/src/frontend/settings/languages/components/source-lang.vue b/src/frontend/settings/languages/components/source-lang.vue new file mode 100644 index 00000000..6c9db8b6 --- /dev/null +++ b/src/frontend/settings/languages/components/source-lang.vue @@ -0,0 +1,50 @@ + + + From ea16b36c0d733effe3b93c2937cfcc76aea30961 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Fri, 20 Feb 2026 11:25:29 +0300 Subject: [PATCH 03/99] feat: implement language management interface with actions and table components --- .../settings/languages/components/actions.vue | 13 + .../languages/components/lang-table.story.vue | 295 ++++++++++++++++++ .../languages/components/lang-table.vue | 136 ++++++++ .../languages/components/member-row.vue | 12 + .../components/source-lang.story.vue | 27 ++ .../languages/components/source-lang.vue | 17 +- .../settings/languages/languages-index.vue | 51 ++- src/frontend/shared/icon.vue | 14 + src/frontend/shared/pagination.vue | 2 +- 9 files changed, 551 insertions(+), 16 deletions(-) create mode 100644 src/frontend/settings/languages/components/actions.vue create mode 100644 src/frontend/settings/languages/components/lang-table.story.vue create mode 100644 src/frontend/settings/languages/components/lang-table.vue create mode 100644 src/frontend/settings/languages/components/member-row.vue create mode 100644 src/frontend/settings/languages/components/source-lang.story.vue diff --git a/src/frontend/settings/languages/components/actions.vue b/src/frontend/settings/languages/components/actions.vue new file mode 100644 index 00000000..9b7e8cb7 --- /dev/null +++ b/src/frontend/settings/languages/components/actions.vue @@ -0,0 +1,13 @@ + + diff --git a/src/frontend/settings/languages/components/lang-table.story.vue b/src/frontend/settings/languages/components/lang-table.story.vue new file mode 100644 index 00000000..fec7e045 --- /dev/null +++ b/src/frontend/settings/languages/components/lang-table.story.vue @@ -0,0 +1,295 @@ + + + diff --git a/src/frontend/settings/languages/components/lang-table.vue b/src/frontend/settings/languages/components/lang-table.vue new file mode 100644 index 00000000..6c7cbce4 --- /dev/null +++ b/src/frontend/settings/languages/components/lang-table.vue @@ -0,0 +1,136 @@ + + + diff --git a/src/frontend/settings/languages/components/member-row.vue b/src/frontend/settings/languages/components/member-row.vue new file mode 100644 index 00000000..f59d9029 --- /dev/null +++ b/src/frontend/settings/languages/components/member-row.vue @@ -0,0 +1,12 @@ + + diff --git a/src/frontend/settings/languages/components/source-lang.story.vue b/src/frontend/settings/languages/components/source-lang.story.vue new file mode 100644 index 00000000..7dc017fe --- /dev/null +++ b/src/frontend/settings/languages/components/source-lang.story.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/frontend/settings/languages/components/source-lang.vue b/src/frontend/settings/languages/components/source-lang.vue index 6c9db8b6..0d2ad0dd 100644 --- a/src/frontend/settings/languages/components/source-lang.vue +++ b/src/frontend/settings/languages/components/source-lang.vue @@ -1,5 +1,5 @@ + + diff --git a/src/frontend/shared/icon.vue b/src/frontend/shared/icon.vue index 91997306..3340e042 100644 --- a/src/frontend/shared/icon.vue +++ b/src/frontend/shared/icon.vue @@ -3180,6 +3180,20 @@ stroke-linejoin="round" /> + + + + Date: Fri, 20 Feb 2026 13:13:27 +0300 Subject: [PATCH 04/99] feat: add RingBlock component and story for dashboard progress visualization --- src/frontend/dashboard/ring-block.story.vue | 51 ++++++++ src/frontend/dashboard/ring-block.vue | 122 ++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 src/frontend/dashboard/ring-block.story.vue create mode 100644 src/frontend/dashboard/ring-block.vue diff --git a/src/frontend/dashboard/ring-block.story.vue b/src/frontend/dashboard/ring-block.story.vue new file mode 100644 index 00000000..e35ef4b4 --- /dev/null +++ b/src/frontend/dashboard/ring-block.story.vue @@ -0,0 +1,51 @@ +
+ +
+ + + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + + + diff --git a/src/frontend/dashboard/ring-block.vue b/src/frontend/dashboard/ring-block.vue new file mode 100644 index 00000000..6443d9bc --- /dev/null +++ b/src/frontend/dashboard/ring-block.vue @@ -0,0 +1,122 @@ + + + From a8192a40c4a4eb29d053e541357d7c0b3bf573b5 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Fri, 20 Feb 2026 13:18:10 +0300 Subject: [PATCH 05/99] feat: extend LanguageSpecification and update translation progress handling in lang-table components --- src/frontend/dashboard/ring-block.vue | 12 +++------ .../languages/components/lang-table.story.vue | 2 +- .../languages/components/lang-table.vue | 26 ++++++------------- src/types.ts | 6 +++++ 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/frontend/dashboard/ring-block.vue b/src/frontend/dashboard/ring-block.vue index 6443d9bc..f695c57d 100644 --- a/src/frontend/dashboard/ring-block.vue +++ b/src/frontend/dashboard/ring-block.vue @@ -67,15 +67,9 @@ diff --git a/src/frontend/settings/languages/components/source-lang.vue b/src/frontend/settings/languages/components/source-lang.vue index 0d2ad0dd..48db7f83 100644 --- a/src/frontend/settings/languages/components/source-lang.vue +++ b/src/frontend/settings/languages/components/source-lang.vue @@ -5,12 +5,12 @@ {{ language }}

- {{ nativeName }} ({{ locale }}) + {{ nativeName }} ({{ spec.locale }})

- ( {{ bibleVersionAbbreviation }} ) {{ bibleVersionName }} + {{ spec.bibleLabel }}

@@ -24,20 +24,20 @@ diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index 7ccbf95f..f1613f12 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -26,12 +26,15 @@ /> diff --git a/src/types.ts b/src/types.ts index 20836abc..5d445741 100644 --- a/src/types.ts +++ b/src/types.ts @@ -543,12 +543,8 @@ export interface LanguageSpecification { languageDirection: 'rtl' | 'ltr'; locale: string; bibleVersion?: string; -} - -export interface LanguageSpecificationExtended extends LanguageSpecification { bibleVersionId?: string; - bibleVersionName?: string; - bibleVersionAbbreviation?: string; + bibleLabel?: string; } export interface Providers { From 38378d63ac7da57b607312d652af07e7566a9878 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Fri, 20 Feb 2026 13:48:22 +0300 Subject: [PATCH 07/99] fix: remove extraneous closing tag in languages-index.vue --- src/frontend/settings/languages/languages-index.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index f1613f12..2eac228c 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -35,7 +35,6 @@ bibleLabel: '(KJV) King James Version', }" /> - /> From 502f55310a2ed343b3e03a52a01ef31062fe9c3b Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Mon, 23 Feb 2026 07:36:43 +0300 Subject: [PATCH 08/99] refactor: update type definitions in lang-table story to use TableItem --- .../settings/languages/components/lang-table.story.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/components/lang-table.story.vue b/src/frontend/settings/languages/components/lang-table.story.vue index 7067cc21..1c7652d8 100644 --- a/src/frontend/settings/languages/components/lang-table.story.vue +++ b/src/frontend/settings/languages/components/lang-table.story.vue @@ -14,11 +14,11 @@ From 5f5115703f3d9f6c7e292e40628bc54e572fe949 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 24 Feb 2026 08:16:36 +0300 Subject: [PATCH 09/99] feat: introduce LangStrip component for language display and update lang-table and source-lang components to utilize it --- .../languages/components/lang-strip.vue | 29 +++++++++++++++++++ .../languages/components/lang-table.story.vue | 17 +++++------ .../languages/components/lang-table.vue | 12 +++++--- .../languages/components/source-lang.vue | 26 +++-------------- 4 files changed, 48 insertions(+), 36 deletions(-) create mode 100644 src/frontend/settings/languages/components/lang-strip.vue diff --git a/src/frontend/settings/languages/components/lang-strip.vue b/src/frontend/settings/languages/components/lang-strip.vue new file mode 100644 index 00000000..de8e9595 --- /dev/null +++ b/src/frontend/settings/languages/components/lang-strip.vue @@ -0,0 +1,29 @@ + + + diff --git a/src/frontend/settings/languages/components/lang-table.story.vue b/src/frontend/settings/languages/components/lang-table.story.vue index 1c7652d8..0c774032 100644 --- a/src/frontend/settings/languages/components/lang-table.story.vue +++ b/src/frontend/settings/languages/components/lang-table.story.vue @@ -23,7 +23,6 @@ const languages: TableItem[] = [ language: 'English', languageDirection: 'ltr', locale: 'en', - activeTranslations: 24, translationProgress: [ { name: 'Interface', done: 100, draft: 0, total: 100 }, { name: 'Content', done: 240, draft: 0, total: 240 }, @@ -60,7 +59,6 @@ const languages: TableItem[] = [ language: 'Spanish', languageDirection: 'ltr', locale: 'es', - activeTranslations: 18, translationProgress: [ { name: 'Interface', done: 75, draft: 0, total: 100 }, { name: 'Content', done: 225, draft: 0, total: 300 }, @@ -109,7 +107,6 @@ const languages: TableItem[] = [ language: 'French', languageDirection: 'ltr', locale: 'fr', - activeTranslations: 12, translationProgress: [ { name: 'Interface', done: 50, draft: 0, total: 100 }, { name: 'Content', done: 90, draft: 10, total: 150 }, @@ -134,7 +131,7 @@ const languages: TableItem[] = [ language: 'Arabic', languageDirection: 'rtl', locale: 'ar', - activeTranslations: 5, + translationProgress: [ { name: 'Interface', done: 25, draft: 0, total: 100 }, { name: 'Content', done: 50, draft: 0, total: 200 }, @@ -146,7 +143,7 @@ const languages: TableItem[] = [ language: 'Portuguese', languageDirection: 'ltr', locale: 'pt', - activeTranslations: 0, + translationProgress: [ { name: 'Interface', done: 0, draft: 0, total: 100 }, { name: 'Content', done: 0, draft: 0, total: 100 }, @@ -175,7 +172,7 @@ const manyLanguages: TableItem[] = [ language: 'German', languageDirection: 'ltr', locale: 'de', - activeTranslations: 8, + translationProgress: [ { name: 'Interface', done: 42, draft: 0, total: 100 }, { name: 'Content', done: 84, draft: 0, total: 200 }, @@ -200,7 +197,7 @@ const manyLanguages: TableItem[] = [ language: 'Swahili', languageDirection: 'ltr', locale: 'sw', - activeTranslations: 15, + translationProgress: [ { name: 'Interface', done: 88, draft: 0, total: 100 }, { name: 'Content', done: 264, draft: 0, total: 300 }, @@ -237,7 +234,7 @@ const manyLanguages: TableItem[] = [ language: 'Hindi', languageDirection: 'ltr', locale: 'hi', - activeTranslations: 3, + translationProgress: [ { name: 'Interface', done: 12, draft: 0, total: 100 }, { name: 'Content', done: 36, draft: 0, total: 300 }, @@ -249,7 +246,7 @@ const manyLanguages: TableItem[] = [ language: 'Chinese (Simplified)', languageDirection: 'ltr', locale: 'zh', - activeTranslations: 20, + translationProgress: [ { name: 'Interface', done: 92, draft: 0, total: 100 }, { name: 'Content', done: 460, draft: 40, total: 500 }, @@ -298,7 +295,7 @@ const manyLanguages: TableItem[] = [ language: 'Russian', languageDirection: 'ltr', locale: 'ru', - activeTranslations: 6, + translationProgress: [ { name: 'Interface', done: 35, draft: 0, total: 100 }, { name: 'Content', done: 105, draft: 0, total: 300 }, diff --git a/src/frontend/settings/languages/components/lang-table.vue b/src/frontend/settings/languages/components/lang-table.vue index 0906b13c..eead90b3 100644 --- a/src/frontend/settings/languages/components/lang-table.vue +++ b/src/frontend/settings/languages/components/lang-table.vue @@ -34,8 +34,10 @@ - - {{ item.activeTranslations ?? '—' }} + + @@ -57,7 +59,9 @@

- + {{ item.bibleTranslation ?? '—' }} @@ -89,9 +93,9 @@ import Pagination from '../../../shared/pagination.vue'; import type { LanguageSpecification, UserInterface, Progress } from '../../../../types'; import MemberRow from './member-row.vue'; import RingBlock from '../../../dashboard/ring-block.vue'; +import LangStrip from './lang-strip.vue'; export interface TableItem extends LanguageSpecification { - activeTranslations?: number; translationProgress?: Omit[]; teamMembers?: UserInterface[]; bibleTranslation?: string; diff --git a/src/frontend/settings/languages/components/source-lang.vue b/src/frontend/settings/languages/components/source-lang.vue index 48db7f83..570e59ff 100644 --- a/src/frontend/settings/languages/components/source-lang.vue +++ b/src/frontend/settings/languages/components/source-lang.vue @@ -1,12 +1,7 @@ From d6744c81c0b3fba13cd61913efff6f5566d817b9 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 24 Feb 2026 08:34:56 +0300 Subject: [PATCH 10/99] refactor: update lang-table components to use LanguageTableItem and replace bibleTranslation with bibleLabel --- .../languages/components/lang-table.story.vue | 29 ++++++++++--------- .../languages/components/lang-table.vue | 14 +++------ src/types.ts | 5 ++++ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/frontend/settings/languages/components/lang-table.story.vue b/src/frontend/settings/languages/components/lang-table.story.vue index 0c774032..c0cc5832 100644 --- a/src/frontend/settings/languages/components/lang-table.story.vue +++ b/src/frontend/settings/languages/components/lang-table.story.vue @@ -14,15 +14,17 @@ diff --git a/src/frontend/settings/languages/components/lang-table.vue b/src/frontend/settings/languages/components/lang-table.vue index eead90b3..e858f0ca 100644 --- a/src/frontend/settings/languages/components/lang-table.vue +++ b/src/frontend/settings/languages/components/lang-table.vue @@ -62,7 +62,7 @@ - {{ item.bibleTranslation ?? '—' }} + {{ item.bibleLabel ?? '—' }} +
+ + + +
From 534caad78914ec31e4517bc9dac5b200ed3d476f Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 24 Feb 2026 11:05:42 +0300 Subject: [PATCH 12/99] fix: adjust positioning of dropdown menu in lang-table component for improved layout --- src/frontend/settings/languages/components/lang-table.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/settings/languages/components/lang-table.vue b/src/frontend/settings/languages/components/lang-table.vue index 8be950c2..06b6c581 100644 --- a/src/frontend/settings/languages/components/lang-table.vue +++ b/src/frontend/settings/languages/components/lang-table.vue @@ -73,7 +73,7 @@
- +
- diff --git a/src/frontend/settings/languages/languages-edit.story.vue b/src/frontend/settings/languages/languages-edit.story.vue index bdcb693f..a3a6aed2 100644 --- a/src/frontend/settings/languages/languages-edit.story.vue +++ b/src/frontend/settings/languages/languages-edit.story.vue @@ -1,7 +1,7 @@ @@ -9,4 +9,28 @@ diff --git a/src/frontend/settings/languages/languages-edit.vue b/src/frontend/settings/languages/languages-edit.vue index 89c5faea..411d2925 100644 --- a/src/frontend/settings/languages/languages-edit.vue +++ b/src/frontend/settings/languages/languages-edit.vue @@ -19,19 +19,49 @@ + From dae0a1ced5f940fba6477f7a1329b85c9f897948 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 10:06:26 +0300 Subject: [PATCH 30/99] feat: sort language list items for improved organization and user experience --- src/frontend/settings/languages/languages-edit.vue | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/languages-edit.vue b/src/frontend/settings/languages/languages-edit.vue index f053c1b6..afefa084 100644 --- a/src/frontend/settings/languages/languages-edit.vue +++ b/src/frontend/settings/languages/languages-edit.vue @@ -105,10 +105,11 @@ const addedLanguageItems = computed(() => })), ); -const languageListItems = computed(() => [ - ...addedLanguageItems.value, - ...availableLanguageItems.value, -]); +const languageListItems = computed(() => + [...addedLanguageItems.value, ...availableLanguageItems.value].sort((a, b) => + a.language.language.localeCompare(b.language.language), + ), +); const removeSelectedLanguage = (locale: string) => { const next = new Set(selectedLocales.value); From 0bbf2e8d0e13878c855a9a6169dafbf00b3536c0 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 10:14:27 +0300 Subject: [PATCH 31/99] feat: enhance language list layout with additional padding and update button styles for better usability --- src/frontend/settings/languages/language-list.vue | 2 +- src/frontend/settings/languages/languages-edit.vue | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/settings/languages/language-list.vue b/src/frontend/settings/languages/language-list.vue index 5816e74b..e4e72357 100644 --- a/src/frontend/settings/languages/language-list.vue +++ b/src/frontend/settings/languages/language-list.vue @@ -1,5 +1,5 @@ + + @@ -67,7 +75,7 @@ import { ref, computed } from 'vue'; import AppLayout from '../../shared/app-layout.vue'; import ContentHeader from '../../shared/content-header.vue'; import LanguageList from './language-list.vue'; - +import LanguageAddModal from './components/language-add-modal.vue'; import type { LanguageSpecification } from '../../../types'; import { languages as allLanguages } from './languages'; @@ -75,6 +83,10 @@ const props = defineProps<{ addedLanguages: LanguageSpecification[]; }>(); +const emit = defineEmits<{ + add: [locales: string[]]; +}>(); + const selectedLocales = ref>(new Set()); const availableLanguageItems = computed(() => @@ -118,7 +130,15 @@ const removeSelectedLanguage = (locale: string) => { selectedLocales.value = next; }; +const showAddModal = ref(false); + const addLanguage = () => { - console.log('addLanguage'); + showAddModal.value = true; +}; + +const confirmAddLanguages = () => { + showAddModal.value = false; + emit('add', [...selectedLocales.value]); + selectedLocales.value = new Set(); }; From 0b3065d5badd8f0783b39cd2e349422b3c2f8e15 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 10:54:40 +0300 Subject: [PATCH 34/99] refactor: replace button components with PillButton for consistent styling --- .../settings/languages/components/actions.vue | 13 ------- .../components/language-add-modal.vue | 15 ++----- .../settings/languages/language-list.vue | 11 +++--- .../settings/languages/languages-edit.vue | 10 ++--- .../settings/languages/languages-index.vue | 4 +- src/frontend/shared/pill-button.vue | 39 +++++++++++++++++++ 6 files changed, 55 insertions(+), 37 deletions(-) delete mode 100644 src/frontend/settings/languages/components/actions.vue create mode 100644 src/frontend/shared/pill-button.vue diff --git a/src/frontend/settings/languages/components/actions.vue b/src/frontend/settings/languages/components/actions.vue deleted file mode 100644 index 9b7e8cb7..00000000 --- a/src/frontend/settings/languages/components/actions.vue +++ /dev/null @@ -1,13 +0,0 @@ - - diff --git a/src/frontend/settings/languages/components/language-add-modal.vue b/src/frontend/settings/languages/components/language-add-modal.vue index 03fbe742..031dab2f 100644 --- a/src/frontend/settings/languages/components/language-add-modal.vue +++ b/src/frontend/settings/languages/components/language-add-modal.vue @@ -54,18 +54,8 @@
- - + +
@@ -75,6 +65,7 @@ From 7447891579886eb129e8b8888d03f15a1f8c69dd Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 11:02:16 +0300 Subject: [PATCH 35/99] refactor: update Languages Index component with new button actions and story title --- .../settings/languages/languages-index.story.vue | 2 +- src/frontend/settings/languages/languages-index.vue | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/languages-index.story.vue b/src/frontend/settings/languages/languages-index.story.vue index a0c814f4..3fb29fd3 100644 --- a/src/frontend/settings/languages/languages-index.story.vue +++ b/src/frontend/settings/languages/languages-index.story.vue @@ -1,5 +1,5 @@ @@ -44,7 +48,7 @@ import Icon from '../../shared/icon.vue'; import PillButton from '../../shared/pill-button.vue'; import SourceLang from './components/source-language.vue'; import LanguagesTable from './components/language-table.vue'; -import type { LanguagesProps, SharedPageProps } from '../../../types'; +import type { LanguageTableItem, LanguagesProps, SharedPageProps } from '../../../types'; import { useSharedStore } from '../../store'; const props = defineProps(); @@ -54,7 +58,15 @@ shared.setFromProps(props); shared.setCurrentStoryName(''); const requestAppUpdate = () => { - console.log('addLanguage'); + console.log('requestAppUpdate'); +}; + +const handleRemove = (_item: LanguageTableItem) => { + console.log('remove language', _item.locale); +}; + +const handleRequestDeletion = (_item: LanguageTableItem) => { + console.log('request language deletion', _item.locale); }; const items = computed(() => props.languageItems ?? []); diff --git a/src/frontend/shared/pill-button.vue b/src/frontend/shared/pill-button.vue index 4654a5ca..2d2a9913 100644 --- a/src/frontend/shared/pill-button.vue +++ b/src/frontend/shared/pill-button.vue @@ -15,7 +15,7 @@ import { computed } from 'vue'; const props = withDefaults( defineProps<{ label: string; - variant?: 'green' | 'blue' | 'gray'; + variant?: 'green' | 'blue' | 'gray' | 'red'; disabled?: boolean; }>(), { variant: 'blue', disabled: false }, @@ -30,6 +30,7 @@ const variantClasses: Record = { 'bg-green-500 hover:bg-green-400 disabled:bg-gray-400 disabled:hover:bg-gray-400', blue: 'bg-blue-500 hover:bg-blue-400 disabled:bg-gray-400 disabled:hover:bg-gray-400', gray: 'bg-gray-200 hover:bg-gray-400 disabled:bg-gray-400 disabled:hover:bg-gray-400', + red: 'bg-red-500 hover:bg-red-400 disabled:bg-gray-400 disabled:hover:bg-gray-400', }; const buttonClasses = computed( From 876bc36af9a8228af78d6173c986d7cb8e523468 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 11:35:09 +0300 Subject: [PATCH 37/99] feat: add Request App Update modal component and integrate it into Languages Index --- .../request-app-update-modal.story.vue | 29 ++++++ .../components/request-app-update-modal.vue | 98 +++++++++++++++++++ .../settings/languages/languages-index.vue | 18 +++- 3 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/frontend/settings/languages/components/request-app-update-modal.story.vue create mode 100644 src/frontend/settings/languages/components/request-app-update-modal.vue diff --git a/src/frontend/settings/languages/components/request-app-update-modal.story.vue b/src/frontend/settings/languages/components/request-app-update-modal.story.vue new file mode 100644 index 00000000..36fecefa --- /dev/null +++ b/src/frontend/settings/languages/components/request-app-update-modal.story.vue @@ -0,0 +1,29 @@ + + + diff --git a/src/frontend/settings/languages/components/request-app-update-modal.vue b/src/frontend/settings/languages/components/request-app-update-modal.vue new file mode 100644 index 00000000..f3b13e6e --- /dev/null +++ b/src/frontend/settings/languages/components/request-app-update-modal.vue @@ -0,0 +1,98 @@ + + + diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index e9b28f8b..8dbb1fd5 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -6,7 +6,7 @@ diff --git a/src/frontend/settings/languages/components/request-feedback-modal.vue b/src/frontend/settings/languages/components/request-feedback-modal.vue new file mode 100644 index 00000000..561529c6 --- /dev/null +++ b/src/frontend/settings/languages/components/request-feedback-modal.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index 8dbb1fd5..016af147 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -42,6 +42,12 @@ @close="showRequestAppUpdateModal = false" @confirm="handleRequestAppUpdateConfirm" /> + + @@ -55,6 +61,7 @@ import PillButton from '../../shared/pill-button.vue'; import SourceLang from './components/source-language.vue'; import LanguagesTable from './components/language-table.vue'; import RequestAppUpdateModal from './components/request-app-update-modal.vue'; +import RequestFeedbackModal from './components/request-feedback-modal.vue'; import type { LanguageTableItem, LanguagesProps, SharedPageProps } from '../../../types'; import { useSharedStore } from '../../store'; @@ -65,10 +72,30 @@ shared.setFromProps(props); shared.setCurrentStoryName(''); const showRequestAppUpdateModal = ref(false); +const showFeedbackModal = ref(false); +const feedbackModalVariant = ref<'success' | 'error'>('success'); -const handleRequestAppUpdateConfirm = (reason: string) => { - console.log('requestAppUpdate', reason); +const handleRequestAppUpdateConfirm = async (reason: string) => { showRequestAppUpdateModal.value = false; + try { + // TODO: Replace with actual API call + await submitAppUpdateRequest(reason); + feedbackModalVariant.value = 'success'; + showFeedbackModal.value = true; + } catch { + feedbackModalVariant.value = 'error'; + showFeedbackModal.value = true; + } +}; + +const submitAppUpdateRequest = async (_reason: string): Promise => { + // Simulate API call - replace with actual implementation + await new Promise((resolve) => { + setTimeout(() => { + // Simulate success; use reject() to test error modal + resolve(undefined); + }, 300); + }); }; const handleRemove = (_item: LanguageTableItem) => { From 030c8367d761d8c4af00ff3ac4e8d3683882890e Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 3 Mar 2026 11:55:26 +0300 Subject: [PATCH 39/99] feat: add mailFromAddress to CmsMeta and integrate it into Request Feedback Modal for contact inquiries --- src/backend/define_config.ts | 1 + src/backend/stubs/config/cms.stub | 5 +++++ .../components/request-feedback-modal.story.vue | 7 ++++++- .../languages/components/request-feedback-modal.vue | 13 +++++-------- src/frontend/settings/languages/languages-index.vue | 1 + src/frontend/test/mocks.ts | 1 + src/types.ts | 2 ++ 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/backend/define_config.ts b/src/backend/define_config.ts index a88e9484..81a5e31a 100644 --- a/src/backend/define_config.ts +++ b/src/backend/define_config.ts @@ -10,6 +10,7 @@ export function defineConfig(config: Partial): CmsConfig { hasAppPreview: false, helpUrl: 'https://journeys.helpscoutdocs.com/', logo: 'https://res.cloudinary.com/journeys/image/upload/v1756295658/logo_g8k7tf.png', + mailFromAddress: 'ops@scoutredeem.co', ...config.meta, }, diff --git a/src/backend/stubs/config/cms.stub b/src/backend/stubs/config/cms.stub index 1b3fd3bd..70337879 100644 --- a/src/backend/stubs/config/cms.stub +++ b/src/backend/stubs/config/cms.stub @@ -80,6 +80,11 @@ const cmsConfig: CmsConfig = defineConfig({ * Are we embedding a Flutter preview? */ hasAppPreview: false, + + /** + * Contact email for enquiries (from MAIL_FROM_ADDRESS) + */ + mailFromAddress: 'ops@scoutredeem.co', }, languages: { diff --git a/src/frontend/settings/languages/components/request-feedback-modal.story.vue b/src/frontend/settings/languages/components/request-feedback-modal.story.vue index 0fcfb95f..23b432d5 100644 --- a/src/frontend/settings/languages/components/request-feedback-modal.story.vue +++ b/src/frontend/settings/languages/components/request-feedback-modal.story.vue @@ -1,12 +1,16 @@ + +
+ + + + {{ selectedBibleVersion?.name ?? 'Select translation' }} + + + + + + + + +
  • + + {{ version.name }} + + + +
  • +
    +
    +
    +
    +
    + + +
    + import { ref, computed } from 'vue'; +import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue'; import Icon from '../../../shared/icon.vue'; import Pagination from '../../../shared/pagination.vue'; import PillButton from '../../../shared/pill-button.vue'; @@ -151,6 +229,14 @@ import MemberRow from './member-row.vue'; import RingBlock from '../../../dashboard/ring-block.vue'; import LangStrip from './language-strip.vue'; +const BIBLE_VERSIONS = [ + { id: 'eng-ESV', name: 'English Standard Version' }, + { id: 'eng-NIV', name: 'New International Version' }, + { id: 'eng-NLT', name: 'New Living Translation' }, + { id: 'eng-NASB', name: 'New American Standard Bible' }, + { id: 'eng-KJV', name: 'King James Version' }, +] as const; + const props = withDefaults( defineProps<{ items: LanguageTableItem[]; @@ -162,6 +248,11 @@ const props = withDefaults( const emit = defineEmits<{ remove: [item: LanguageTableItem]; requestDeletion: [item: LanguageTableItem]; + bibleChange: [ + item: LanguageTableItem, + bibleVersionId: string, + bibleVersionName: string, + ]; }>(); const currentPage = ref(1); @@ -178,6 +269,8 @@ const handlePageChange = (page: number) => { const openActionsLocale = ref(null); const removeModalLocale = ref(null); const requestDeletionModalLocale = ref(null); +const bibleModalLocale = ref(null); +const selectedBibleVersion = ref<{ id: string; name: string } | null>(null); const toggleActions = (locale: string) => { openActionsLocale.value = openActionsLocale.value === locale ? null : locale; @@ -204,6 +297,32 @@ const confirmRequestDeletion = () => { requestDeletionModalLocale.value = null; }; +const openBibleModal = (item: LanguageTableItem) => { + openActionsLocale.value = null; + bibleModalLocale.value = item.locale; + const current = BIBLE_VERSIONS.find( + (v) => v.id === item.bibleVersionId || v.name === item.bibleLabel, + ); + selectedBibleVersion.value = current ?? BIBLE_VERSIONS[0]; +}; + +const closeBibleModal = () => { + bibleModalLocale.value = null; +}; + +const confirmBibleChange = () => { + const item = props.items.find((i) => i.locale === bibleModalLocale.value); + if (item && selectedBibleVersion.value) { + emit( + 'bibleChange', + item, + selectedBibleVersion.value.id, + selectedBibleVersion.value.name, + ); + } + closeBibleModal(); +}; + const truncate = (s: string | null | undefined, max: number) => { const text = s ?? '—'; return text.length > max ? `${text.slice(0, max)}…` : text; @@ -211,6 +330,4 @@ const truncate = (s: string | null | undefined, max: number) => { const hasContent = (item: LanguageTableItem) => item.translationProgress?.every((progress) => progress.done > 0) ?? false; - - diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index 22b64c27..14141240 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -53,8 +53,9 @@ diff --git a/src/types.ts b/src/types.ts index abafa3ce..3cf7524e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -540,17 +540,13 @@ export type CmsConfig = { }; }; -export interface BibleSpecification { - id: string; - bibleVersion?: string; - bibleVersionId?: string; - bibleLabel?: string; -} - -export interface LanguageSpecification extends Omit { +export interface LanguageSpecification { language: string; languageDirection: 'rtl' | 'ltr'; locale: string; + bibleVersion?: string; + bibleVersionId?: string; + bibleLabel?: string; } export interface LanguageTableItem extends LanguageSpecification { From 13a85917effdf9e1378b6c061876ffdb7b5b6333 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 06:38:00 +0300 Subject: [PATCH 43/99] refactor: change name of function --- .../languages/components/language-table.vue | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/frontend/settings/languages/components/language-table.vue b/src/frontend/settings/languages/components/language-table.vue index 89a74adb..b8568d40 100644 --- a/src/frontend/settings/languages/components/language-table.vue +++ b/src/frontend/settings/languages/components/language-table.vue @@ -84,7 +84,7 @@ @@ -133,9 +133,9 @@
    @@ -199,11 +199,11 @@
    @@ -248,7 +248,7 @@ const props = withDefaults( const emit = defineEmits<{ remove: [item: LanguageTableItem]; requestDeletion: [item: LanguageTableItem]; - bibleChange: [ + bibleTranslationChange: [ item: LanguageTableItem, bibleVersionId: string, bibleVersionName: string, @@ -269,7 +269,7 @@ const handlePageChange = (page: number) => { const openActionsLocale = ref(null); const removeModalLocale = ref(null); const requestDeletionModalLocale = ref(null); -const bibleModalLocale = ref(null); +const bibleTranslationsModalLocale = ref(null); const selectedBibleVersion = ref<{ id: string; name: string } | null>(null); const toggleActions = (locale: string) => { @@ -297,30 +297,30 @@ const confirmRequestDeletion = () => { requestDeletionModalLocale.value = null; }; -const openBibleModal = (item: LanguageTableItem) => { +const openBibleTranslationsModal = (item: LanguageTableItem) => { openActionsLocale.value = null; - bibleModalLocale.value = item.locale; + bibleTranslationsModalLocale.value = item.locale; const current = BIBLE_VERSIONS.find( (v) => v.id === item.bibleVersionId || v.name === item.bibleLabel, ); selectedBibleVersion.value = current ?? BIBLE_VERSIONS[0]; }; -const closeBibleModal = () => { - bibleModalLocale.value = null; +const closeBibleTranslationsModal = () => { + bibleTranslationsModalLocale.value = null; }; -const confirmBibleChange = () => { - const item = props.items.find((i) => i.locale === bibleModalLocale.value); +const bibleTranslationChange = () => { + const item = props.items.find((i) => i.locale === bibleTranslationsModalLocale.value); if (item && selectedBibleVersion.value) { emit( - 'bibleChange', + 'bibleTranslationChange', item, selectedBibleVersion.value.id, selectedBibleVersion.value.name, ); } - closeBibleModal(); + closeBibleTranslationsModal(); }; const truncate = (s: string | null | undefined, max: number) => { From 8b1f2c9352cc4f3e42668ed07ce0bfe33ada8c5b Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 06:42:19 +0300 Subject: [PATCH 44/99] refactor: replace LanguageModal with dedicated modals for language removal and request deletion, and update Bible translation modal integration --- .../languages/components/language-table.vue | 145 +++--------------- .../modals/bible-translations-modal.vue | 130 ++++++++++++++++ .../modals/remove-language-modal.vue | 27 ++++ .../modals/request-deletion-modal.vue | 27 ++++ 4 files changed, 205 insertions(+), 124 deletions(-) create mode 100644 src/frontend/settings/languages/components/modals/bible-translations-modal.vue create mode 100644 src/frontend/settings/languages/components/modals/remove-language-modal.vue create mode 100644 src/frontend/settings/languages/components/modals/request-deletion-modal.vue diff --git a/src/frontend/settings/languages/components/language-table.vue b/src/frontend/settings/languages/components/language-table.vue index b8568d40..f396cada 100644 --- a/src/frontend/settings/languages/components/language-table.vue +++ b/src/frontend/settings/languages/components/language-table.vue @@ -100,113 +100,24 @@ - - - + @confirm="confirmRemove" + /> - - - + @confirm="confirmRequestDeletion" + /> - -
    - - - - {{ selectedBibleVersion?.name ?? 'Select translation' }} - - - - - - - - -
  • - - {{ version.name }} - - - -
  • -
    -
    -
    -
    -
    - - -
    + @confirm="handleBibleTranslationConfirm" + /> import { ref, computed } from 'vue'; -import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue'; import Icon from '../../../shared/icon.vue'; import Pagination from '../../../shared/pagination.vue'; -import PillButton from '../../../shared/pill-button.vue'; -import LanguageModal from './language-modal.vue'; +import RemoveLanguageModal from './modals/remove-language-modal.vue'; +import RequestDeletionModal from './modals/request-deletion-modal.vue'; +import BibleTranslationsModal from './modals/bible-translations-modal.vue'; import type { LanguageTableItem } from '../../../../types'; import MemberRow from './member-row.vue'; import RingBlock from '../../../dashboard/ring-block.vue'; import LangStrip from './language-strip.vue'; -const BIBLE_VERSIONS = [ - { id: 'eng-ESV', name: 'English Standard Version' }, - { id: 'eng-NIV', name: 'New International Version' }, - { id: 'eng-NLT', name: 'New Living Translation' }, - { id: 'eng-NASB', name: 'New American Standard Bible' }, - { id: 'eng-KJV', name: 'King James Version' }, -] as const; - const props = withDefaults( defineProps<{ items: LanguageTableItem[]; @@ -270,7 +173,10 @@ const openActionsLocale = ref(null); const removeModalLocale = ref(null); const requestDeletionModalLocale = ref(null); const bibleTranslationsModalLocale = ref(null); -const selectedBibleVersion = ref<{ id: string; name: string } | null>(null); + +const bibleTranslationsModalItem = computed(() => + props.items.find((i) => i.locale === bibleTranslationsModalLocale.value) ?? null, +); const toggleActions = (locale: string) => { openActionsLocale.value = openActionsLocale.value === locale ? null : locale; @@ -300,25 +206,16 @@ const confirmRequestDeletion = () => { const openBibleTranslationsModal = (item: LanguageTableItem) => { openActionsLocale.value = null; bibleTranslationsModalLocale.value = item.locale; - const current = BIBLE_VERSIONS.find( - (v) => v.id === item.bibleVersionId || v.name === item.bibleLabel, - ); - selectedBibleVersion.value = current ?? BIBLE_VERSIONS[0]; }; const closeBibleTranslationsModal = () => { bibleTranslationsModalLocale.value = null; }; -const bibleTranslationChange = () => { - const item = props.items.find((i) => i.locale === bibleTranslationsModalLocale.value); - if (item && selectedBibleVersion.value) { - emit( - 'bibleTranslationChange', - item, - selectedBibleVersion.value.id, - selectedBibleVersion.value.name, - ); +const handleBibleTranslationConfirm = (bibleVersionId: string, bibleVersionName: string) => { + const item = bibleTranslationsModalItem.value; + if (item) { + emit('bibleTranslationChange', item, bibleVersionId, bibleVersionName); } closeBibleTranslationsModal(); }; diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue new file mode 100644 index 00000000..cca4e43f --- /dev/null +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -0,0 +1,130 @@ + + + diff --git a/src/frontend/settings/languages/components/modals/remove-language-modal.vue b/src/frontend/settings/languages/components/modals/remove-language-modal.vue new file mode 100644 index 00000000..b397a3f2 --- /dev/null +++ b/src/frontend/settings/languages/components/modals/remove-language-modal.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/frontend/settings/languages/components/modals/request-deletion-modal.vue b/src/frontend/settings/languages/components/modals/request-deletion-modal.vue new file mode 100644 index 00000000..94058ee1 --- /dev/null +++ b/src/frontend/settings/languages/components/modals/request-deletion-modal.vue @@ -0,0 +1,27 @@ + + + From 93dcdca7db66bc2e684ba2c7b440868ecbbc2d55 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 06:49:48 +0300 Subject: [PATCH 45/99] refactor: update Bible translations modal to use new BibleVersion structure --- .../modals/bible-translations-modal.vue | 78 +++++++++++-------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index cca4e43f..c116d8a4 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -1,25 +1,17 @@ @@ -82,14 +67,37 @@ import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headless import Icon from '../../../../shared/icon.vue'; import LanguageModal from '../language-modal.vue'; import PillButton from '../../../../shared/pill-button.vue'; -import type { LanguageTableItem } from '../../../../../types'; +import type { LanguageTableItem, LanguageSpecification } from '../../../../../types'; -const BIBLE_VERSIONS = [ - { id: 'eng-ESV', name: 'English Standard Version' }, - { id: 'eng-NIV', name: 'New International Version' }, - { id: 'eng-NLT', name: 'New Living Translation' }, - { id: 'eng-NASB', name: 'New American Standard Bible' }, - { id: 'eng-KJV', name: 'King James Version' }, +const BIBLE_VERSIONS: Omit< + LanguageSpecification, + 'language' | 'languageDirection' | 'locale' +>[] = [ + { + bibleVersion: 'English Standard Version', + bibleVersionId: 'de4e12af7f28f599-02', + bibleLabel: '(ESV) English Standard Version', + }, + { + bibleVersion: 'New International Version', + bibleVersionId: 'de4e12af7f28f599-03', + bibleLabel: '(NIV) New International Version', + }, + { + bibleVersion: 'New Living Translation', + bibleVersionId: 'de4e12af7f28f599-04', + bibleLabel: '(NLT) New Living Translation', + }, + { + bibleVersion: 'New American Standard Bible', + bibleVersionId: 'de4e12af7f28f599-05', + bibleLabel: '(NASB) New American Standard Bible', + }, + { + bibleVersion: 'King James Version', + bibleVersionId: 'de4e12af7f28f599-01', + bibleLabel: '(KJV) King James Version', + }, ] as const; const props = defineProps<{ @@ -102,14 +110,16 @@ const emit = defineEmits<{ confirm: [bibleVersionId: string, bibleVersionName: string]; }>(); -const selectedBibleVersion = ref<{ id: string; name: string } | null>(null); +type BibleVersion = (typeof BIBLE_VERSIONS)[number]; +const selectedBibleVersion = ref(null); watch( () => [props.open, props.item] as const, ([isOpen, item]) => { if (isOpen && item) { const current = BIBLE_VERSIONS.find( - (v) => v.id === item.bibleVersionId || v.name === item.bibleLabel, + (v) => + v.bibleVersionId === item.bibleVersionId || v.bibleLabel === item.bibleLabel, ); selectedBibleVersion.value = current ?? BIBLE_VERSIONS[0]; } @@ -123,7 +133,11 @@ const handleClose = () => { const handleConfirm = () => { if (selectedBibleVersion.value) { - emit('confirm', selectedBibleVersion.value.id, selectedBibleVersion.value.name); + emit( + 'confirm', + selectedBibleVersion.value.bibleVersionId ?? '', + selectedBibleVersion.value.bibleLabel ?? '', + ); } emit('close'); }; From d4639cefd77f3f1b338409afefa600cf9c57cdcf Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:02:00 +0300 Subject: [PATCH 46/99] refactor: streamline Bible translations handling by integrating API call and state management in shared store --- .../modals/bible-translations-modal.vue | 99 ++++++++++++------- .../settings/languages/languages-index.vue | 55 +---------- src/frontend/store/shared.ts | 13 +++ 3 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index c116d8a4..571e4e1e 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -24,7 +24,7 @@ class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" > diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index 14141240..b7315324 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -53,9 +53,8 @@ diff --git a/src/frontend/store/shared.ts b/src/frontend/store/shared.ts index d00f3eca..6e3fbf6f 100644 --- a/src/frontend/store/shared.ts +++ b/src/frontend/store/shared.ts @@ -177,6 +177,16 @@ export const useSharedStore = defineStore('shared', () => { sourceSectionWidth.value = value; }; + // bible translations + const bibleTranslations = ref< + Omit[] + >([]); + const setBibleTranslations = ( + value: Omit[], + ) => { + bibleTranslations.value = value; + }; + return { exclude, meta, @@ -239,5 +249,8 @@ export const useSharedStore = defineStore('shared', () => { sourceSectionWidth, setSourceSectionWidth, + + bibleTranslations, + setBibleTranslations, }; }); From dded727298e7bb1f3afea06da1b51e16191e14bb Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:02:48 +0300 Subject: [PATCH 47/99] refactor: define APIBibleVersion type for improved type safety in getBibleVersions function --- .../modals/bible-translations-modal.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index 571e4e1e..4f2b19df 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -119,15 +119,15 @@ const handleConfirm = () => { emit('close'); }; -const getBibleVersions = async (): Promise< - Array<{ - name: string; - id: string; - abbreviation: string; - description: string; - language: string; - }> -> => { +type APIBibleVersion = { + name: string; + id: string; + abbreviation: string; + description: string; + language: string; +}; + +const getBibleVersions = async (): Promise> => { const apiKey = widgets.providers.scripture?.bibleApiKey; if (!apiKey) { return []; From ecafc2b0fd576418ba84ffbbd2db2daee4c57fab Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:03:05 +0300 Subject: [PATCH 48/99] refactor: update transformBibleVersions function to utilize APIBibleVersion type for enhanced type safety --- .../components/modals/bible-translations-modal.vue | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index 4f2b19df..4e6e7c14 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -156,13 +156,7 @@ onMounted(async () => { }); const transformBibleVersions = ( - versions: Array<{ - name: string; - id: string; - abbreviation: string; - description: string; - language: string; - }>, + versions: Array, ): Omit[] => { return versions.map((version) => ({ bibleVersion: version.name, From 0dfd23a0ccfaf2760770836c4e2e1516c9a579e4 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:04:59 +0300 Subject: [PATCH 49/99] refator: add loading state --- .../modals/bible-translations-modal.vue | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index 4e6e7c14..c2ae0007 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -1,7 +1,10 @@ @@ -79,6 +87,7 @@ type BibleVersion = Omit< 'language' | 'languageDirection' | 'locale' >; const selectedBibleVersion = ref(null); +const isLoading = ref(false); const props = defineProps<{ open: boolean; @@ -151,8 +160,13 @@ const getBibleVersions = async (): Promise> => { }; onMounted(async () => { - const versions = await getBibleVersions(); - shared.setBibleTranslations(transformBibleVersions(versions)); + isLoading.value = true; + try { + const versions = await getBibleVersions(); + shared.setBibleTranslations(transformBibleVersions(versions)); + } finally { + isLoading.value = false; + } }); const transformBibleVersions = ( From 02b22534858bcb6a6af9b6c6d2bbbb4abca6e475 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:14:06 +0300 Subject: [PATCH 50/99] refactor: enhance Bible translations modal with error handling and loading spinner --- .../modals/bible-translations-modal.vue | 24 +++++++++++++++---- src/frontend/shared/icon.vue | 23 ++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index c2ae0007..86d7c542 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -1,8 +1,20 @@ @@ -88,6 +100,7 @@ type BibleVersion = Omit< >; const selectedBibleVersion = ref(null); const isLoading = ref(false); +const hasError = ref(false); const props = defineProps<{ open: boolean; @@ -155,15 +168,18 @@ const getBibleVersions = async (): Promise> => { })); } catch (err) { console.error('getBibleVersions failed:', err); - return []; + throw err; } }; onMounted(async () => { isLoading.value = true; + hasError.value = false; try { const versions = await getBibleVersions(); shared.setBibleTranslations(transformBibleVersions(versions)); + } catch { + hasError.value = true; } finally { isLoading.value = false; } diff --git a/src/frontend/shared/icon.vue b/src/frontend/shared/icon.vue index 3340e042..91c377f2 100644 --- a/src/frontend/shared/icon.vue +++ b/src/frontend/shared/icon.vue @@ -11,6 +11,29 @@ + + Date: Wed, 4 Mar 2026 07:21:28 +0300 Subject: [PATCH 51/99] refactor: update transformBibleVersions function to return an array of BibleVersion objects for improved clarity --- .../languages/components/modals/bible-translations-modal.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index 86d7c542..e68fb765 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -187,7 +187,7 @@ onMounted(async () => { const transformBibleVersions = ( versions: Array, -): Omit[] => { +): Array => { return versions.map((version) => ({ bibleVersion: version.name, bibleVersionId: version.id, From 45988e4fa478330092073329fce9f021a0dc424e Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:25:14 +0300 Subject: [PATCH 52/99] refactor: simplify BibleVersion type and enhance default selection logic in Bible translations modal --- .../components/modals/bible-translations-modal.vue | 9 ++++----- src/frontend/store/shared.ts | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index e68fb765..bcb0c057 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -94,10 +94,7 @@ import type { LanguageTableItem, LanguageSpecification } from '../../../../../ty const widgets = useWidgetsStore(); const shared = useSharedStore(); -type BibleVersion = Omit< - LanguageSpecification, - 'language' | 'languageDirection' | 'locale' ->; +type BibleVersion = Omit; const selectedBibleVersion = ref(null); const isLoading = ref(false); const hasError = ref(false); @@ -120,7 +117,8 @@ watch( (v) => v.bibleVersionId === item.bibleVersionId || v.bibleLabel === item.bibleLabel, ); - selectedBibleVersion.value = current ?? shared.bibleTranslations[0]; + selectedBibleVersion.value = + current ?? shared.bibleTranslations[0] ?? null; } }, { immediate: true }, @@ -189,6 +187,7 @@ const transformBibleVersions = ( versions: Array, ): Array => { return versions.map((version) => ({ + language: version.language, bibleVersion: version.name, bibleVersionId: version.id, bibleLabel: `(${version.abbreviation}) ${version.name}`, diff --git a/src/frontend/store/shared.ts b/src/frontend/store/shared.ts index 6e3fbf6f..0c600986 100644 --- a/src/frontend/store/shared.ts +++ b/src/frontend/store/shared.ts @@ -179,10 +179,10 @@ export const useSharedStore = defineStore('shared', () => { // bible translations const bibleTranslations = ref< - Omit[] + Omit[] >([]); const setBibleTranslations = ( - value: Omit[], + value: Omit[], ) => { bibleTranslations.value = value; }; From 43b58c1ec3d7c97380372ef579087bb153746fb8 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:30:03 +0300 Subject: [PATCH 53/99] refactor: improve error handling in Bible translations modal by displaying specific error messages --- .../components/modals/bible-translations-modal.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index bcb0c057..a75a2ddd 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -11,9 +11,7 @@
    Failed to load translations. - Please check your connection and try again. + {{ errorMessage }}
    @@ -83,7 +81,7 @@ From 47946b0abcffbf65b9f02c2a987989603ab2838d Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:56:11 +0300 Subject: [PATCH 55/99] refactor: add no translations available message and update button state in Bible translations modal --- .../components/modals/bible-translations-modal.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index d33af959..d5b94bca 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -14,6 +14,12 @@ {{ errorMessage }} +
    + No Bible translations available for this language. +
    From eceaccbbfc5ceb082b458a8131443b74596d514d Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 07:58:26 +0300 Subject: [PATCH 56/99] refactor: optimize loading logic in Bible translations modal to prevent unnecessary API calls --- .../languages/components/modals/bible-translations-modal.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index d5b94bca..03f1c11b 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -195,6 +195,9 @@ const currentBibleTranslations = computed(() => { }); onMounted(async () => { + if (shared.bibleTranslations.length > 0) { + return; + } isLoading.value = true; hasError.value = false; try { From e3240515c7fd7cc9cb90426807be781bea476d2c Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 08:12:31 +0300 Subject: [PATCH 57/99] refactor: implement language matching logic to enhance Bible translations filtering --- .../modals/bible-translations-modal.vue | 14 +++++--- src/frontend/shared/helpers.ts | 13 +++++++ src/frontend/test/mocks.ts | 24 ++++++++++++- tests/unit/languageMatches.spec.ts | 36 +++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/unit/languageMatches.spec.ts diff --git a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue index 03f1c11b..abb3783c 100644 --- a/src/frontend/settings/languages/components/modals/bible-translations-modal.vue +++ b/src/frontend/settings/languages/components/modals/bible-translations-modal.vue @@ -18,7 +18,9 @@ v-else-if="currentBibleTranslations.length === 0" class="flex min-h-[160px] flex-col items-center justify-center gap-2 text-center" > - No Bible translations available for this language. + No Bible translations available for this language. [props.open, props.item] as const, ([isOpen, item]) => { if (isOpen && item) { - const filtered = shared.bibleTranslations.filter( - (v) => v.language === item.language, + const filtered = shared.bibleTranslations.filter((v) => + languageMatches(item.language, v.language), ); const current = filtered.find( (v) => @@ -191,7 +194,10 @@ const transformBibleVersions = ( }; const currentBibleTranslations = computed(() => { - return shared.bibleTranslations.filter((v) => v.language === props.item?.language); + const itemLanguage = props.item?.language ?? ''; + return shared.bibleTranslations.filter((v) => + languageMatches(itemLanguage, v.language), + ); }); onMounted(async () => { diff --git a/src/frontend/shared/helpers.ts b/src/frontend/shared/helpers.ts index 4b5d29c7..2e3042ed 100644 --- a/src/frontend/shared/helpers.ts +++ b/src/frontend/shared/helpers.ts @@ -34,6 +34,19 @@ export const expandShortcuts = (text: string) => { export const padZero = (value: number): string => (value > 9 ? `${value}` : `0${value}`); +/** + * Match stored language ("Arabic - عربى") with API language ("Arabic" or "Arabic, Sudanese Creole"). + * Extracts the base name before " - " and checks for exact match or API dialect (comma/space suffix). + */ +export const languageMatches = (stored: string, api: string): boolean => { + const storedBase = stored.split(' - ')[0].trim(); + return ( + api === storedBase || + api.startsWith(storedBase + ',') || + api.startsWith(storedBase + ' ') + ); +}; + export const formatDate = (value: string): string => { const d = new Date(value); return `${padZero(d.getDate())}/${padZero(d.getMonth() + 1)}/${padZero( diff --git a/src/frontend/test/mocks.ts b/src/frontend/test/mocks.ts index 0964de46..43f11788 100644 --- a/src/frontend/test/mocks.ts +++ b/src/frontend/test/mocks.ts @@ -675,7 +675,7 @@ export const languageTableItems: LanguageTableItem[] = [ ], }, { - language: 'Arabic', + language: 'Arabic - عربى', languageDirection: 'rtl', locale: 'ar', bibleLabel: 'Smith & Van Dyke', @@ -685,6 +685,28 @@ export const languageTableItems: LanguageTableItem[] = [ ], teamMembers: [], }, + { + language: 'Bengali - বাংলা', + languageDirection: 'ltr', + locale: 'bn', + bibleLabel: 'Bangla Bible', + translationProgress: [ + { name: 'Interface', done: 25, draft: 0, total: 100 }, + { name: 'Content', done: 50, draft: 0, total: 200 }, + ], + teamMembers: [], + }, + { + language: 'Chinese - 中文', + languageDirection: 'ltr', + locale: 'zh', + bibleLabel: 'Chinese Union Version', + translationProgress: [ + { name: 'Interface', done: 25, draft: 0, total: 100 }, + { name: 'Content', done: 50, draft: 0, total: 200 }, + ], + teamMembers: [], + }, { language: 'Portuguese', languageDirection: 'ltr', diff --git a/tests/unit/languageMatches.spec.ts b/tests/unit/languageMatches.spec.ts new file mode 100644 index 00000000..5743939c --- /dev/null +++ b/tests/unit/languageMatches.spec.ts @@ -0,0 +1,36 @@ +import { test, expect } from '@playwright/test'; + +import { languageMatches } from '../../src/frontend/shared/helpers'; + +test.describe('languageMatches', () => { + test('exact match when stored is base name only', () => { + expect(languageMatches('Bengali', 'Bengali')).toBe(true); + expect(languageMatches('English', 'English')).toBe(true); + }); + + test('match stored format with native script to API base name', () => { + expect(languageMatches('Bengali - বাংলা', 'Bengali')).toBe(true); + expect(languageMatches('Arabic - عربى', 'Arabic')).toBe(true); + expect(languageMatches('English - English', 'English')).toBe(true); + }); + + test('match stored format to API dialect with comma', () => { + expect(languageMatches('Arabic - عربى', 'Arabic, Sudanese Creole')).toBe(true); + }); + + test('match stored format to API variant with space', () => { + expect(languageMatches('Arabic - عربى', 'Arabic Standard')).toBe(true); + expect(languageMatches('English - English', 'English, US')).toBe(true); + }); + + test('reject non-matching languages', () => { + expect(languageMatches('Bengali - বাংলা', 'Arabic')).toBe(false); + expect(languageMatches('Arabic - عربى', 'Bengali')).toBe(false); + expect(languageMatches('English', 'French')).toBe(false); + }); + + test('reject partial prefix match to avoid false positives', () => { + expect(languageMatches('Arab - test', 'Arabic')).toBe(false); + expect(languageMatches('Eng - test', 'English')).toBe(false); + }); +}); From 43e3bb7e8ad511e0c2ef553cff6c71d7551078ce Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 08:22:48 +0300 Subject: [PATCH 58/99] refactor: enhance language table with active languages header and description --- .../languages/components/language-table.vue | 15 ++++++++++++--- .../modals/bible-translations-modal.vue | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/frontend/settings/languages/components/language-table.vue b/src/frontend/settings/languages/components/language-table.vue index f396cada..e679c0fa 100644 --- a/src/frontend/settings/languages/components/language-table.vue +++ b/src/frontend/settings/languages/components/language-table.vue @@ -1,4 +1,10 @@ diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index b7315324..ff7a6f9e 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -28,7 +28,10 @@ - +
    { }; const items = computed(() => props.languageItems ?? []); + +const handleBibleTranslationChange = ( + bibleVersionId: string, + bibleVersionName: string, +) => { + console.log('bible translation change', bibleVersionId, bibleVersionName); +}; diff --git a/src/frontend/shared/helpers.ts b/src/frontend/shared/helpers.ts index 2e3042ed..21b5bd6f 100644 --- a/src/frontend/shared/helpers.ts +++ b/src/frontend/shared/helpers.ts @@ -35,11 +35,12 @@ export const expandShortcuts = (text: string) => { export const padZero = (value: number): string => (value > 9 ? `${value}` : `0${value}`); /** - * Match stored language ("Arabic - عربى") with API language ("Arabic" or "Arabic, Sudanese Creole"). - * Extracts the base name before " - " and checks for exact match or API dialect (comma/space suffix). + * Match stored language to API language. + * Handles stored formats: "Bengali - বাংলা", "Arabic - عربى", "English | American". + * API returns: "Bengali", "Arabic, Sudanese Creole", "English". */ export const languageMatches = (stored: string, api: string): boolean => { - const storedBase = stored.split(' - ')[0].trim(); + const storedBase = stored.split(/\s*-\s*|\s*\|\s*/)[0].trim(); return ( api === storedBase || api.startsWith(storedBase + ',') || diff --git a/tests/unit/languageMatches.spec.ts b/tests/unit/languageMatches.spec.ts index 5743939c..3e396dee 100644 --- a/tests/unit/languageMatches.spec.ts +++ b/tests/unit/languageMatches.spec.ts @@ -14,6 +14,11 @@ test.describe('languageMatches', () => { expect(languageMatches('English - English', 'English')).toBe(true); }); + test('match stored format with pipe separator (e.g. source language)', () => { + expect(languageMatches('English | American', 'English')).toBe(true); + expect(languageMatches('English | American', 'English, American Standard')).toBe(true); + }); + test('match stored format to API dialect with comma', () => { expect(languageMatches('Arabic - عربى', 'Arabic, Sudanese Creole')).toBe(true); }); From 9b07b433ed912a6363916ec22e8c3abc033eb42f Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 08:32:02 +0300 Subject: [PATCH 60/99] refactor: adjust button size and streamline request language button in language list --- src/frontend/settings/languages/language-list.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/frontend/settings/languages/language-list.vue b/src/frontend/settings/languages/language-list.vue index 36a5a43a..eb62af38 100644 --- a/src/frontend/settings/languages/language-list.vue +++ b/src/frontend/settings/languages/language-list.vue @@ -5,7 +5,7 @@
  • From c6ffa1a72f54114197467fa3af5c8ccffbcea107 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 10:23:40 +0300 Subject: [PATCH 61/99] refactor: export language index template --- src/frontend/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/index.ts b/src/frontend/index.ts index c5c89165..c2cf5775 100644 --- a/src/frontend/index.ts +++ b/src/frontend/index.ts @@ -23,6 +23,7 @@ import ImageField from './fields/image-field.vue'; import IndexCard from './stories/components/index-card.vue'; import IndexFilter from './shared/index-filter.vue'; import LabelButton from './shared/label-button.vue'; +import LanguageIndex from './settings/languages/languages-index.vue'; import ListField from './fields/list-field.vue'; import ListSwitcher from './shared/list-switcher.vue'; import Login from './auth/login-index.vue'; @@ -91,6 +92,7 @@ export { IndexCard, IndexFilter, LabelButton, + LanguageIndex, ListField, ListSwitcher, Login, From 27f6cb22442f02d08a8ff360312ce7a41a05bf23 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 10:39:32 +0300 Subject: [PATCH 62/99] feat: add settings icon and link to sidebar --- src/frontend/shared/icon.vue | 16 ++++++++++++++++ src/frontend/shared/sidebar.vue | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/src/frontend/shared/icon.vue b/src/frontend/shared/icon.vue index 91c377f2..dd720265 100644 --- a/src/frontend/shared/icon.vue +++ b/src/frontend/shared/icon.vue @@ -11,6 +11,22 @@ + + + +
    + + + Settings + Team From 0244fd73a4853d0a263c9cda26b221ce2eb689d3 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 10:51:57 +0300 Subject: [PATCH 63/99] feat: conditionally display settings and team links in sidebar for admin users --- src/frontend/shared/sidebar.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/shared/sidebar.vue b/src/frontend/shared/sidebar.vue index 8e72615a..e3bd83dc 100644 --- a/src/frontend/shared/sidebar.vue +++ b/src/frontend/shared/sidebar.vue @@ -115,10 +115,15 @@
    - + Settings + Team From bb9a3a42e267541393e62618038fc7e8a26f9aa1 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 11:06:58 +0300 Subject: [PATCH 64/99] fix: correct import name from LanguageIndex to LanguagesIndex in index.ts --- src/frontend/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/index.ts b/src/frontend/index.ts index c2cf5775..e4086fcf 100644 --- a/src/frontend/index.ts +++ b/src/frontend/index.ts @@ -23,7 +23,7 @@ import ImageField from './fields/image-field.vue'; import IndexCard from './stories/components/index-card.vue'; import IndexFilter from './shared/index-filter.vue'; import LabelButton from './shared/label-button.vue'; -import LanguageIndex from './settings/languages/languages-index.vue'; +import LanguagesIndex from './settings/languages/languages-index.vue'; import ListField from './fields/list-field.vue'; import ListSwitcher from './shared/list-switcher.vue'; import Login from './auth/login-index.vue'; @@ -92,7 +92,7 @@ export { IndexCard, IndexFilter, LabelButton, - LanguageIndex, + LanguagesIndex, ListField, ListSwitcher, Login, From 180ee5d858ac7aec2f19694b773c40d2a66e5cde Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 11:24:10 +0300 Subject: [PATCH 65/99] ops: update package-lock.json --- package-lock.json | 424 +++++++++++++++++++++++++++------------------- 1 file changed, 254 insertions(+), 170 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb3798a5..ef04e068 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1448,11 +1448,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.4", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.8.tgz", + "integrity": "sha512-Ql8elcUdYCha83Ol7NznBsgN5GVZnv3vUd86fEc6waU6oUdY0T1O9NODkEEOS/Uaogr87avDrUC6DSeM4oXjZg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.3.4", + "@smithy/types": "^4.13.0", + "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" }, "engines": { @@ -2979,25 +2981,6 @@ "vue": "^3.0.0" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -3163,20 +3146,22 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor": { - "version": "7.56.2", + "version": "7.57.6", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.57.6.tgz", + "integrity": "sha512-0rFv/D8Grzw1Mjs2+8NGUR+o4h9LVm5zKRtMeWnpdB5IMJF4TeHCL1zR5LMCIudkOvyvjbhMG5Wjs0B5nqsrRQ==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.32.2", + "@microsoft/api-extractor-model": "7.33.4", "@microsoft/tsdoc": "~0.16.0", - "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.19.1", - "@rushstack/rig-package": "0.6.0", - "@rushstack/terminal": "0.21.0", - "@rushstack/ts-command-line": "5.2.0", + "@microsoft/tsdoc-config": "~0.18.1", + "@rushstack/node-core-library": "5.20.3", + "@rushstack/rig-package": "0.7.2", + "@rushstack/terminal": "0.22.3", + "@rushstack/ts-command-line": "5.3.3", "diff": "~8.0.2", - "lodash": "~4.17.15", - "minimatch": "10.1.2", + "lodash": "~4.17.23", + "minimatch": "10.2.1", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", @@ -3187,13 +3172,38 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.32.2", + "version": "7.33.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.33.4.tgz", + "integrity": "sha512-u1LTaNTikZAQ9uK6KG1Ms7nvNedsnODnspq/gH2dcyETWvH4hVNGNDvRAEutH66kAmxA4/necElqGNs1FggC8w==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.16.0", - "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.19.1" + "@microsoft/tsdoc-config": "~0.18.1", + "@rushstack/node-core-library": "5.20.3" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@microsoft/api-extractor/node_modules/diff": { @@ -3216,11 +3226,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/minimatch": { - "version": "10.1.2", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" @@ -3265,29 +3277,35 @@ }, "node_modules/@microsoft/tsdoc": { "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "dev": true, "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { - "version": "0.18.0", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.1.tgz", + "integrity": "sha512-9brPoVdfN9k9g0dcWkFeA7IH9bbcttzDJlXvkf8b2OBzd5MueR1V2wkKBL0abn0otvmkHJC6aapBOTJDDeMCZg==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.16.0", - "ajv": "~8.12.0", + "ajv": "~8.18.0", "jju": "~1.4.0", "resolve": "~1.22.2" } }, "node_modules/@microsoft/tsdoc-config/node_modules/ajv": { - "version": "8.12.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3296,6 +3314,8 @@ }, "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -3658,9 +3678,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", - "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ "arm" ], @@ -3672,9 +3692,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", - "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ "arm64" ], @@ -3686,7 +3706,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.57.1", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], @@ -3698,9 +3720,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", - "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -3712,9 +3734,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", - "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -3726,9 +3748,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", - "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ "x64" ], @@ -3740,9 +3762,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", - "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ "arm" ], @@ -3754,9 +3776,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", - "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ "arm" ], @@ -3768,9 +3790,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", - "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -3782,9 +3804,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", - "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", "cpu": [ "arm64" ], @@ -3796,9 +3818,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", - "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", "cpu": [ "loong64" ], @@ -3810,9 +3832,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", - "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", "cpu": [ "loong64" ], @@ -3824,9 +3846,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", - "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", "cpu": [ "ppc64" ], @@ -3838,9 +3860,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", - "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", "cpu": [ "ppc64" ], @@ -3852,9 +3874,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", - "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", "cpu": [ "riscv64" ], @@ -3866,9 +3888,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", - "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", "cpu": [ "riscv64" ], @@ -3880,9 +3902,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", - "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", "cpu": [ "s390x" ], @@ -3894,9 +3916,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", - "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], @@ -3907,9 +3929,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", - "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", "cpu": [ "x64" ], @@ -3921,9 +3943,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", - "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", "cpu": [ "x64" ], @@ -3935,9 +3957,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", - "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", "cpu": [ "arm64" ], @@ -3949,9 +3971,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", - "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", "cpu": [ "arm64" ], @@ -3963,9 +3985,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", - "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", "cpu": [ "ia32" ], @@ -3977,9 +3999,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", - "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", "cpu": [ "x64" ], @@ -3991,9 +4013,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", - "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", "cpu": [ "x64" ], @@ -4005,11 +4027,13 @@ ] }, "node_modules/@rushstack/node-core-library": { - "version": "5.19.1", + "version": "5.20.3", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", + "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "~8.13.0", + "ajv": "~8.18.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~11.3.0", @@ -4028,14 +4052,16 @@ } }, "node_modules/@rushstack/node-core-library/node_modules/ajv": { - "version": "8.13.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4044,6 +4070,8 @@ }, "node_modules/@rushstack/node-core-library/node_modules/ajv-draft-04": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -4057,11 +4085,15 @@ }, "node_modules/@rushstack/node-core-library/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "license": "ISC", "dependencies": { @@ -4073,6 +4105,8 @@ }, "node_modules/@rushstack/node-core-library/node_modules/semver": { "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "license": "ISC", "dependencies": { @@ -4086,7 +4120,9 @@ } }, "node_modules/@rushstack/problem-matcher": { - "version": "0.1.1", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.2.1.tgz", + "integrity": "sha512-gulfhBs6n+I5b7DvjKRfhMGyUejtSgOHTclF/eONr8hcgF1APEDjhxIsfdUYYMzC3rvLwGluqLjbwCFZ8nxrog==", "dev": true, "license": "MIT", "peerDependencies": { @@ -4099,7 +4135,9 @@ } }, "node_modules/@rushstack/rig-package": { - "version": "0.6.0", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.7.2.tgz", + "integrity": "sha512-9XbFWuqMYcHUso4mnETfhGVUSaADBRj6HUAAEYk50nMPn8WRICmBuCphycQGNB3duIR6EEZX3Xj3SYc2XiP+9A==", "dev": true, "license": "MIT", "dependencies": { @@ -4108,12 +4146,14 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.21.0", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.22.3.tgz", + "integrity": "sha512-gHC9pIMrUPzAbBiI4VZMU7Q+rsCzb8hJl36lFIulIzoceKotyKL3Rd76AZ2CryCTKEg+0bnTj406HE5YY5OQvw==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.19.1", - "@rushstack/problem-matcher": "0.1.1", + "@rushstack/node-core-library": "5.20.3", + "@rushstack/problem-matcher": "0.2.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -4127,6 +4167,8 @@ }, "node_modules/@rushstack/terminal/node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4140,11 +4182,13 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "5.2.0", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.3.tgz", + "integrity": "sha512-c+ltdcvC7ym+10lhwR/vWiOhsrm/bP3By2VsFcs5qTKv+6tTmxgbVrtJ5NdNjANiV5TcmOZgUN+5KYQ4llsvEw==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.21.0", + "@rushstack/terminal": "0.22.3", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -4152,6 +4196,8 @@ }, "node_modules/@rushstack/ts-command-line/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -4662,7 +4708,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.12.0", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", + "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -5172,6 +5220,8 @@ }, "node_modules/@types/argparse": { "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true, "license": "MIT" }, @@ -5566,11 +5616,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5813,11 +5865,13 @@ } }, "node_modules/@vue/language-core/node_modules/minimatch": { - "version": "9.0.5", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -6001,7 +6055,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -6017,6 +6073,8 @@ }, "node_modules/ajv-formats": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6032,7 +6090,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -6048,6 +6108,8 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -6201,11 +6263,13 @@ } }, "node_modules/axios": { - "version": "1.13.4", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -7730,6 +7794,8 @@ }, "node_modules/fast-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -7744,7 +7810,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-parser": { - "version": "5.3.4", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", + "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", "funding": [ { "type": "github", @@ -7753,7 +7821,7 @@ ], "license": "MIT", "dependencies": { - "strnum": "^2.1.0" + "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -8857,6 +8925,8 @@ }, "node_modules/import-lazy": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, "license": "MIT", "engines": { @@ -9063,6 +9133,8 @@ }, "node_modules/jju": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", "dev": true, "license": "MIT" }, @@ -9676,7 +9748,9 @@ "license": "ISC" }, "node_modules/markdown-it": { - "version": "14.1.0", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, "license": "MIT", "dependencies": { @@ -9941,7 +10015,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11019,7 +11095,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -11308,11 +11386,13 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.5", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -11322,7 +11402,9 @@ } }, "node_modules/rollup": { - "version": "4.57.1", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { @@ -11336,31 +11418,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.1", - "@rollup/rollup-android-arm64": "4.57.1", - "@rollup/rollup-darwin-arm64": "4.57.1", - "@rollup/rollup-darwin-x64": "4.57.1", - "@rollup/rollup-freebsd-arm64": "4.57.1", - "@rollup/rollup-freebsd-x64": "4.57.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", - "@rollup/rollup-linux-arm-musleabihf": "4.57.1", - "@rollup/rollup-linux-arm64-gnu": "4.57.1", - "@rollup/rollup-linux-arm64-musl": "4.57.1", - "@rollup/rollup-linux-loong64-gnu": "4.57.1", - "@rollup/rollup-linux-loong64-musl": "4.57.1", - "@rollup/rollup-linux-ppc64-gnu": "4.57.1", - "@rollup/rollup-linux-ppc64-musl": "4.57.1", - "@rollup/rollup-linux-riscv64-gnu": "4.57.1", - "@rollup/rollup-linux-riscv64-musl": "4.57.1", - "@rollup/rollup-linux-s390x-gnu": "4.57.1", - "@rollup/rollup-linux-x64-gnu": "4.57.1", - "@rollup/rollup-linux-x64-musl": "4.57.1", - "@rollup/rollup-openbsd-x64": "4.57.1", - "@rollup/rollup-openharmony-arm64": "4.57.1", - "@rollup/rollup-win32-arm64-msvc": "4.57.1", - "@rollup/rollup-win32-ia32-msvc": "4.57.1", - "@rollup/rollup-win32-x64-gnu": "4.57.1", - "@rollup/rollup-win32-x64-msvc": "4.57.1", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, @@ -11772,6 +11854,8 @@ }, "node_modules/string-argv": { "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "license": "MIT", "engines": { From 30b7f4e2ad4d0f5c1b8dbe3b6a7ea21842523009 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 11:53:22 +0300 Subject: [PATCH 66/99] fix: update button click handler to use dynamic locale in languages index --- src/frontend/settings/languages/languages-index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/settings/languages/languages-index.vue b/src/frontend/settings/languages/languages-index.vue index ff7a6f9e..0e72007a 100644 --- a/src/frontend/settings/languages/languages-index.vue +++ b/src/frontend/settings/languages/languages-index.vue @@ -20,7 +20,7 @@ From 9cb35f7cc1c038a91de27608ceace0487ae22f21 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 13:15:46 +0300 Subject: [PATCH 67/99] feat: add LanguagesEdit component to index export --- src/frontend/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/index.ts b/src/frontend/index.ts index e4086fcf..890e58b4 100644 --- a/src/frontend/index.ts +++ b/src/frontend/index.ts @@ -23,6 +23,7 @@ import ImageField from './fields/image-field.vue'; import IndexCard from './stories/components/index-card.vue'; import IndexFilter from './shared/index-filter.vue'; import LabelButton from './shared/label-button.vue'; +import LanguagesEdit from './settings/languages/languages-edit.vue'; import LanguagesIndex from './settings/languages/languages-index.vue'; import ListField from './fields/list-field.vue'; import ListSwitcher from './shared/list-switcher.vue'; @@ -92,6 +93,7 @@ export { IndexCard, IndexFilter, LabelButton, + LanguagesEdit, LanguagesIndex, ListField, ListSwitcher, From fa3edf77c3a4e2d781ddb2b20a0b6afd208b7168 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 4 Mar 2026 13:39:22 +0300 Subject: [PATCH 68/99] feat: introduce LanguagesEditProps interface and update LanguagesEdit component to utilize shared props --- .../settings/languages/languages-edit.story.vue | 15 +++++++++++++-- .../settings/languages/languages-edit.vue | 17 +++++++++++++---- src/types.ts | 4 ++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/frontend/settings/languages/languages-edit.story.vue b/src/frontend/settings/languages/languages-edit.story.vue index a3a6aed2..67a6a9e8 100644 --- a/src/frontend/settings/languages/languages-edit.story.vue +++ b/src/frontend/settings/languages/languages-edit.story.vue @@ -1,14 +1,25 @@ diff --git a/src/types.ts b/src/types.ts index 0287d1e4..20451d11 100644 --- a/src/types.ts +++ b/src/types.ts @@ -594,3 +594,8 @@ export interface LanguagesProps { export interface LanguagesEditProps { addedLanguages: LanguageSpecification[]; } + +export interface LanguageListItemProps { + language: LanguageSpecification; + status: 'selected' | 'added'; +} From 30af455ff5a7d11e1c7bf6b73d2c23cc663cf966 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Tue, 17 Mar 2026 11:55:02 +0300 Subject: [PATCH 74/99] refactor: update LanguageList component to use status prop and simplify props structure --- .../settings/languages/language-list.story.vue | 17 ++++++++--------- .../settings/languages/language-list.vue | 17 ++++------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/frontend/settings/languages/language-list.story.vue b/src/frontend/settings/languages/language-list.story.vue index 81bf4599..44617e24 100644 --- a/src/frontend/settings/languages/language-list.story.vue +++ b/src/frontend/settings/languages/language-list.story.vue @@ -1,20 +1,19 @@ diff --git a/src/frontend/settings/languages/language-list.vue b/src/frontend/settings/languages/language-list.vue index 15ba7128..505ca87d 100644 --- a/src/frontend/settings/languages/language-list.vue +++ b/src/frontend/settings/languages/language-list.vue @@ -38,8 +38,7 @@ v-for="item in filteredItems" :key="item.language.locale" :language="item.language" - :is-selected="item.isSelected" - :is-added="item.isAdded" + :status="item.status" class="w-full" @update="(isSelected) => emit('update', item.language.locale, isSelected)" /> @@ -76,14 +75,12 @@ From 102c653e1344f0c4685144dbce2e6e45d5856498 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 18 Mar 2026 09:04:11 +0300 Subject: [PATCH 78/99] refactor: enhance availableLanguageItems and addedLanguageItems computations to utilize LanguageListItemProps and update status handling --- .../settings/languages/languages-edit.vue | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/frontend/settings/languages/languages-edit.vue b/src/frontend/settings/languages/languages-edit.vue index c77e6375..d3e0f1bb 100644 --- a/src/frontend/settings/languages/languages-edit.vue +++ b/src/frontend/settings/languages/languages-edit.vue @@ -77,6 +77,7 @@ import PillButton from '../../shared/pill-button.vue'; import LanguageList from './language-list.vue'; import LanguageAddModal from './components/language-add-modal.vue'; import type { + LanguageListItemProps, LanguageSpecification, LanguagesEditProps, SharedPageProps, @@ -98,13 +99,12 @@ const emit = defineEmits<{ const selectedLocales = ref>(new Set()); -const availableLanguageItems = computed(() => +const availableLanguageItems = computed((): LanguageListItemProps[] => allLanguages .filter((language: LanguageSpecification) => !props.addedLanguages.includes(language)) - .map((language: LanguageSpecification) => ({ + .map((language: LanguageSpecification): LanguageListItemProps => ({ language, - isSelected: selectedLocales.value.has(language.locale), - isAdded: false, + status: selectedLocales.value.has(language.locale) ? 'selected' : 'available', })), ); @@ -119,11 +119,10 @@ const handleSelectionUpdate = (locale: string, isSelected: boolean) => { selectedLocales.value = next; }; -const addedLanguageItems = computed(() => - props.addedLanguages.map((language: LanguageSpecification) => ({ +const addedLanguageItems = computed((): LanguageListItemProps[] => + props.addedLanguages.map((language: LanguageSpecification): LanguageListItemProps => ({ language, - isSelected: false, - isAdded: true, + status: 'readonly', })), ); From d60094398ccb87430c49114675340d3311340d46 Mon Sep 17 00:00:00 2001 From: Timothy Koech Date: Wed, 18 Mar 2026 09:11:32 +0300 Subject: [PATCH 79/99] refactor: update language-list-item component to toggle checkbox visibility based on 'readonly' status --- .../settings/languages/components/language-list-item.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/settings/languages/components/language-list-item.vue b/src/frontend/settings/languages/components/language-list-item.vue index d50de88f..6375f112 100644 --- a/src/frontend/settings/languages/components/language-list-item.vue +++ b/src/frontend/settings/languages/components/language-list-item.vue @@ -9,7 +9,7 @@ >
    -