From c91748da15ad7078a1ac125695ff6b6a399af1f3 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 22 Aug 2025 12:14:53 +0300 Subject: [PATCH] feat(react/ribbon): port template switch --- apps/client/src/widgets/react/hooks.tsx | 7 ++- .../src/widgets/ribbon/BasicPropertiesTab.tsx | 18 +++++++ .../ribbon_widgets/basic_properties.ts | 2 - apps/client/src/widgets/switch.ts | 8 --- apps/client/src/widgets/template_switch.ts | 52 ------------------- 5 files changed, 23 insertions(+), 64 deletions(-) delete mode 100644 apps/client/src/widgets/template_switch.ts diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 7c8257ead..1e91c475a 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -316,6 +316,7 @@ export function useNoteProperty(note: FNote | null | unde export function useNoteLabel(note: FNote | undefined | null, labelName: string): [string | null | undefined, (newValue: string) => void] { const [ labelValue, setLabelValue ] = useState(note?.getLabelValue(labelName)); + useEffect(() => setLabelValue(note?.getLabelValue(labelName) ?? null), [ note ]); useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => { for (const attr of loadResults.getAttributeRows()) { if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) { @@ -336,8 +337,10 @@ export function useNoteLabel(note: FNote | undefined | null, labelName: string): ] as const; } -export function useNoteLabelBoolean(note: FNote | undefined | null, labelName: string): [ boolean | null | undefined, (newValue: boolean) => void] { - const [ labelValue, setLabelValue ] = useState(note?.hasLabel(labelName)); +export function useNoteLabelBoolean(note: FNote | undefined | null, labelName: string): [ boolean, (newValue: boolean) => void] { + const [ labelValue, setLabelValue ] = useState(!!note?.hasLabel(labelName)); + + useEffect(() => setLabelValue(!!note?.hasLabel(labelName)), [ note ]); useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => { for (const attr of loadResults.getAttributeRows()) { diff --git a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx index 33f28a277..8ed0526b7 100644 --- a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx +++ b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx @@ -15,6 +15,7 @@ import FormDropdownList from "../react/FormDropdownList"; import toast from "../../services/toast"; import branches from "../../services/branches"; import sync from "../../services/sync"; +import TemplateSwitchWidget from "../template_switch"; export default function BasicPropertiesTab() { const { note } = useNoteContext(); @@ -26,6 +27,7 @@ export default function BasicPropertiesTab() { + ); } @@ -202,6 +204,22 @@ function BookmarkSwitch({ note }: { note?: FNote | null }) { ) } +function TemplateSwitch({ note }: { note?: FNote | null }) { + const [ isTemplate, setIsTemplate ] = useNoteLabelBoolean(note, "template"); + + return ( +
+ +
+ ) +} + function SharedSwitch({ note }: { note?: FNote | null }) { const [ isShared, setIsShared ] = useState(false); const refreshState = useCallback(() => { diff --git a/apps/client/src/widgets/ribbon_widgets/basic_properties.ts b/apps/client/src/widgets/ribbon_widgets/basic_properties.ts index 8a762f96c..a60b999e4 100644 --- a/apps/client/src/widgets/ribbon_widgets/basic_properties.ts +++ b/apps/client/src/widgets/ribbon_widgets/basic_properties.ts @@ -10,8 +10,6 @@ import type FNote from "../../entities/fnote.js"; import NoteLanguageWidget from "../note_language.js"; const TPL = /*html*/` -
-
${t("basic_properties.language")}:  
diff --git a/apps/client/src/widgets/switch.ts b/apps/client/src/widgets/switch.ts index 1f5956a6e..c31be8646 100644 --- a/apps/client/src/widgets/switch.ts +++ b/apps/client/src/widgets/switch.ts @@ -1,14 +1,6 @@ import { t } from "../services/i18n.js"; import NoteContextAwareWidget from "./note_context_aware_widget.js"; -const TPL = /*html*/` -
- - -
`; - export default class SwitchWidget extends NoteContextAwareWidget { doRender() { diff --git a/apps/client/src/widgets/template_switch.ts b/apps/client/src/widgets/template_switch.ts deleted file mode 100644 index 50c11f657..000000000 --- a/apps/client/src/widgets/template_switch.ts +++ /dev/null @@ -1,52 +0,0 @@ -import SwitchWidget from "./switch.js"; -import attributeService from "../services/attributes.js"; -import { t } from "../services/i18n.js"; -import type { EventData } from "../components/app_context.js"; -import type FNote from "../entities/fnote.js"; - -/** - * Switch for the basic properties widget which allows the user to select whether the note is a template or not, which toggles the `#template` attribute. - */ -export default class TemplateSwitchWidget extends SwitchWidget { - - isEnabled() { - return super.isEnabled() && !this.noteId?.startsWith("_options"); - } - - doRender() { - super.doRender(); - - this.switchOnName = t("template_switch.template"); - this.switchOnTooltip = t("template_switch.toggle-on-hint"); - - this.switchOffName = t("template_switch.template"); - this.switchOffTooltip = t("template_switch.toggle-off-hint"); - - this.$helpButton.attr("data-help-page", "template.html").show(); - } - - async switchOn() { - if (this.noteId) { - await attributeService.setLabel(this.noteId, "template"); - } - } - - async switchOff() { - if (this.note && this.noteId) { - for (const templateAttr of this.note.getOwnedLabels("template")) { - await attributeService.removeAttributeById(this.noteId, templateAttr.attributeId); - } - } - } - - async refreshWithNote(note: FNote) { - const isTemplate = note.hasLabel("template"); - this.isToggled = isTemplate; - } - - entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { - if (loadResults.getAttributeRows().find((attr) => attr.type === "label" && attr.name === "template" && attr.noteId === this.noteId)) { - this.refresh(); - } - } -}