mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 09:16:45 +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 locales.find(locale => typeof locale === "object" && locale.id === currentNoteLanguage) as Locale | undefined;
|
||||||
|
}, [ currentNoteLanguage ]);
|
||||||
|
|
||||||
return (
|
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