From 2e5a6b7487a396662aeeaf15a427abf4bfb6ae24 Mon Sep 17 00:00:00 2001 From: Katherine Jensen Date: Wed, 21 Aug 2024 15:14:38 -0700 Subject: [PATCH 01/11] Switching Computers Partial Commit --- assets/localization/en.json | 8 + .../contributions/localizedStrings.json | 30 ++- .../src/web-views/hello-world.web-view.tsx | 165 ++++++++++++---- .../contributions/localizedStrings.json | 3 + .../src/platform-scripture-editor/src/main.ts | 24 ++- .../basic-list/basic-list.component.tsx | 181 +++++++++++------- 6 files changed, 306 insertions(+), 105 deletions(-) diff --git a/assets/localization/en.json b/assets/localization/en.json index 19468d5a19..d04eafb75c 100644 --- a/assets/localization/en.json +++ b/assets/localization/en.json @@ -1,5 +1,13 @@ { "%product_name%": "Platform.Bible", + "%basicList_basicList%": "Basic List", + "%basicList_Chapter%": "Chapter", + "%basicList_Description%": "Description", + "%basicList_issueDescription%": "Basic check issue description", + "%basicList_issue%": "Issue", + "%basicList_issues%": "issues", + "%basicList_scriptureReference%": "Scripture reference", + "%basicList_Verse%": "Verse", "%insertNote%": "Insert Note", "%mainMenu_aboutPlatformBible%": "About Platform.Bible", "%mainMenu_downloadSlashInstallResources%": "Download/Install Resources", diff --git a/extensions/src/hello-world/contributions/localizedStrings.json b/extensions/src/hello-world/contributions/localizedStrings.json index 2e907918ab..20feb57137 100644 --- a/extensions/src/hello-world/contributions/localizedStrings.json +++ b/extensions/src/hello-world/contributions/localizedStrings.json @@ -13,10 +13,36 @@ "%mainMenu_openHelloWorldProject%": "Open Hello World Project", "%mainMenu_createNewHelloWorldProject%": "Create New Hello World Project", "%mainMenu_deleteHelloWorldProject%": "Delete Hello World Project", - "%helloWorld_webViewMenu_project%": "Project", - "%helloWorld_webViewMenu_view%": "View", + "%helloSomeone_greetingLoading%": "Greeting loading", + "%helloWorld_delete%": "Delete", + "%helloWorld_frenchLocalizationSubmit%": "French localization of Submit Button", + "%helloWorld_helloWorld%": "Hello World", + "%helloWorld_listOfSelectedIds%": "List of Selected Project Id(s)", + "%helloWorld_logo%": "Hello World Logo", + "%helloWorld_none%": "None", + "%helloWorld_openResourceViewer%": "Open in Resource Viewer", + "%helloWorld_openScriptureEditor%": "Open in Scripture Editor", + "%helloWorld_option1%": "Option 1", + "%helloWorld_option2%": "Option 2", + "%helloWorld_react%": "React", + "%helloWorld_select_project%": "Select Project", + "%helloWorld_select_projects%": "Select Projects", + "%helloWorld_selected_project%": "Selected Project", + "%helloWorld_table_id%": "ID", + "%helloWorld_table_subtitle%": "Subtitle", + "%helloWorld_table_title%": "Title", + "%helloWorld_testMe%": "Test Me", + "%helloWorld_throw_test_exception%": "Throw test exception", "%helloWorld_webViewMenu_deleteProject%": "Delete this Project", "%helloWorld_webViewMenu_openViewer%": "Open Viewer", + "%helloWorld_webViewMenu_project%": "Project", + "%helloWorld_webViewMenu_view%": "View", + "%quickVerse_loadingLatest%": "Loading latest Scripture text...", + "%scripture_loadingVerse%": "Loading Verse", + "%selectProject_prompt%": "Please select a Scripture project for Hello World WebView: (Render", + "%selectProject_title%": "Select Hello World Project", + "%selectProjects_prompt%": "Please select one or more Scripture projects for Hello World WebView:", + "%selectProjects_title%": "Select List of Hello World Projects", "%settings_hello_world_group1_label%": "Hello World Settings", "%settings_hello_world_personName_label%": "Selected Person's Name on Hello World Web View", "%project_settings_helloWorld_group1_label%": "Hello World Project Settings", diff --git a/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx b/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx index e0e3d23333..d213493305 100644 --- a/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx +++ b/extensions/src/hello-world/src/web-views/hello-world.web-view.tsx @@ -74,6 +74,98 @@ globalThis.webViewComponent = function HelloWorld({ [scrRef], ); + const deleteKey = '%helloWorld_delete%'; + const frenchLocalizationSubmit = '%helloWorld_frenchLocalizationSubmit%'; + const greetingLoading = '%helloSomeone_greetingLoading%'; + const helloWorld = '%helloWorld_helloWorld%'; + const listOfSelectedIds = '%helloWorld_listOfSelectedIds%'; + const logoKey = '%helloWorld_logo%'; + const noneKey = '%helloWorld_none%'; + const openResourceViewer = '%helloWorld_openResourceViewer%'; + const openScriptureEditor = '%helloWorld_openScriptureEditor%'; + const option1 = '%helloWorld_option1%'; + const option2 = '%helloWorld_option2%'; + const quickVerseLoadingLatest = '%quickVerse_loadingLatest%'; + const reactKey = '%helloWorld_react%'; + const scriptureLoadingVerse = '%scripture_loadingVerse%'; + const selectedProjectKey = '%helloWorld_selected_project%'; + const selectProjectKey = '%helloWorld_select_project%'; + const selectProjectPrompt = '%selectProject_prompt%'; + const selectProjectsKey = '%helloWorld_select_projects%'; + const selectProjectsPrompt = '%selectProjects_prompt%'; + const selectProjectsTitle = '%selectProjects_title%'; + const selectProjectTitle = '%selectProject_title%'; + const submit = '%submitButton%'; + const tableId = '%helloWorld_table_id%'; + const tableSubtitle = '%helloWorld_table_subtitle%'; + const tableTitle = '%helloWorld_table_title%'; + const testException = '%helloWorld_throw_test_exception%'; + const testMe = '%helloWorld_testMe%'; + + const [localizedStrings] = useLocalizedStrings( + useMemo( + () => [ + deleteKey, + frenchLocalizationSubmit, + greetingLoading, + helloWorld, + listOfSelectedIds, + logoKey, + noneKey, + openResourceViewer, + openScriptureEditor, + option1, + option2, + quickVerseLoadingLatest, + reactKey, + scriptureLoadingVerse, + selectedProjectKey, + selectProjectKey, + selectProjectPrompt, + selectProjectsKey, + selectProjectsPrompt, + selectProjectsTitle, + selectProjectTitle, + submit, + tableId, + tableSubtitle, + tableTitle, + testException, + testMe, + ], + [], + ), + useMemo(() => ['fr', 'en'], []), + ); + + const localizedDelete = localizedStrings[deleteKey]; + const localizedFrenchLocalizationSubmit = localizedStrings[frenchLocalizationSubmit]; + const localizedGreetingLoading = localizedStrings[greetingLoading]; + const localizedHelloWorld = localizedStrings[helloWorld]; + const localizedListOfSelectedIds = localizedStrings[listOfSelectedIds]; + const localizedLogo = localizedStrings[logoKey]; + const localizedNone = localizedStrings[noneKey]; + const localizedOpenResourceViewer = localizedStrings[openResourceViewer]; + const localizedOpenScriptureEditor = localizedStrings[openScriptureEditor]; + const localizedOption1 = localizedStrings[option1]; + const localizedOption2 = localizedStrings[option2]; + const localizedQuickVerseLoadingLatest = localizedStrings[quickVerseLoadingLatest]; + const localizedReact = localizedStrings[reactKey]; + const localizedScriptureLoadingVerse = localizedStrings[scriptureLoadingVerse]; + const localizedSelectedProject = localizedStrings[selectedProjectKey]; + const localizedSelectProject = localizedStrings[selectProjectKey]; + const localizedSelectProjectPrompt = localizedStrings[selectProjectPrompt]; + const localizedSelectProjects = localizedStrings[selectProjectsKey]; + const localizedSelectProjectsPrompt = localizedStrings[selectProjectsPrompt]; + const localizedSelectProjectsTitle = localizedStrings[selectProjectsTitle]; + const localizedSelectProjectTitle = localizedStrings[selectProjectTitle]; + const localizedSubmit = localizedStrings[submit]; + const localizedTableId: string = localizedStrings[tableId]; + const localizedTableSubtitle = localizedStrings[tableSubtitle]; + const localizedTableTitle = localizedStrings[tableTitle]; + const localizedTestException = localizedStrings[testException]; + const localizedTestMe = localizedStrings[testMe]; + // Update the clicks when we are informed helloWorld has been run useEvent( papi.network.getNetworkEvent('helloWorld.onHelloWorld'), @@ -87,8 +179,8 @@ globalThis.webViewComponent = function HelloWorld({ useEffect(() => { logger.debug(`Hello World WebView previous title: ${title}`); - updateWebViewDefinition({ title: `Hello World ${clicks}` }); - }, [title, updateWebViewDefinition, clicks]); + updateWebViewDefinition({ title: `${localizedHelloWorld} ${clicks}` }); + }, [title, updateWebViewDefinition, localizedHelloWorld, clicks]); const currentRender = useRef(-1); currentRender.current += 1; @@ -98,9 +190,9 @@ globalThis.webViewComponent = function HelloWorld({ // This is intentionally not a stable reference like `useMemo` or something because we are // testing below to make sure `useDialogCallback` returns the same callback every time { - prompt: `Please select a Scripture project for Hello World WebView: (Render ${currentRender.current})`, + prompt: `${localizedSelectProjectPrompt} ${currentRender.current})`, iconUrl: 'papi-extension://helloWorld/assets/offline.svg', - title: 'Select Hello World Project', + title: localizedSelectProjectTitle, maximumOpenDialogs: 2, // Test ref parameter properly getting latest value currentRender: currentRender.current, @@ -137,7 +229,7 @@ globalThis.webViewComponent = function HelloWorld({ const [latestVerseText] = useData('quickVerse.quickVerse').Verse( 'latest', - 'Loading latest Scripture text...', + localizedQuickVerseLoadingLatest, ); const [projects, setProjects] = useWebViewState('projects', []); @@ -146,13 +238,13 @@ globalThis.webViewComponent = function HelloWorld({ 'platform.selectMultipleProjects', useMemo( () => ({ - prompt: 'Please select one or more Scripture projects for Hello World WebView:', + prompt: `${localizedSelectProjectsPrompt}`, iconUrl: 'papi-extension://helloWorld/assets/offline.svg', - title: 'Select List of Hello World Projects', + title: localizedSelectProjectsTitle, selectedProjectIds: projects, includeProjectInterfaces: ['platformScripture.USFM_Verse'], }), - [projects], + [localizedSelectProjectsPrompt, localizedSelectProjectsTitle, projects], ), useCallback( (selectedProjects) => { @@ -189,34 +281,33 @@ globalThis.webViewComponent = function HelloWorld({ const peopleDataProvider = useDataProvider('helloSomeone.people'); - const [personGreeting] = useData('helloSomeone.people').Greeting(name, 'Greeting loading'); + const [personGreeting] = useData('helloSomeone.people').Greeting(name, localizedGreetingLoading); const [personAge] = useData('helloSomeone.people').Age(name, -1); const [currentProjectVerse] = useProjectData( 'platformScripture.USFM_Verse', projectId ?? undefined, - ).VerseUSFM(verseRef, 'Loading Verse'); + ).VerseUSFM(verseRef, localizedScriptureLoadingVerse); const helloWorldProjectSettings = useHelloWorldProjectSettings(projectId); const { headerStyle } = helloWorldProjectSettings; - const [localizedStrings] = useLocalizedStrings( - useMemo(() => ['%submitButton%'], []), - useMemo(() => ['fr', 'en'], []), - ); - const localizedString = localizedStrings['%submitButton%']; + const genericComboBoxOptions = useMemo( + () => [localizedOption1, localizedOption2], + [localizedOption1, localizedOption2], + ); return (
- Hello World React + {localizedHelloWorld} {localizedReact} {/** * Note: `Logo` here is inlined into this code as a `data:` url. This is here simply for * demonstration purposes. Inlining as a `data:` url is generally not recommended. Rather, it is * generally better to use `papi-extension:` to avoid unnecessary bloat */} - Hello World Logo + {localizedLogo}
@@ -237,21 +328,25 @@ globalThis.webViewComponent = function HelloWorld({ throw new Error(`${NAME} test exception!`); }} > - Throw test exception + {localizedTestException}
{latestVerseText}
setName(e.target.value)} /> - +
{personGreeting}
{personAge}

-
Selected Project: {projectId ?? 'None'}
- + {localizedSelectedProject}: {projectId ?? localizedNone} +
+
+

{verseRef.toString()}

{currentProjectVerse}
-

List of Selected Project Id(s):

-
{(projects.length > 0 ? projects : ['None']).join(', ')}
+

{localizedListOfSelectedIds}:

+
{(projects.length > 0 ? projects : [{ localizedNone }]).join(', ')}
- +

- - + + {/* no label available */} - + {/* no label available */} setScrRef(newScrRef)} /> columns={[ { key: 'id', - name: 'ID', + name: localizedTableId, }, { key: 'title', - name: 'Title', + name: localizedTableTitle, editable: true, }, { key: 'subtitle', - name: 'Subtitle', + name: localizedTableSubtitle, editable: true, }, ]} @@ -318,8 +413,8 @@ globalThis.webViewComponent = function HelloWorld({ />
-

French localization of Submit Button:

-
{localizedString}
+

{localizedFrenchLocalizationSubmit}:

+
{localizedSubmit}
); diff --git a/extensions/src/platform-scripture-editor/contributions/localizedStrings.json b/extensions/src/platform-scripture-editor/contributions/localizedStrings.json index a48899acf5..a222639b57 100644 --- a/extensions/src/platform-scripture-editor/contributions/localizedStrings.json +++ b/extensions/src/platform-scripture-editor/contributions/localizedStrings.json @@ -11,6 +11,9 @@ "%webView_platformScriptureEditor_thickBorders%": "Thick Borders", "%webView_platformScriptureEditor_publisherInfo%": "Publisher Info", "%webView_platformScriptureEditor_copyrightInfo%": "Copyright Info", + "%webView_platformScriptureEditor_editable%": "(Editable)", + "%webView_platformScriptureEditor_resourceViewer%": "Resource Viewer", + "%webView_platformScriptureEditor_scriptureEditor%": "Scripture Editor", "%platformScriptureEditor_dialog_openResourceViewer_title%": "Open Resource Viewer", "%platformScriptureEditor_dialog_openResourceViewer_prompt%": "Choose a resource to open:", "%platformScriptureEditor_dialog_openScriptureEditor_title%": "Open Scripture Editor", diff --git a/extensions/src/platform-scripture-editor/src/main.ts b/extensions/src/platform-scripture-editor/src/main.ts index fcd2407aa7..7210eb967e 100644 --- a/extensions/src/platform-scripture-editor/src/main.ts +++ b/extensions/src/platform-scripture-editor/src/main.ts @@ -6,18 +6,33 @@ import type { SavedWebViewDefinition, WebViewDefinition, } from '@papi/core'; +import { LanguageStrings } from 'platform-bible-utils'; +// TODO: Remove this as soon as you get to the other computer +// eslint-disable-next-line import/no-unresolved +import localizationService from '@shared/services/localization.service'; import platformScriptureEditorWebView from './platform-scripture-editor.web-view?inline'; import platformScriptureEditorWebViewStyles from './platform-scripture-editor.web-view.scss?inline'; logger.info('Scripture Editor is importing!'); const scriptureEditorWebViewType = 'platformScriptureEditor.react'; +const editable = '%webView_platformScriptureEditor_editable%'; +const resourceViewer = '%webView_platformScriptureEditor_resourceViewer%'; +const scriptureEditor = '%webView_platformScriptureEditor_scriptureEditor%'; interface PlatformScriptureEditorOptions extends GetWebViewOptions { projectId: string | undefined; isReadOnly: boolean; } +async function getLocalizations(): Promise { + const localizationData = await localizationService.getLocalizedStrings({ + localizeKeys: [editable, resourceViewer, scriptureEditor], + locales: ['en'], + }); + return localizationData; +} + /** Temporary function to manually control `isReadOnly`. Registered as a command handler. */ async function openPlatformScriptureEditor( projectId: string | undefined, @@ -103,6 +118,11 @@ const scriptureEditorWebViewProvider: IWebViewProvider = { `${scriptureEditorWebViewType} provider received request to provide a ${savedWebView.webViewType} web view`, ); + const localizedStrings = await getLocalizations(); + const localizedEditable = localizedStrings[editable]; + const localizedResourceViewer = localizedStrings[resourceViewer]; + const localizedScriptureEditor = localizedStrings[scriptureEditor]; + // We know that the projectId (if present in the state) will be a string. const projectId = getWebViewOptions.projectId || savedWebView.projectId || undefined; const isReadOnly = getWebViewOptions.isReadOnly || savedWebView.state?.isReadOnly; @@ -112,8 +132,8 @@ const scriptureEditorWebViewProvider: IWebViewProvider = { (await ( await papi.projectDataProviders.get('platform.base', projectId) ).getSetting('platform.name')) ?? projectId - }${isReadOnly ? '' : ' (Editable)'}`; - } else title = isReadOnly ? 'Resource Viewer' : 'Scripture Editor'; + }${isReadOnly ? '' : ` ${localizedEditable}`}`; + } else title = isReadOnly ? `${localizedResourceViewer}` : `${localizedScriptureEditor}`; return { title, diff --git a/src/renderer/components/basic-list/basic-list.component.tsx b/src/renderer/components/basic-list/basic-list.component.tsx index 56515f3ecf..ee6ea7e35e 100644 --- a/src/renderer/components/basic-list/basic-list.component.tsx +++ b/src/renderer/components/basic-list/basic-list.component.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useMemo, useState } from 'react'; import { SavedTabInfo, TabInfo } from '@shared/models/docking-framework.model'; import { ExpandedState, @@ -12,8 +12,14 @@ import { Canon } from '@sillsdev/scripture'; import { faker } from '@faker-js/faker'; import './basic-list.component.scss'; +import { useLocalizedStrings } from '@renderer/hooks/papi-hooks'; +import localizationService from '@shared/services/localization.service'; export const TAB_TYPE_BASIC_LIST = 'basic-list'; +const basicList = '%basicList_basicList%'; +const localizedBasicList = await localizationService.getLocalizedString({ + localizeKey: basicList, +}); type CheckResult = { book: string; @@ -23,91 +29,134 @@ type CheckResult = { subRows?: CheckResult[]; }; -const newCheckResult = (bookId: string): CheckResult => ({ +const newCheckResult = (bookId: string, localizedIssueDescription: string): CheckResult => ({ book: Canon.bookIdToEnglishName(bookId), chapter: faker.number.int(40), verse: faker.number.int(40), - issueDescription: 'Basic check issue description', + issueDescription: localizedIssueDescription, }); -const makeMockCheckResults = () => { +const makeMockCheckResults = (localizedIssueDescription: string, localizedIssues: string) => { return Canon.allBookIds.map((bookId) => { const numberOfIssues: number = faker.number.int({ min: 1, max: 10 }); const bookResults: CheckResult = { book: Canon.bookIdToEnglishName(bookId), - issueDescription: `${numberOfIssues} issues`, + issueDescription: `${numberOfIssues} ${localizedIssues}`, }; const subResults: CheckResult[] = []; for (let i = 0; i < numberOfIssues; i++) { - subResults.push(newCheckResult(bookId)); + subResults.push(newCheckResult(bookId, localizedIssueDescription)); } bookResults.subRows = subResults; return bookResults; }); }; -const columns: ColumnDef[] = [ - { - header: 'Scripture reference', - columns: [ - { - accessorKey: 'book', - header: ({ table }) => ( - <> - {' '} - Book - - ), - cell: ({ row, getValue }) => ( -
- {row.getCanExpand() && ( - - )}{' '} - {getValue()} -
- ), - }, - { - accessorFn: (row) => row.chapter, - id: 'chapter', - cell: (info) => info.getValue(), - header: ({ table }) => <> {table.getIsSomeRowsExpanded() && Chapter} , - }, - { - accessorFn: (row) => row.verse, - id: 'verse', - cell: (info) => info.getValue(), - header: ({ table }) => <> {table.getIsSomeRowsExpanded() && Verse} , - }, - ], - }, - { - header: 'Issue', - columns: [ - { - accessorKey: 'issueDescription', - header: () => 'Description', - footer: (props) => props.column.id, - }, - ], - }, -]; +const makeColumns = ( + localizedScriptureReference: string, + localizedChapter: string, + localizedVerse: string, + localizedIssue: string, + localizedDescription: string, +): ColumnDef[] => { + return [ + { + header: localizedScriptureReference, + columns: [ + { + accessorKey: 'book', + header: ({ table }) => ( + <> + {' '} + Book + + ), + cell: ({ row, getValue }) => ( +
+ {row.getCanExpand() && ( + + )}{' '} + {getValue()} +
+ ), + }, + { + accessorFn: (row) => row.chapter, + id: 'chapter', + cell: (info) => info.getValue(), + header: ({ table }) => ( + <> {table.getIsSomeRowsExpanded() && {localizedChapter}} + ), + }, + { + accessorFn: (row) => row.verse, + id: 'verse', + cell: (info) => info.getValue(), + header: ({ table }) => ( + <> {table.getIsSomeRowsExpanded() && {localizedVerse}} + ), + }, + ], + }, + { + header: localizedIssue, + columns: [ + { + accessorKey: 'issueDescription', + header: () => localizedDescription, + footer: (props) => props.column.id, + }, + ], + }, + ]; +}; export default function BasicList() { + const chapter = '%basicList_Chapter%'; + const description = '%basicList_Description%'; + const issueDescriptionKey = '%basicList_issueDescription%'; + const issue = '%basicList_issue%'; + const issues = '%basicList_issues%'; + const scriptureReference = '%basicList_scriptureReference%'; + const verse = '%basicList_Verse%'; + + const [localizedStrings] = useLocalizedStrings( + useMemo( + () => [chapter, description, issueDescriptionKey, issue, issues, scriptureReference, verse], + [], + ), + useMemo(() => ['en'], []), + ); + + const localizedChapter = localizedStrings[chapter]; + const localizedDescription = localizedStrings[description]; + const localizedIssueDescription = localizedStrings[issueDescriptionKey]; + const localizedIssue = localizedStrings[issue]; + const localizedIssues = localizedStrings[issues]; + const localizedScriptureReference = localizedStrings[scriptureReference]; + const localizedVerse = localizedStrings[verse]; + const [expanded, setExpanded] = useState({}); - const [data] = useState(() => makeMockCheckResults()); + const [data] = useState(() => makeMockCheckResults(localizedIssueDescription, localizedIssues)); + const columns = makeColumns( + localizedScriptureReference, + localizedChapter, + localizedVerse, + localizedIssue, + localizedDescription, + ); const table = useReactTable({ data, columns, @@ -161,7 +210,7 @@ export default function BasicList() { export function loadBasicListTab(savedTabInfo: SavedTabInfo): TabInfo { return { ...savedTabInfo, - tabTitle: 'Basic List', + tabTitle: localizedBasicList, content: , }; } From 6e0a56236ba943a79c22b29b830795e65f50ac92 Mon Sep 17 00:00:00 2001 From: Katherine Jensen Date: Fri, 30 Aug 2024 10:29:16 -0700 Subject: [PATCH 02/11] Paranext Core localizations --- assets/localization/en.json | 49 +++++++++-- .../src/platform-scripture-editor/src/main.ts | 5 +- lib/papi-dts/papi.d.ts | 6 +- src/extension-host/data/menu.data.json | 2 +- .../dialogs/select-books-dialog.component.tsx | 5 +- .../select-multiple-projects.dialog.tsx | 6 +- .../dialogs/select-project.dialog.tsx | 5 +- .../docking/error-tab.component.tsx | 6 +- .../docking/platform-tab-title.component.tsx | 14 +++- .../download-update-project-tab.component.tsx | 31 +++++-- .../book-selector.component.tsx | 32 +++++-- .../run-basic-checks-tab.component.tsx | 84 ++++++++++++++----- .../settings-components/setting.component.tsx | 7 +- .../settings-tabs/settings-tab.component.tsx | 13 ++- .../components/web-view.component.test.ts | 43 ---------- .../components/web-view.component.tsx | 22 +++-- src/shared/models/docking-framework.model.ts | 3 +- src/shared/models/web-view.model.ts | 4 +- 18 files changed, 220 insertions(+), 117 deletions(-) delete mode 100644 src/renderer/components/web-view.component.test.ts diff --git a/assets/localization/en.json b/assets/localization/en.json index 1fcb708f4a..472c7f7831 100644 --- a/assets/localization/en.json +++ b/assets/localization/en.json @@ -1,13 +1,34 @@ { "%product_name%": "Platform.Bible", - "%basicList_basicList%": "Basic List", - "%basicList_Chapter%": "Chapter", - "%basicList_Description%": "Description", - "%basicList_issueDescription%": "Basic check issue description", - "%basicList_issue%": "Issue", - "%basicList_issues%": "issues", - "%basicList_scriptureReference%": "Scripture reference", - "%basicList_Verse%": "Verse", + "%bookSelector_chooseEllipsis%": "Choose...", + "%bookSelector_chooseBooks%": "Choose Books", + "%bookSelector_currentBook%": "Current Book", + "%bookSelector_selectBooks%": "Select Books", + "%bookSelector_selectOneOrMoreBooksToRunBasicChecksOn%": "Select one or more books to run basic checks on", + "%checks_Capitalization%": "Capitalization", + "%checks_chapterSlashVerseNumbers%": "Chapter/Verse Numbers", + "%checks_charactersParenthesesCombinations%": "Characters (Combinations)", + "%checks_checks%": "Checks", + "%checks_footnoteQuotes%": "Footnote Quotes", + "%checks_markers%": "Markers", + "%checks_noCurrentProject%": "No current project", + "%checks_numbers%": "Numbers", + "%checks_punctuationParenthesesSequences%": "Punctuation (Sequences)", + "%checks_quotations%": "Quotations", + "%checks_quotationTypes%": "Quotation types", + "%checks_references%": "References", + "%checks_repeatedWords%": "Repeated Words", + "%checks_runBasicChecks%": "Run Basic Checks", + "%checks_unmatchedPairsOfPunctuation%": "Unmatched Pairs of Punctuation", + "%downloadUpdateProjectTab_aria_downloadableProjects%": "downloadable projects", + "%downloadUpdateProjectTab_aria_downloadedProjects%": "downloaded projects", + "%downloadUpdateProjectTab_listItem_delete%": "Delete", + "%downloadUpdateProjectTab_subheader_downloadableProjects%": "Downloadable Projects", + "%downloadUpdateProjectTab_subheader_downloadedProjects%": "Downloaded Projects", + "%downloadUpdateProjectTab_title_downloadSlashUpdateProject%": "Download/Update Project", + "%general_cancel%": "Cancel", + "%general_loading%": "Loading", + "%general_run%": "Run", "%insertNote%": "Insert Note", "%mainMenu_aboutPlatformBible%": "About Platform.Bible", "%mainMenu_downloadSlashInstallResources%": "Download/Install Resources", @@ -22,17 +43,29 @@ "%mainMenu_window%": "Window", "%some_localization_key%": "This is the English text for %some_localization_key%.", "%submitButton%": "Submit", + "%tab_error%": "Error", + "%tab_unknown%": "Unknown", + "%tabAria_tab%": "Tab", "%webView_edit%": "Edit", "%webView_openProjectSettings%": "Open Project Settings", "%webView_project%": "Project", "%webView_projectAssignmentsAndProgress%": "Assignments and Progress", + "%webView_defaultTitle_webView%": "Web View", "%wordList%": "Word List", + "%selectBooks_selectBooks%": "Select Books", + "%selectProject_selectProject%": "Select Project", + "%selectMultipleProjects_selectProjects%": "Select Projects", + "%settings_loadingSetting%": "Loading setting", "%settings_platform_group1_label%": "Platform Settings", + "%settings_searchProjectSettingsEllipsis%": "Search Project Settings...", + "%settings_searchUserSettingsEllipsis%": "Search User Settings...", "%settings_platform_group1_description%": "Settings pertaining to the software overall", "%settings_platform_verseRef_label%": "Current Verse Reference", "%settings_platform_interfaceLanguage_label%": "Interface Language", "%settings_platform_ptxUtilsMementoData_label%": "PtxUtils Memento Data", "%settings_platform_paratextDataLastRegistryDataCachedTimes_label%": "ParatextData Last Registry Data Cached Times", + "%settings_projectSettings%": "Project Settings", + "%settings_userSettings%": "User Settings", "%project_settings_platform_group1_label%": "Platform Settings", "%project_settings_platform_group1_description%": "Project settings pertaining to the software overall", "%project_settings_platform_name_label%": "Project Short Name", diff --git a/extensions/src/platform-scripture-editor/src/main.ts b/extensions/src/platform-scripture-editor/src/main.ts index 7210eb967e..04a0abb7ef 100644 --- a/extensions/src/platform-scripture-editor/src/main.ts +++ b/extensions/src/platform-scripture-editor/src/main.ts @@ -7,9 +7,6 @@ import type { WebViewDefinition, } from '@papi/core'; import { LanguageStrings } from 'platform-bible-utils'; -// TODO: Remove this as soon as you get to the other computer -// eslint-disable-next-line import/no-unresolved -import localizationService from '@shared/services/localization.service'; import platformScriptureEditorWebView from './platform-scripture-editor.web-view?inline'; import platformScriptureEditorWebViewStyles from './platform-scripture-editor.web-view.scss?inline'; @@ -26,7 +23,7 @@ interface PlatformScriptureEditorOptions extends GetWebViewOptions { } async function getLocalizations(): Promise { - const localizationData = await localizationService.getLocalizedStrings({ + const localizationData = await papi.localization.getLocalizedStrings({ localizeKeys: [editable, resourceViewer, scriptureEditor], locales: ['en'], }); diff --git a/lib/papi-dts/papi.d.ts b/lib/papi-dts/papi.d.ts index 539844eaa7..47afc05471 100644 --- a/lib/papi-dts/papi.d.ts +++ b/lib/papi-dts/papi.d.ts @@ -2,6 +2,7 @@ /// /// declare module 'shared/models/web-view.model' { + import { LocalizeKey } from 'platform-bible-utils'; /** The type of code that defines a webview's content */ export enum WebViewContentType { /** @@ -37,7 +38,7 @@ declare module 'shared/models/web-view.model' { */ iconUrl?: string; /** Name of the tab for the WebView */ - title?: string; + title?: string | LocalizeKey; /** Tooltip that is shown when hovering over the webview title */ tooltip?: string; /** @@ -2850,6 +2851,7 @@ declare module 'shared/models/docking-framework.model' { WebViewDefinition, WebViewDefinitionUpdateInfo, } from 'shared/models/web-view.model'; + import { LocalizeKey } from 'platform-bible-utils'; /** * Saved information used to recreate a tab. * @@ -2881,7 +2883,7 @@ declare module 'shared/models/docking-framework.model' { */ tabIconUrl?: string; /** Text to show on the title bar of the tab */ - tabTitle: string; + tabTitle: string | LocalizeKey; /** Text to show when hovering over the title bar of the tab */ tabTooltip?: string; /** Content to show inside the tab. */ diff --git a/src/extension-host/data/menu.data.json b/src/extension-host/data/menu.data.json index 3c98878471..41651dae00 100644 --- a/src/extension-host/data/menu.data.json +++ b/src/extension-host/data/menu.data.json @@ -33,7 +33,7 @@ "command": "platform.openProjectDialog" }, { - "label": "%mainMenu_downloadSlashUpdateProject%", + "label": "%downloadUpdateProjectTab_title_downloadSlashUpdateProject%", "localizeNotes": "Application main menu > Project > Download/Update Project", "group": "platform.projectProjects", "order": 2, diff --git a/src/renderer/components/dialogs/select-books-dialog.component.tsx b/src/renderer/components/dialogs/select-books-dialog.component.tsx index db3392f7c6..85aa5c38e3 100644 --- a/src/renderer/components/dialogs/select-books-dialog.component.tsx +++ b/src/renderer/components/dialogs/select-books-dialog.component.tsx @@ -2,6 +2,7 @@ import DoneIcon from '@mui/icons-material/Done'; import { Button, Checklist } from 'platform-bible-react'; import { useState } from 'react'; import { Canon } from '@sillsdev/scripture'; +import { LocalizeKey } from 'platform-bible-utils'; import DIALOG_BASE from './dialog-base.data'; import { DialogDefinition, DialogTypes, SELECT_BOOKS_DIALOG_TYPE } from './dialog-definition.model'; import './select-books-dialog.component.scss'; @@ -48,10 +49,12 @@ function SelectBooksDialog({ ); } +const localizeSelectBooksKey: LocalizeKey = `%selectBooks_selectBooks%`; + const SELECT_BOOKS_DIALOG: DialogDefinition = Object.freeze({ ...DIALOG_BASE, tabType: SELECT_BOOKS_DIALOG_TYPE, - defaultTitle: 'Select Books', + defaultTitle: localizeSelectBooksKey, initialSize: { width: 500, height: 400, diff --git a/src/renderer/components/dialogs/select-multiple-projects.dialog.tsx b/src/renderer/components/dialogs/select-multiple-projects.dialog.tsx index 254571c3eb..7fb4f4a66d 100644 --- a/src/renderer/components/dialogs/select-multiple-projects.dialog.tsx +++ b/src/renderer/components/dialogs/select-multiple-projects.dialog.tsx @@ -7,7 +7,7 @@ import ProjectList, { } from '@renderer/components/projects/project-list.component'; import '@renderer/components/dialogs/select-multiple-projects.dialog.scss'; import projectLookupService from '@shared/services/project-lookup.service'; -import { Button, usePromise } from 'platform-bible-react'; +import { Button, LocalizeKey, usePromise } from 'platform-bible-react'; import DIALOG_BASE from '@renderer/components/dialogs/dialog-base.data'; import { DialogDefinition, @@ -103,12 +103,14 @@ function SelectMultipleProjectsDialog({ ); } +const localizeSelectProjectsKey: LocalizeKey = '%selectMultipleProjects_selectProjects%'; + const SELECT_MULTIPLE_PROJECTS_DIALOG: DialogDefinition< typeof SELECT_MULTIPLE_PROJECTS_DIALOG_TYPE > = Object.freeze({ ...DIALOG_BASE, tabType: SELECT_MULTIPLE_PROJECTS_DIALOG_TYPE, - defaultTitle: 'Select Projects', + defaultTitle: localizeSelectProjectsKey, initialSize: { width: 500, height: 350, diff --git a/src/renderer/components/dialogs/select-project.dialog.tsx b/src/renderer/components/dialogs/select-project.dialog.tsx index 4023db80ce..6c09e6e60e 100644 --- a/src/renderer/components/dialogs/select-project.dialog.tsx +++ b/src/renderer/components/dialogs/select-project.dialog.tsx @@ -15,6 +15,7 @@ import { } from '@renderer/components/dialogs/dialog-definition.model'; import { papiFrontendProjectDataProviderService } from '@shared/services/project-data-provider.service'; import { PROJECT_INTERFACE_PLATFORM_BASE } from '@shared/models/project-data-provider.model'; +import { LocalizeKey } from 'platform-bible-utils'; function SelectProjectDialog({ prompt, @@ -78,10 +79,12 @@ function SelectProjectDialog({ ); } +const localizeSelectProject: LocalizeKey = '%selectProject_selectProject%'; + const SELECT_PROJECT_DIALOG: DialogDefinition = Object.freeze({ ...DIALOG_BASE, tabType: SELECT_PROJECT_DIALOG_TYPE, - defaultTitle: 'Select Project', + defaultTitle: localizeSelectProject, initialSize: { width: 500, height: 350, diff --git a/src/renderer/components/docking/error-tab.component.tsx b/src/renderer/components/docking/error-tab.component.tsx index 39f59fb1d7..b92330182f 100644 --- a/src/renderer/components/docking/error-tab.component.tsx +++ b/src/renderer/components/docking/error-tab.component.tsx @@ -1,5 +1,5 @@ import { SavedTabInfo, TabInfo } from '@shared/models/docking-framework.model'; -import { newGuid } from 'platform-bible-utils'; +import { LocalizeKey, newGuid } from 'platform-bible-utils'; export type ErrorTabData = { errorMessage: string }; @@ -16,12 +16,14 @@ export default function ErrorTab({ errorMessage }: { errorMessage: string }) { ); } +const localizeError: LocalizeKey = '%tab_error%'; + /** Creates a new error message tab with the specified error message */ export const createErrorTab = (errorMessage: string): TabInfo => { return { id: newGuid(), tabType: 'error', - tabTitle: 'Error', + tabTitle: localizeError, content: , minWidth: 150, minHeight: 150, diff --git a/src/renderer/components/docking/platform-tab-title.component.tsx b/src/renderer/components/docking/platform-tab-title.component.tsx index daed009374..3934c6c58e 100644 --- a/src/renderer/components/docking/platform-tab-title.component.tsx +++ b/src/renderer/components/docking/platform-tab-title.component.tsx @@ -2,8 +2,9 @@ import { Tooltip } from '@mui/material'; import { CommandHandler, HamburgerMenuButton } from 'platform-bible-react'; import './platform-tab-title.component.scss'; import menuDataService from '@shared/services/menu-data.service'; -import { useData } from '@renderer/hooks/papi-hooks'; +import { useData, useLocalizedStrings } from '@renderer/hooks/papi-hooks'; import { useCallback, useRef } from 'react'; +import { isLocalizeKey, LocalizeKey } from 'platform-bible-utils'; import { handleMenuCommand } from '../platform-bible-menu.commands'; type PlatformTabTitleProps = { @@ -14,7 +15,7 @@ type PlatformTabTitleProps = { /** Url to image to show on the tab. Defaults to Platform.Bible logo */ iconUrl?: string; /** Text to show on the tab */ - text: string; + text: string | LocalizeKey; /** Text to show when hovering over the tab. Defaults to empty string */ tooltip?: string; }; @@ -35,6 +36,11 @@ export default function PlatformTabTitle({ }: PlatformTabTitleProps) { const menuSelector = webViewType ?? 'invalid.invalid'; + const tabAria: LocalizeKey = '%tabAria_tab%'; + const [localizedStrings] = useLocalizedStrings(isLocalizeKey(text) ? [text, tabAria] : [tabAria]); + const title = isLocalizeKey(text) ? localizedStrings[text] : text; + const tabLabel = localizedStrings[tabAria]; + const menuInfo = useData(webViewType ? menuDataService.dataProviderName : undefined).WebViewMenu( menuSelector, { @@ -82,13 +88,13 @@ export default function PlatformTabTitle({ commandHandler={commandHandler} normalMenu={webViewMenu?.topMenu} className="tab-menu-button" - aria-label="Tab" + aria-label={tabLabel} containerRef={containerRef} > {icon} )} - {text} + {title} ); diff --git a/src/renderer/components/projects/download-update-project-tab.component.tsx b/src/renderer/components/projects/download-update-project-tab.component.tsx index eed61f434b..b0473de583 100644 --- a/src/renderer/components/projects/download-update-project-tab.component.tsx +++ b/src/renderer/components/projects/download-update-project-tab.component.tsx @@ -17,6 +17,7 @@ import ProjectList, { Project, } from '@renderer/components/projects/project-list.component'; import './download-update-project-tab.component.scss'; +import { useLocalizedStrings } from '@renderer/hooks/papi-hooks'; export const TAB_TYPE_DOWNLOAD_UPDATE_PROJECT_DIALOG = 'download-update-project-dialog'; @@ -33,6 +34,24 @@ function deleteProject(project: Project) { } export default function DownloadUpdateProjectTab() { + const downloadableProjectsAriaKey = '%downloadUpdateProjectTab_aria_downloadableProjects%'; + const downloadableProjectsHeaderKey = '%downloadUpdateProjectTab_subheader_downloadableProjects%'; + const downloadedProjectsAriaKey = '%downloadUpdateProjectTab_aria_downloadedProjects%'; + const downloadedProjectsHeaderKey = '%downloadUpdateProjectTab_subheader_downloadedProjects%'; + const deleteListItemKey = '%downloadUpdateProjectTab_listItem_delete%'; + const [localizedStrings] = useLocalizedStrings([ + downloadableProjectsAriaKey, + downloadableProjectsHeaderKey, + downloadedProjectsAriaKey, + downloadedProjectsHeaderKey, + deleteListItemKey, + ]); + const localizedDownloadableProjectsAria = localizedStrings[downloadableProjectsAriaKey]; + const localizedDownloadableProjectsHeader = localizedStrings[downloadableProjectsHeaderKey]; + const localizedDownloadedProjectsAria = localizedStrings[downloadedProjectsAriaKey]; + const localizedDownloadedProjectsHeader = localizedStrings[downloadedProjectsHeaderKey]; + const localizedDeleteListItem = localizedStrings[deleteListItemKey]; + const [downloadableProjects, downloadedProjects] = useMemo(() => { const projects = fetchProjects(); return [ @@ -43,10 +62,10 @@ export default function DownloadUpdateProjectTab() { return (
-