From 36ac891c00d99a7c7997aa4463bae9094f4765df Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Sun, 18 Feb 2024 21:20:07 +0100 Subject: [PATCH] #756 - Language dropdown --- src/commands/i18n.ts | 26 +++++++-- .../components/Contents/ContentActions.tsx | 2 +- .../components/Contents/I18nLabel.tsx | 55 ++++++++++++++++++- .../components/Contents/Item.tsx | 53 ++++++++++++------ src/dashboardWebView/hooks/usePages.tsx | 3 + src/dashboardWebView/models/Page.ts | 7 ++- 6 files changed, 118 insertions(+), 28 deletions(-) diff --git a/src/commands/i18n.ts b/src/commands/i18n.ts index 4128f1b8..e897bb1f 100644 --- a/src/commands/i18n.ts +++ b/src/commands/i18n.ts @@ -23,6 +23,8 @@ import { ParsedFrontMatter } from '../parsers'; // Locale settings on the page folder level and global level // Show the i18n content -> if default locale is in subfolder, the other content is not found // Update the page folder setting to include the locales property (use #ref) +// Update the default card item when the translation is removed +// Add action to create new translation export class i18n { /** @@ -146,21 +148,31 @@ export class i18n { */ public static async getTranslations( filePath: string - ): Promise<{ [locale: string]: string } | undefined> { + ): Promise<{ [locale: string]: { + locale: I18nConfig; + path: string; + } } | undefined> { const i18nSettings = await i18n.getSettings(filePath); if (!i18nSettings) { return; } - const translations: { [locale: string]: string } = {}; + const translations: { [locale: string]: { + locale: I18nConfig; + path: string; + } } = {}; const pageFolder = Folders.getPageFolderByFilePath(filePath); + const fileName = parse(filePath).base; if (pageFolder && pageFolder.defaultLocale) { for (const i18n of i18nSettings) { if (i18n.path) { - const translation = join(pageFolder.path, i18n.path, filePath); + const translation = join(pageFolder.path, i18n.path, fileName); if (await existsAsync(translation)) { - translations[i18n.locale] = translation; + translations[i18n.locale] = { + locale: i18n, + path: translation + }; } } } @@ -172,7 +184,6 @@ export class i18n { return; } - const fileName = parse(filePath).base; const defaultLanguageFolders = folders.filter((folder) => folder.defaultLocale); let defaultLanguageFolder: ContentFolder | undefined; for (const folder of defaultLanguageFolders) { @@ -190,7 +201,10 @@ export class i18n { for (const i18n of i18nSettings) { const translation = join(defaultLanguageFolder.path, i18n.path || '', fileName); if (await existsAsync(translation)) { - translations[i18n.locale] = translation; + translations[i18n.locale] = { + locale: i18n, + path: translation + }; } } diff --git a/src/dashboardWebView/components/Contents/ContentActions.tsx b/src/dashboardWebView/components/Contents/ContentActions.tsx index 1477e6af..5b2d1b2c 100644 --- a/src/dashboardWebView/components/Contents/ContentActions.tsx +++ b/src/dashboardWebView/components/Contents/ContentActions.tsx @@ -136,7 +136,7 @@ export const ContentActions: React.FunctionComponent = ({ )} - + {l10n.t(LocalizationKey.dashboardContentsContentActionsActionMenuButtonTitle)} diff --git a/src/dashboardWebView/components/Contents/I18nLabel.tsx b/src/dashboardWebView/components/Contents/I18nLabel.tsx index 9861f9ab..255315a9 100644 --- a/src/dashboardWebView/components/Contents/I18nLabel.tsx +++ b/src/dashboardWebView/components/Contents/I18nLabel.tsx @@ -1,6 +1,10 @@ import * as React from 'react'; import { Page } from '../../models'; -import { LanguageIcon } from '@heroicons/react/24/outline'; +import { ChevronDownIcon, LanguageIcon } from '@heroicons/react/24/outline'; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '../../../components/shadcn/Dropdown'; +import { MenuItem } from '../Menu'; +import { DashboardMessage } from '../../DashboardMessage'; +import { messageHandler } from '@estruyf/vscode/dist/client'; export interface II18nLabelProps { page: Page; @@ -9,14 +13,59 @@ export interface II18nLabelProps { export const I18nLabel: React.FunctionComponent = ({ page }: React.PropsWithChildren) => { + + const openFile = (filePath: string) => { + messageHandler.send(DashboardMessage.openFile, filePath); + } + + const dropdown = React.useMemo(() => { + console.log(page) + if (!page.fmLocale || !page.fmTranslations || Object.keys(page.fmTranslations).length < 1) { + return null; + } + + return ( + + + + + + openFile(value)} /> + + + + { + Object.entries(page.fmTranslations).map(([key, value]) => { + return ( + openFile(value)} /> + ); + }) + } + + + ) + }, [page]) + if (!page.fmLocale) { return null; } return (
- - {page.fmLocale.title || page.fmLocale.locale} + {/* + {page.fmLocale.title || page.fmLocale.locale} */} + + {dropdown}
); }; \ No newline at end of file diff --git a/src/dashboardWebView/components/Contents/Item.tsx b/src/dashboardWebView/components/Contents/Item.tsx index 5844e8ab..8cbc34f6 100644 --- a/src/dashboardWebView/components/Contents/Item.tsx +++ b/src/dashboardWebView/components/Contents/Item.tsx @@ -70,6 +70,34 @@ export const Item: React.FunctionComponent = ({ return []; }, [settings, pageData]); + const statusPlaceholder = useMemo(() => { + if (!statusHtml && !cardFields?.state) { + return null; + } + + return ( + statusHtml ? ( +
+ ) : ( + cardFields?.state && draftField && draftField.name && pageData[draftField.name] ? : null + ) + ) + }, [statusHtml, cardFields?.state, draftField, pageData]); + + const datePlaceholder = useMemo(() => { + if (!dateHtml && !cardFields?.date) { + return null; + } + + return ( + dateHtml ? ( +
+ ) : ( + cardFields?.date && pageData.date ? : null + ) + ) + }, [dateHtml, cardFields?.date, pageData]); + const hasDraftOrDate = useMemo(() => { return cardFields && (cardFields.state || cardFields.date); }, [cardFields]); @@ -107,23 +135,14 @@ export const Item: React.FunctionComponent = ({
-
- { - statusHtml ? ( -
- ) : ( - cardFields?.state && draftField && draftField.name && - ) - } - - { - dateHtml ? ( -
- ) : ( - cardFields?.date && - ) - } -
+ { + (statusPlaceholder || datePlaceholder) && ( +
+ {statusPlaceholder} + {datePlaceholder} +
+ ) + } !page.fmLocale || (page.fmLocale && page.fmDefaultLocale)) + // Process the tab data const draftTypes = Object.assign({}, tabInfo); draftTypes[Tab.All] = crntPages.length; diff --git a/src/dashboardWebView/models/Page.ts b/src/dashboardWebView/models/Page.ts index dce8467d..034bdb66 100644 --- a/src/dashboardWebView/models/Page.ts +++ b/src/dashboardWebView/models/Page.ts @@ -24,7 +24,12 @@ export interface Page { // i18n fields fmDefaultLocale?: boolean; fmLocale?: I18nConfig; - fmTranslations?: { [locale: string]: string }; + fmTranslations?: { + [locale: string]: { + locale: I18nConfig; + path: string; + } + }; title: string; slug: string;