-
Notifications
You must be signed in to change notification settings - Fork 0
Sco 1753 language UI #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
timosville
wants to merge
100
commits into
main
Choose a base branch
from
sco-1753-language-ui
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Sco 1753 language UI #105
Changes from all commits
Commits
Show all changes
100 commits
Select commit
Hold shift + click to select a range
8472ff9
feat: add settings section and languages index component
timosville 24e888d
feat: add source language component for language settings
timosville ea16b36
feat: implement language management interface with actions and table …
timosville 8889251
feat: add RingBlock component and story for dashboard progress visual…
timosville a8192a4
feat: extend LanguageSpecification and update translation progress ha…
timosville a8d716c
refactor: simplify LanguageSpecification and update SourceLang compon…
timosville 38378d6
fix: remove extraneous closing tag in languages-index.vue
timosville 502f553
refactor: update type definitions in lang-table story to use TableItem
timosville 5f51157
feat: introduce LangStrip component for language display and update l…
timosville d6744c8
refactor: update lang-table components to use LanguageTableItem and r…
timosville 26b8479
feat: enhance lang-table with action buttons for team management and …
timosville 534caad
fix: adjust positioning of dropdown menu in lang-table component for …
timosville c228305
feat: implement toggle functionality for action buttons in lang-table…
timosville 95dd533
refactor: update action button functionality in lang-table component …
timosville 5d9d7c4
feat: add source-language component and update related components for…
timosville 1e440a9
feat: add LanguagesProps interface and update language components to …
timosville 455c238
feat: enhance language display by adding truncation for bibleLabel an…
timosville 83066c2
feat: add LanguagesEdit component and corresponding story for languag…
timosville 7730b9c
feat: add language list component and corresponding story for languag…
timosville 713a573
feat: add LanguageListItem component with story for showcasing langua…
timosville a2caae2
feat: add .cursorignore file to exclude .env from cursor operations
timosville b741089
feat: enhance language list stories and update language-list-item com…
timosville 4def133
feat: update language-list-item component to improve background color…
timosville aa13220
feat: add interactive variant to language-list-item story for enhance…
timosville e77494b
feat: refactor language list component to utilize items prop and enha…
timosville 94f5698
feat: add search and letter filter
timosville a92844a
feat: improve language selection interface with dynamic updates and e…
timosville bfbcbb5
feat: update language list button styles for improved accessibility a…
timosville 9c1cbdd
refactor: handle second click
timosville dae0a1c
feat: sort language list items for improved organization and user exp…
timosville 0bbf2e8
feat: enhance language list layout with additional padding and update…
timosville ad7cb7b
feat: add Language Add Modal component with story for language select…
timosville ddd3057
refactor: add language modal in edit page
timosville 0b3065d
refactor: replace button components with PillButton for consistent st…
timosville 7447891
refactor: update Languages Index component with new button actions an…
timosville 8ae6beb
refactor: integrate LanguageModal for language removal and request de…
timosville 876bc36
feat: add Request App Update modal component and integrate it into La…
timosville 5a767d0
feat: add Request Feedback Modal component and integrate it into Lang…
timosville 030c836
feat: add mailFromAddress to CmsMeta and integrate it into Request Fe…
timosville b92f4c0
refactor: remove simulated API call in submitAppUpdateRequest and add…
timosville b9e41dc
refactor: restructure LanguageSpecification to extend BibleSpecificat…
timosville eb89b0c
refactor: add change modal
timosville 13a8591
refactor: change name of function
timosville 8b1f2c9
refactor: replace LanguageModal with dedicated modals for language re…
timosville 93dcdca
refactor: update Bible translations modal to use new BibleVersion str…
timosville d4639ce
refactor: streamline Bible translations handling by integrating API c…
timosville dded727
refactor: define APIBibleVersion type for improved type safety in get…
timosville ecafc2b
refactor: update transformBibleVersions function to utilize APIBibleV…
timosville 0dfd23a
refator: add loading state
timosville 02b2253
refactor: enhance Bible translations modal with error handling and lo…
timosville 22a08b0
refactor: update transformBibleVersions function to return an array o…
timosville 45988e4
refactor: simplify BibleVersion type and enhance default selection lo…
timosville 43b58c1
refactor: improve error handling in Bible translations modal by displ…
timosville 40fb667
refactor: filter languages based on the prop
timosville 47946b0
refactor: add no translations available message and update button sta…
timosville eceaccb
refactor: optimize loading logic in Bible translations modal to preve…
timosville e324051
refactor: implement language matching logic to enhance Bible translat…
timosville 43e3bb7
refactor: enhance language table with active languages header and des…
timosville 1ea842d
refactor: integrate Bible translations modal
timosville 9b07b43
refactor: adjust button size and streamline request language button i…
timosville c6ffa1a
refactor: export language index template
timosville 27f6cb2
feat: add settings icon and link to sidebar
timosville 0244fd7
feat: conditionally display settings and team links in sidebar for ad…
timosville bb9a3a4
fix: correct import name from LanguageIndex to LanguagesIndex in inde…
timosville 180ee5d
ops: update package-lock.json
timosville 30b7f4e
fix: update button click handler to use dynamic locale in languages i…
timosville 9cb35f7
feat: add LanguagesEdit component to index export
timosville fa3edf7
feat: introduce LanguagesEditProps interface and update LanguagesEdit…
timosville 2cbc666
refactor: remove white background
timosville 6e24410
refactor: change layout from flex to grid for language list item
timosville bdfb951
feat: conditionally render pagination component based on items length…
timosville 013bc51
refactor: adjust size of the ring block component
timosville fb87ddd
feat: add LanguageListItemProps interface and update language-list-it…
timosville 30af455
refactor: update LanguageList component to use status prop and simpli…
timosville 7fb25f6
refactor: update LanguageListItemProps to include 'readonly' and 'ava…
timosville 21f162e
refactor: update props structure in language-list component to correc…
timosville d8de96a
refactor: update status assignment in language-list component to incl…
timosville 102c653
refactor: enhance availableLanguageItems and addedLanguageItems compu…
timosville d600943
refactor: update language-list-item component to toggle checkbox visi…
timosville 7dd585f
feat: introduce SettingsIndex component and update import paths for s…
timosville 4c94234
refactor: move templates
timosville 238a78c
refactor: replace bibleVersionId with bibleVersion across components …
timosville a711f33
refactor: rename LanguagesProps to SettingsPageProps and update relat…
timosville dfdb482
refactor: improve code readability in languages-edit component by for…
timosville c64cd62
refactor: streamline language selection logic in languages-edit compo…
timosville e1bce09
ops: audit fix
timosville 1ebc9d5
refactor: update import and export for SettingsIndex component in ind…
timosville 5d4eb09
feat: add RequestFeedbackModal import to settings-index component
timosville 0024f6e
feat: add providers prop to SettingsPageProps and integrate with widg…
timosville b7930d2
feat:add feedback message
timosville 044be6f
feat: add BibleTranslationsModal story with multiple variants for lan…
timosville 1cf94c5
feat: update SettingsIndex story to use setupSettings and add provide…
timosville 8348e90
feat: add event handler for Bible translation change in settings-inde…
timosville 696aca6
feat: enhance settings-index component with shared state for source l…
timosville 2e81fd7
feat: implement language removal functionality in settings-index comp…
timosville c37d69c
feat: add confirmation message for added languages in languages-edit …
timosville ac53dc2
feat: save languages
timosville 70373dd
feat: refactor Bible translation change handlers in settings-index co…
timosville 5eed30c
Merge branch 'main' into sco-1753-language-ui
timosville 1b28bc3
ops: update lock file
timosville File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| .env |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| <template> | ||
| <Story title="Ring block" group="dashboard" :layout="{ type: 'grid', width: 350 }"> | ||
| <Variant title="Incomplete"> | ||
| <div class="bg-white p-8"> | ||
| <RingBlock | ||
| :progress="[ | ||
| { name: 'Interface', done: 75, draft: 0, total: 100 }, | ||
| { name: 'Content', done: 100, draft: 20, total: 100 }, | ||
| ]" | ||
| /> | ||
| </div> | ||
| </Variant> | ||
|
|
||
| <Variant title="All done"> | ||
| <div class="bg-white p-8"> | ||
| <RingBlock | ||
| :progress="[ | ||
| { name: 'Interface', done: 100, draft: 50, total: 100 }, | ||
| { name: 'Content', done: 300, draft: 10, total: 300 }, | ||
| ]" | ||
| /> | ||
| </div> | ||
| </Variant> | ||
|
|
||
| <Variant title="Not started"> | ||
| <div class="bg-white p-8"> | ||
| <RingBlock | ||
| :progress="[ | ||
| { name: 'Interface', done: 0, draft: 0, total: 100 }, | ||
| { name: 'Content', done: 0, draft: 0, total: 300 }, | ||
| ]" | ||
| /> | ||
| </div> | ||
| </Variant> | ||
|
|
||
| <Variant title="In progress"> | ||
| <div class="bg-white p-8"> | ||
| <RingBlock | ||
| :progress="[ | ||
| { name: 'Interface', done: 50, draft: 10, total: 100 }, | ||
| { name: 'Content', done: 150, draft: 0, total: 300 }, | ||
| ]" | ||
| /> | ||
| </div> | ||
| </Variant> | ||
| </Story> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import RingBlock from './ring-block.vue'; | ||
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| <template> | ||
| <div class="flex flex-col items-center text-gray-500"> | ||
| <template v-if="hasCompleteRings"> | ||
| <div class="relative mx-auto size-20 rounded-full border-[3px] border-teal-500"> | ||
| <div class="absolute inset-0 flex items-center justify-center"> | ||
| <Icon name="check-large" class="h-auto w-6 text-teal-500" /> | ||
| </div> | ||
| </div> | ||
| <p class="mt-2 text-center text-xs font-medium leading-4">All done</p> | ||
| </template> | ||
| <template v-else> | ||
| <div class="flex justify-between gap-8"> | ||
| <div v-for="item in ringData" :key="item.name" class="flex flex-col items-center"> | ||
| <p class="mb-2 text-center text-sm font-medium leading-4"> | ||
| {{ item.name }} | ||
| </p> | ||
| <div class="relative flex flex-col items-center justify-center"> | ||
| <svg | ||
| v-if="item.label !== ''" | ||
| class="-rotate-90" | ||
| :height="circleWidth" | ||
| :width="circleWidth" | ||
| > | ||
| <circle | ||
| class="fill-transparent stroke-teal-500 stroke-[6px]" | ||
| stroke="currentColor" | ||
| :r="circleRadius" | ||
| :cx="center" | ||
| :cy="center" | ||
| :stroke-dasharray="`${item.tealSegment} ${circumference}`" | ||
| stroke-dashoffset="0" | ||
| /> | ||
| <circle | ||
| class="fill-transparent stroke-blue-500 stroke-[6px]" | ||
| stroke="currentColor" | ||
| :r="circleRadius" | ||
| :cx="center" | ||
| :cy="center" | ||
| :stroke-dasharray="`${item.blueSegment} ${circumference}`" | ||
| :stroke-dashoffset="`-${item.tealSegment}`" | ||
| /> | ||
| <circle | ||
| class="fill-transparent stroke-gray-200 stroke-[6px]" | ||
| stroke="currentColor" | ||
| :r="circleRadius" | ||
| :cx="center" | ||
| :cy="center" | ||
| :stroke-dasharray="`${item.unfilledSegment} ${circumference}`" | ||
| :stroke-dashoffset="`-${item.tealSegment + item.blueSegment}`" | ||
| /> | ||
| </svg> | ||
| <div class="absolute inset-0 flex items-center justify-center"> | ||
| <div v-if="item.donePercentage === 100 && item.draftPercentage === 0"> | ||
| <Icon name="check" class="h-auto w-4 text-teal-500" /> | ||
| </div> | ||
| <span v-else class="text-sm font-bold leading-none text-gray-800"> | ||
| {{ item.label }} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </template> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import { computed } from 'vue'; | ||
| import Icon from '../shared/icon.vue'; | ||
| import type { Progress } from '../../types'; | ||
|
|
||
| const props = defineProps<{ progress: Omit<Progress, 'lastUpdated'>[] }>(); | ||
|
|
||
| const hasCompleteRings = computed(() => { | ||
| return props.progress.every((stat) => stat.done === stat.total); | ||
| }); | ||
|
|
||
| const circleWidth = 80; | ||
| const center = circleWidth / 2; | ||
| const circleRadius = circleWidth / 2 - 6; | ||
| const circumference = 2 * Math.PI * circleRadius; | ||
|
|
||
| function computeRingData(item: Omit<Progress, 'lastUpdated'>) { | ||
| const isOverdone = item.done + item.draft > item.total; | ||
| const workingDone = isOverdone | ||
| ? item.done - (item.done + item.draft - item.total) | ||
| : item.done; | ||
| const donePercentage = | ||
| item.total === 0 ? 0 : Math.round((workingDone / item.total) * 100); | ||
| const draftPercentage = | ||
| item.total === 0 ? 0 : Math.round((item.draft / item.total) * 100); | ||
| const unfilledPercentage = 100 - (donePercentage + draftPercentage); | ||
|
|
||
| let label = ''; | ||
| const nr = donePercentage + draftPercentage; | ||
| if (!isNaN(nr)) { | ||
| label = nr > 100 ? '100%' : `${nr}%`; | ||
| } | ||
|
|
||
| const tealSegment = circumference * (donePercentage / 100); | ||
| const blueSegment = circumference * (draftPercentage / 100); | ||
| const unfilledSegment = circumference * (unfilledPercentage / 100); | ||
|
|
||
| return { | ||
| name: item.name, | ||
| label, | ||
| donePercentage, | ||
| draftPercentage, | ||
| tealSegment, | ||
| blueSegment, | ||
| unfilledSegment, | ||
| }; | ||
| } | ||
|
|
||
| const ringData = computed(() => props.progress.map(computeRingData)); | ||
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
src/frontend/settings/languages/components/bible-translations-modal.story.vue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| <template> | ||
| <Story title="Bible Translations Modal" group="settings"> | ||
| <Variant title="With translations" :setup-app="setupWithTranslations"> | ||
| <button | ||
| class="rounded bg-blue-500 px-4 py-2 text-white" | ||
| @click="showModal = true" | ||
| > | ||
| Choose Bible translation | ||
| </button> | ||
| <BibleTranslationsModal | ||
| :open="showModal" | ||
| :item="englishItem" | ||
| @close="showModal = false" | ||
| @confirm="onConfirm" | ||
| /> | ||
| </Variant> | ||
| <Variant title="No translations for language" :setup-app="setupWithTranslations"> | ||
| <button | ||
| class="rounded bg-blue-500 px-4 py-2 text-white" | ||
| @click="showEmptyModal = true" | ||
| > | ||
| Choose Bible translation | ||
| </button> | ||
| <BibleTranslationsModal | ||
| :open="showEmptyModal" | ||
| :item="obscureLanguageItem" | ||
| @close="showEmptyModal = false" | ||
| @confirm="onConfirm" | ||
| /> | ||
| </Variant> | ||
| <Variant title="Multiple versions" :setup-app="setupWithMultipleVersions"> | ||
| <button | ||
| class="rounded bg-blue-500 px-4 py-2 text-white" | ||
| @click="showMultipleModal = true" | ||
| > | ||
| Choose Bible translation | ||
| </button> | ||
| <BibleTranslationsModal | ||
| :open="showMultipleModal" | ||
| :item="spanishItem" | ||
| @close="showMultipleModal = false" | ||
| @confirm="onConfirm" | ||
| /> | ||
| </Variant> | ||
| </Story> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import { ref } from 'vue'; | ||
| import BibleTranslationsModal from './bible-translations-modal.vue'; | ||
| import { useSharedStore, useWidgetsStore } from '../../../store'; | ||
| import type { StoryHandler } from '../../../shared/helpers'; | ||
| import type { LanguageTableItem } from '../../../../types'; | ||
|
|
||
| const showModal = ref(false); | ||
| const showEmptyModal = ref(false); | ||
| const showMultipleModal = ref(false); | ||
|
|
||
| const englishItem: LanguageTableItem = { | ||
| language: 'English', | ||
| languageDirection: 'ltr', | ||
| locale: 'en', | ||
| bibleVersion: 'de4e12af7f28f599-01', | ||
| bibleLabel: '(KJV) King James Version', | ||
| }; | ||
|
|
||
| const obscureLanguageItem: LanguageTableItem = { | ||
| language: 'Klingon', | ||
| languageDirection: 'ltr', | ||
| locale: 'tlh', | ||
| }; | ||
|
|
||
| const spanishItem: LanguageTableItem = { | ||
| language: 'Spanish', | ||
| languageDirection: 'ltr', | ||
| locale: 'es', | ||
| bibleVersion: '592420522e16049f-01', | ||
| bibleLabel: '(RVR1960) Reina-Valera 1960', | ||
| }; | ||
|
|
||
| const mockEnglishTranslations = [ | ||
| { | ||
| language: 'English', | ||
| bibleVersion: 'de4e12af7f28f599-01', | ||
| bibleLabel: '(KJV) King James Version', | ||
| }, | ||
| { | ||
| language: 'English', | ||
| bibleVersion: '9879dbb7cfe39e4d-01', | ||
| bibleLabel: '(ERV) Easy-to-Read Version', | ||
| }, | ||
| { | ||
| language: 'English', | ||
| bibleVersion: 'abc123-01', | ||
| bibleLabel: '(ESV) English Standard Version', | ||
| }, | ||
| ]; | ||
|
|
||
| const mockTranslationsWithMultiple = [ | ||
| ...mockEnglishTranslations, | ||
| { | ||
| language: 'Spanish', | ||
| bibleVersion: '592420522e16049f-01', | ||
| bibleLabel: '(RVR1960) Reina-Valera 1960', | ||
| }, | ||
| { | ||
| language: 'Spanish', | ||
| bibleVersion: 'spa002-01', | ||
| bibleLabel: '(NTV) Nueva Traducción Viviente', | ||
| }, | ||
| { language: 'Spanish', bibleVersion: 'spa003-01', bibleLabel: '(DHH) Dios Habla Hoy' }, | ||
| ]; | ||
|
|
||
| const setupWithTranslations: StoryHandler = () => { | ||
| const shared = useSharedStore(); | ||
| const widgets = useWidgetsStore(); | ||
| shared.setBibleTranslations(mockEnglishTranslations); | ||
| widgets.setProviders({ | ||
| ...widgets.providers, | ||
| scripture: { bibleApiKey: 'mock-key-for-story' }, | ||
| }); | ||
| }; | ||
|
|
||
| const setupWithMultipleVersions: StoryHandler = () => { | ||
| const shared = useSharedStore(); | ||
| const widgets = useWidgetsStore(); | ||
| shared.setBibleTranslations(mockTranslationsWithMultiple); | ||
| widgets.setProviders({ | ||
| ...widgets.providers, | ||
| scripture: { bibleApiKey: 'mock-key-for-story' }, | ||
| }); | ||
| }; | ||
|
|
||
| const onConfirm = (bibleVersion: string, bibleVersionName: string) => { | ||
| alert(`Confirmed: ${bibleVersionName} (${bibleVersion})`); | ||
| }; | ||
| </script> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.