mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	chore(react/ribbon): finalize language switcher
This commit is contained in:
		| @@ -1,103 +0,0 @@ | |||||||
| import { Dropdown } from "bootstrap"; |  | ||||||
| import NoteContextAwareWidget from "./note_context_aware_widget.js"; |  | ||||||
| import { getAvailableLocales, getLocaleById, t } from "../services/i18n.js"; |  | ||||||
| import type { EventData } from "../components/app_context.js"; |  | ||||||
| import type FNote from "../entities/fnote.js"; |  | ||||||
| import attributes from "../services/attributes.js"; |  | ||||||
| import type { Locale } from "@triliumnext/commons"; |  | ||||||
| import options from "../services/options.js"; |  | ||||||
| import appContext from "../components/app_context.js"; |  | ||||||
|  |  | ||||||
| const TPL = /*html*/`\ |  | ||||||
| <div class="dropdown note-language-widget"> |  | ||||||
|     <button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="btn btn-sm dropdown-toggle select-button note-language-button"> |  | ||||||
|         <span class="note-language-desc"></span> |  | ||||||
|         <span class="caret"></span> |  | ||||||
|     </button> |  | ||||||
|     <div class="note-language-dropdown dropdown-menu dropdown-menu-left tn-dropdown-list"></div> |  | ||||||
|     <button class="language-help-button icon-action bx bx-help-circle" type="button" data-in-app-help="B0lcI9xz1r8K" title="${t("open-help-page")}"></button> |  | ||||||
|  |  | ||||||
|     <style> |  | ||||||
|         .note-language-widget { |  | ||||||
|             display: flex; |  | ||||||
|             align-items: center; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .language-help-button { |  | ||||||
|             margin-left: 4px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .note-language-dropdown [dir=rtl] { |  | ||||||
|             text-align: right; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .dropdown-item.rtl > .check { |  | ||||||
|             order: 1; |  | ||||||
|         } |  | ||||||
|     </style> |  | ||||||
| </div> |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| export default class NoteLanguageWidget extends NoteContextAwareWidget { |  | ||||||
|  |  | ||||||
|     private dropdown!: Dropdown; |  | ||||||
|     private $noteLanguageDropdown!: JQuery<HTMLElement>; |  | ||||||
|     private $noteLanguageDesc!: JQuery<HTMLElement>; |  | ||||||
|     private locales: (Locale | "---")[]; |  | ||||||
|     private currentLanguageId?: string; |  | ||||||
|  |  | ||||||
|     constructor() { |  | ||||||
|         super(); |  | ||||||
|         this.locales = NoteLanguageWidget.#buildLocales(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     doRender() { |  | ||||||
|         this.$widget = $(TPL); |  | ||||||
|         this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]); |  | ||||||
|  |  | ||||||
|         this.$noteLanguageDropdown = this.$widget.find(".note-language-dropdown") |  | ||||||
|         this.$noteLanguageDesc = this.$widget.find(".note-language-desc"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     renderDropdown() { |  | ||||||
|         this.$noteLanguageDropdown.empty(); |  | ||||||
|  |  | ||||||
|         if (!this.note) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         const $configureLink = $('<a class="dropdown-item">') |  | ||||||
|             .on("click", () => )); |  | ||||||
|         this.$noteLanguageDropdown.append($configureLink); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async save(languageId: string) { |  | ||||||
|         if (!this.note) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         attributes.setAttribute(this.note, "label", "language", languageId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async refreshWithNote(note: FNote) { |  | ||||||
|         const language = getLocaleById(currentLanguageId) ?? DEFAULT_LOCALE; |  | ||||||
|         this.currentLanguageId = currentLanguageId; |  | ||||||
|         this.$noteLanguageDesc.text(language.name); |  | ||||||
|         this.dropdown.hide(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { |  | ||||||
|         if (loadResults.isOptionReloaded("languages")) { |  | ||||||
|             this.locales = NoteLanguageWidget.#buildLocales(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (loadResults.getAttributeRows().find((a) => a.noteId === this.noteId && a.name === "language")) { |  | ||||||
|             this.refresh(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     static #buildLocales() { |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| import { t } from "../../services/i18n"; | import { t } from "../../services/i18n"; | ||||||
| import { openInAppHelpFromUrl } from "../../services/utils"; | import { openInAppHelpFromUrl } from "../../services/utils"; | ||||||
| import "./FormToggle.css"; | import "./FormToggle.css"; | ||||||
|  | import HelpButton from "./HelpButton"; | ||||||
|  |  | ||||||
| interface FormToggleProps { | interface FormToggleProps { | ||||||
|     currentValue: boolean | null; |     currentValue: boolean | null; | ||||||
| @@ -36,14 +37,7 @@ export default function FormToggle({ currentValue, helpPage, switchOnName, switc | |||||||
|                 </div> |                 </div> | ||||||
|             </label> |             </label> | ||||||
|  |  | ||||||
|             { helpPage && ( |             { helpPage && <HelpButton className="switch-help-button" helpPage={helpPage} />} | ||||||
|                 <button |  | ||||||
|                     class="switch-help-button icon-action bx bx-help-circle" |  | ||||||
|                     type="button" |  | ||||||
|                     onClick={() => openInAppHelpFromUrl(helpPage)} |  | ||||||
|                     title={t("open-help-page")} |  | ||||||
|                 /> |  | ||||||
|             )} |  | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
							
								
								
									
										21
									
								
								apps/client/src/widgets/react/HelpButton.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								apps/client/src/widgets/react/HelpButton.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | import { CSSProperties } from "preact/compat"; | ||||||
|  | import { t } from "../../services/i18n"; | ||||||
|  | import { openInAppHelpFromUrl } from "../../services/utils"; | ||||||
|  |  | ||||||
|  | interface HelpButtonProps { | ||||||
|  |     className?: string; | ||||||
|  |     helpPage: string; | ||||||
|  |     style?: CSSProperties; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default function HelpButton({ className, helpPage, style }: HelpButtonProps) { | ||||||
|  |     return ( | ||||||
|  |         <button | ||||||
|  |             class={`${className ?? ""} icon-action bx bx-help-circle`} | ||||||
|  |             type="button" | ||||||
|  |             onClick={() => openInAppHelpFromUrl(helpPage)} | ||||||
|  |             title={t("open-help-page")} | ||||||
|  |             style={style} | ||||||
|  |         /> | ||||||
|  |     ); | ||||||
|  | } | ||||||
| @@ -16,6 +16,7 @@ import toast from "../../services/toast"; | |||||||
| import branches from "../../services/branches"; | import branches from "../../services/branches"; | ||||||
| import sync from "../../services/sync"; | import sync from "../../services/sync"; | ||||||
| import appContext from "../../components/app_context"; | import appContext from "../../components/app_context"; | ||||||
|  | import HelpButton from "../react/HelpButton"; | ||||||
|  |  | ||||||
| export default function BasicPropertiesTab() { | export default function BasicPropertiesTab() { | ||||||
|     const { note } = useNoteContext(); |     const { note } = useNoteContext(); | ||||||
| @@ -307,10 +308,15 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) { | |||||||
|         return locales; |         return locales; | ||||||
|     }, [ languages ]); |     }, [ languages ]); | ||||||
|  |  | ||||||
|      |     const currentLocale = useMemo(() => { | ||||||
|     return ( |         return locales.find(locale => typeof locale === "object" && locale.id === currentNoteLanguage) as Locale | undefined; | ||||||
|  |     }, [ currentNoteLanguage ]); | ||||||
|  |  | ||||||
|  |     return (         | ||||||
|         <div className="note-language-container"> |         <div className="note-language-container"> | ||||||
|             <Dropdown> |             <span>{t("basic_properties.language")}:</span> | ||||||
|  |               | ||||||
|  |             <Dropdown text={currentLocale?.name ?? DEFAULT_LOCALE.name}> | ||||||
|                 {locales.map(locale => { |                 {locales.map(locale => { | ||||||
|                     if (typeof locale === "object") { |                     if (typeof locale === "object") { | ||||||
|                         const checked = locale.id === (currentNoteLanguage ?? ""); |                         const checked = locale.id === (currentNoteLanguage ?? ""); | ||||||
| @@ -328,6 +334,8 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) { | |||||||
|                     onClick={() => appContext.tabManager.openContextWithNote("_optionsLocalization", { activate: true })} |                     onClick={() => appContext.tabManager.openContextWithNote("_optionsLocalization", { activate: true })} | ||||||
|                 >{t("note_language.configure-languages")}</FormListItem>            |                 >{t("note_language.configure-languages")}</FormListItem>            | ||||||
|             </Dropdown> |             </Dropdown> | ||||||
|  |  | ||||||
|  |             <HelpButton helpPage="B0lcI9xz1r8K" style={{ marginLeft: "4px" }} /> | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,72 +0,0 @@ | |||||||
| import NoteContextAwareWidget from "../note_context_aware_widget.js"; |  | ||||||
| import NoteTypeWidget from "../note_type.js"; |  | ||||||
| import ProtectedNoteSwitchWidget from "../protected_note_switch.js"; |  | ||||||
| import EditabilitySelectWidget from "../editability_select.js"; |  | ||||||
| import BookmarkSwitchWidget from "../bookmark_switch.js"; |  | ||||||
| import SharedSwitchWidget from "../shared_switch.js"; |  | ||||||
| import { t } from "../../services/i18n.js"; |  | ||||||
| import TemplateSwitchWidget from "../template_switch.js"; |  | ||||||
| import type FNote from "../../entities/fnote.js"; |  | ||||||
| import NoteLanguageWidget from "../note_language.js"; |  | ||||||
|  |  | ||||||
| const TPL = /*html*/` |  | ||||||
|     <div class="note-language-container"> |  | ||||||
|         <span>${t("basic_properties.language")}:</span>   |  | ||||||
|     </div> |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| export default class BasicPropertiesWidget extends NoteContextAwareWidget { |  | ||||||
|  |  | ||||||
|     private sharedSwitchWidget: SharedSwitchWidget; |  | ||||||
|     private templateSwitchWidget: TemplateSwitchWidget; |  | ||||||
|     private noteLanguageWidget: NoteLanguageWidget; |  | ||||||
|  |  | ||||||
|     constructor() { |  | ||||||
|         super(); |  | ||||||
|  |  | ||||||
|         this.templateSwitchWidget = new TemplateSwitchWidget().contentSized(); |  | ||||||
|         this.noteLanguageWidget = new NoteLanguageWidget().contentSized(); |  | ||||||
|  |  | ||||||
|         this.child( |  | ||||||
|             this.sharedSwitchWidget, |  | ||||||
|             this.templateSwitchWidget, |  | ||||||
|             this.noteLanguageWidget); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     get name() { |  | ||||||
|         return "basicProperties"; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     get toggleCommand() { |  | ||||||
|         return "toggleRibbonBasicProperties"; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     getTitle() { |  | ||||||
|         return { |  | ||||||
|             show: !this.note?.isLaunchBarConfig(), |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     doRender() { |  | ||||||
|         this.$widget = $(TPL); |  | ||||||
|         this.contentSized(); |  | ||||||
|  |  | ||||||
|         this.$widget.find(".note-type-container").append(this.noteTypeWidget.render()); |  | ||||||
|         this.$widget.find(".protected-note-switch-container").append(this.protectedNoteSwitchWidget.render()); |  | ||||||
|         this.$widget.find(".editability-select-container").append(this.editabilitySelectWidget.render()); |  | ||||||
|         this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render()); |  | ||||||
|         this.$widget.find(".shared-switch-container").append(this.sharedSwitchWidget.render()); |  | ||||||
|         this.$widget.find(".template-switch-container").append(this.templateSwitchWidget.render()); |  | ||||||
|         this.$widget.find(".").append(this.noteLanguageWidget.render()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async refreshWithNote(note: FNote) { |  | ||||||
|         await super.refreshWithNote(note); |  | ||||||
|         if (!this.note) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.$widget.find(".editability-select-container").toggle(this.note && ["text", "code", "mermaid"].includes(this.note.type)); |  | ||||||
|         this.$widget.find(".note-language-container").toggle(this.note && ["text"].includes(this.note.type)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user