mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	refactor(react/settings): add names to all form groups
This commit is contained in:
		| @@ -107,7 +107,7 @@ function AddLinkDialogComponent() { | |||||||
|             }} |             }} | ||||||
|             show={shown} |             show={shown} | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("add_link.note")}> |             <FormGroup label={t("add_link.note")} name="note"> | ||||||
|                 <NoteAutocomplete |                 <NoteAutocomplete | ||||||
|                     inputRef={autocompleteRef} |                     inputRef={autocompleteRef} | ||||||
|                     onChange={setSuggestion} |                     onChange={setSuggestion} | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ function BranchPrefixDialogComponent() { | |||||||
|             footer={<Button text={t("branch_prefix.save")} />} |             footer={<Button text={t("branch_prefix.save")} />} | ||||||
|             show={shown} |             show={shown} | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("branch_prefix.prefix")}> |             <FormGroup label={t("branch_prefix.prefix")} name="prefix"> | ||||||
|                 <div class="input-group"> |                 <div class="input-group"> | ||||||
|                     <input class="branch-prefix-input form-control" value={prefix} ref={branchInput} |                     <input class="branch-prefix-input form-control" value={prefix} ref={branchInput} | ||||||
|                         onChange={(e) => setPrefix((e.target as HTMLInputElement).value)} /> |                         onChange={(e) => setPrefix((e.target as HTMLInputElement).value)} /> | ||||||
|   | |||||||
| @@ -69,15 +69,15 @@ function CloneToDialogComponent() { | |||||||
|         > |         > | ||||||
|             <h5>{t("clone_to.notes_to_clone")}</h5> |             <h5>{t("clone_to.notes_to_clone")}</h5> | ||||||
|             <NoteList style={{ maxHeight: "200px", overflow: "auto" }} noteIds={clonedNoteIds} /> |             <NoteList style={{ maxHeight: "200px", overflow: "auto" }} noteIds={clonedNoteIds} /> | ||||||
|             <FormGroup label={t("clone_to.target_parent_note")}> |             <FormGroup name="target-parent-note" label={t("clone_to.target_parent_note")}> | ||||||
|                 <NoteAutocomplete |                 <NoteAutocomplete | ||||||
|                     placeholder={t("clone_to.search_for_note_by_its_name")} |                     placeholder={t("clone_to.search_for_note_by_its_name")} | ||||||
|                     onChange={setSuggestion} |                     onChange={setSuggestion} | ||||||
|                     inputRef={autoCompleteRef} |                     inputRef={autoCompleteRef} | ||||||
|                 />       |                 />       | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|             <FormGroup label={t("clone_to.prefix_optional")} title={t("clone_to.cloned_note_prefix_title")}> |             <FormGroup name="clone-prefix" label={t("clone_to.prefix_optional")} title={t("clone_to.cloned_note_prefix_title")}> | ||||||
|                 <FormTextBox name="clone-prefix" onChange={setPrefix} /> |                 <FormTextBox onChange={setPrefix} /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|         </Modal> |         </Modal> | ||||||
|     ) |     ) | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import tree from "../../services/tree"; | |||||||
| import Button from "../react/Button"; | import Button from "../react/Button"; | ||||||
| import FormCheckbox from "../react/FormCheckbox"; | import FormCheckbox from "../react/FormCheckbox"; | ||||||
| import FormFileUpload from "../react/FormFileUpload"; | import FormFileUpload from "../react/FormFileUpload"; | ||||||
| import FormGroup from "../react/FormGroup"; | import FormGroup, { FormMultiGroup } from "../react/FormGroup"; | ||||||
| import Modal from "../react/Modal"; | import Modal from "../react/Modal"; | ||||||
| import RawHtml from "../react/RawHtml"; | import RawHtml from "../react/RawHtml"; | ||||||
| import ReactBasicWidget from "../react/ReactBasicWidget"; | import ReactBasicWidget from "../react/ReactBasicWidget"; | ||||||
| @@ -55,11 +55,11 @@ function ImportDialogComponent() { | |||||||
|             footer={<Button text={t("import.import")} primary disabled={!files} />} |             footer={<Button text={t("import.import")} primary disabled={!files} />} | ||||||
|             show={shown} |             show={shown} | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("import.chooseImportFile")} description={<>{t("import.importDescription")} <strong>{ noteTitle }</strong></>}> |             <FormGroup name="files" label={t("import.chooseImportFile")} description={<>{t("import.importDescription")} <strong>{ noteTitle }</strong></>}> | ||||||
|                 <FormFileUpload multiple onChange={setFiles} /> |                 <FormFileUpload multiple onChange={setFiles} /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("import.options")}> |             <FormMultiGroup label={t("import.options")}> | ||||||
|                 <FormCheckbox |                 <FormCheckbox | ||||||
|                     name="safe-import" hint={t("import.safeImportTooltip")} label={t("import.safeImport")} |                     name="safe-import" hint={t("import.safeImportTooltip")} label={t("import.safeImport")} | ||||||
|                     currentValue={safeImport} onChange={setSafeImport} |                     currentValue={safeImport} onChange={setSafeImport} | ||||||
| @@ -84,7 +84,7 @@ function ImportDialogComponent() { | |||||||
|                     name="replace-underscores-with-spaces" label={t("import.replaceUnderscoresWithSpaces")}  |                     name="replace-underscores-with-spaces" label={t("import.replaceUnderscoresWithSpaces")}  | ||||||
|                     currentValue={replaceUnderscoresWithSpaces} onChange={setReplaceUnderscoresWithSpaces} |                     currentValue={replaceUnderscoresWithSpaces} onChange={setReplaceUnderscoresWithSpaces} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormMultiGroup> | ||||||
|         </Modal> |         </Modal> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ function IncludeNoteDialogComponent() { | |||||||
|             footer={<Button text={t("include_note.button_include")} keyboardShortcut="Enter" />} |             footer={<Button text={t("include_note.button_include")} keyboardShortcut="Enter" />} | ||||||
|             show={shown} |             show={shown} | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("include_note.label_note")}> |             <FormGroup name="note" label={t("include_note.label_note")}> | ||||||
|                 <NoteAutocomplete |                 <NoteAutocomplete | ||||||
|                     placeholder={t("include_note.placeholder_search")} |                     placeholder={t("include_note.placeholder_search")} | ||||||
|                     onChange={setSuggestion} |                     onChange={setSuggestion} | ||||||
| @@ -55,8 +55,9 @@ function IncludeNoteDialogComponent() { | |||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("include_note.box_size_prompt")}> |             <FormGroup name="include-note-box-size" label={t("include_note.box_size_prompt")}> | ||||||
|                 <FormRadioGroup name="include-note-box-size" |                 <FormRadioGroup | ||||||
|  |                     name="include-note-box-size" | ||||||
|                     currentValue={boxSize} onChange={setBoxSize} |                     currentValue={boxSize} onChange={setBoxSize} | ||||||
|                     values={[ |                     values={[ | ||||||
|                         { label: t("include_note.box_size_small"), value: "small" }, |                         { label: t("include_note.box_size_small"), value: "small" }, | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ function MoveToDialogComponent() { | |||||||
|             <h5>{t("move_to.notes_to_move")}</h5> |             <h5>{t("move_to.notes_to_move")}</h5> | ||||||
|             <NoteList branchIds={movedBranchIds} /> |             <NoteList branchIds={movedBranchIds} /> | ||||||
|  |  | ||||||
|             <FormGroup label={t("move_to.target_parent_note")}> |             <FormGroup name="parent-note" label={t("move_to.target_parent_note")}> | ||||||
|                 <NoteAutocomplete |                 <NoteAutocomplete | ||||||
|                     onChange={setSuggestion} |                     onChange={setSuggestion} | ||||||
|                     inputRef={autoCompleteRef} |                     inputRef={autoCompleteRef} | ||||||
|   | |||||||
| @@ -83,7 +83,7 @@ function NoteTypeChooserDialogComponent() { | |||||||
|             show={shown} |             show={shown} | ||||||
|             stackable |             stackable | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("note_type_chooser.change_path_prompt")}> |             <FormGroup name="parent-note" label={t("note_type_chooser.change_path_prompt")}> | ||||||
|                 <NoteAutocomplete |                 <NoteAutocomplete | ||||||
|                     onChange={setParentNote} |                     onChange={setParentNote} | ||||||
|                     placeholder={t("note_type_chooser.search_placeholder")} |                     placeholder={t("note_type_chooser.search_placeholder")} | ||||||
| @@ -95,7 +95,7 @@ function NoteTypeChooserDialogComponent() { | |||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("note_type_chooser.modal_body")}> |             <FormGroup name="note-type" label={t("note_type_chooser.modal_body")}> | ||||||
|                 <FormList onSelect={onNoteTypeSelected}> |                 <FormList onSelect={onNoteTypeSelected}> | ||||||
|                     {noteTypes.map((_item) => { |                     {noteTypes.map((_item) => { | ||||||
|                         if (_item.title === "----") {      |                         if (_item.title === "----") {      | ||||||
|   | |||||||
| @@ -74,9 +74,8 @@ function PromptDialogComponent() { | |||||||
|             show={shown} |             show={shown} | ||||||
|             stackable |             stackable | ||||||
|         > |         > | ||||||
|             <FormGroup label={opts.current?.message} labelRef={labelRef}> |             <FormGroup name="prompt-dialog-answer" label={opts.current?.message} labelRef={labelRef}> | ||||||
|                 <FormTextBox |                 <FormTextBox | ||||||
|                     name="prompt-dialog-answer" |  | ||||||
|                     inputRef={answerRef} |                     inputRef={answerRef} | ||||||
|                     currentValue={value} onChange={setValue} |                     currentValue={value} onChange={setValue} | ||||||
|                     readOnly={opts.current?.readOnly} |                     readOnly={opts.current?.readOnly} | ||||||
|   | |||||||
| @@ -83,11 +83,8 @@ function SortChildNotesDialogComponent() { | |||||||
|                 label={t("sort_child_notes.sort_with_respect_to_different_character_sorting")} |                 label={t("sort_child_notes.sort_with_respect_to_different_character_sorting")} | ||||||
|                 currentValue={sortNatural} onChange={setSortNatural} |                 currentValue={sortNatural} onChange={setSortNatural} | ||||||
|             /> |             /> | ||||||
|             <FormGroup className="form-check" label={t("sort_child_notes.natural_sort_language")} description={t("sort_child_notes.the_language_code_for_natural_sort")}> |             <FormGroup name="sort-locale" className="form-check" label={t("sort_child_notes.natural_sort_language")} description={t("sort_child_notes.the_language_code_for_natural_sort")}> | ||||||
|                 <FormTextBox |                 <FormTextBox currentValue={sortLocale} onChange={setSortLocale} /> | ||||||
|                     name="sort-locale"                                         |  | ||||||
|                     currentValue={sortLocale} onChange={setSortLocale} |  | ||||||
|                 /> |  | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|         </Modal> |         </Modal> | ||||||
|     ) |     ) | ||||||
|   | |||||||
| @@ -51,13 +51,12 @@ function UploadAttachmentsDialogComponent() { | |||||||
|             onHidden={() => setShown(false)} |             onHidden={() => setShown(false)} | ||||||
|             show={shown} |             show={shown} | ||||||
|         > |         > | ||||||
|             <FormGroup label={t("upload_attachments.choose_files")} description={description}> |             <FormGroup name="files" label={t("upload_attachments.choose_files")} description={description}> | ||||||
|                 <FormFileUpload onChange={setFiles} multiple /> |                 <FormFileUpload onChange={setFiles} multiple /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("upload_attachments.options")}> |             <FormGroup name="shrink-images" label={t("upload_attachments.options")}> | ||||||
|                 <FormCheckbox                     |                 <FormCheckbox                     | ||||||
|                     name="shrink-images" |  | ||||||
|                     hint={t("upload_attachments.tooltip")} label={t("upload_attachments.shrink_images")} |                     hint={t("upload_attachments.tooltip")} label={t("upload_attachments.shrink_images")} | ||||||
|                     currentValue={shrinkImages} onChange={setShrinkImages} |                     currentValue={shrinkImages} onChange={setShrinkImages} | ||||||
|                 /> |                 /> | ||||||
|   | |||||||
| @@ -3,9 +3,11 @@ import { useEffect, useRef, useMemo, useCallback } from "preact/hooks"; | |||||||
| import { escapeQuotes } from "../../services/utils"; | import { escapeQuotes } from "../../services/utils"; | ||||||
| import { ComponentChildren } from "preact"; | import { ComponentChildren } from "preact"; | ||||||
| import { CSSProperties, memo } from "preact/compat"; | import { CSSProperties, memo } from "preact/compat"; | ||||||
|  | import { useUniqueName } from "./hooks"; | ||||||
|  |  | ||||||
| interface FormCheckboxProps { | interface FormCheckboxProps { | ||||||
|     id?: string; |     id?: string; | ||||||
|  |     name?: string; | ||||||
|     label: string | ComponentChildren; |     label: string | ComponentChildren; | ||||||
|     /** |     /** | ||||||
|      * If set, the checkbox label will be underlined and dotted, indicating a hint. When hovered, it will show the hint text. |      * If set, the checkbox label will be underlined and dotted, indicating a hint. When hovered, it will show the hint text. | ||||||
| @@ -17,7 +19,8 @@ interface FormCheckboxProps { | |||||||
|     containerStyle?: CSSProperties; |     containerStyle?: CSSProperties; | ||||||
| } | } | ||||||
|  |  | ||||||
| const FormCheckbox = memo(({ id, disabled, label, currentValue, onChange, hint, containerStyle }: FormCheckboxProps) => { | const FormCheckbox = memo(({ name, id: _id, disabled, label, currentValue, onChange, hint, containerStyle }: FormCheckboxProps) => { | ||||||
|  |     const id = _id ?? useUniqueName(name); | ||||||
|     const labelRef = useRef<HTMLLabelElement>(null); |     const labelRef = useRef<HTMLLabelElement>(null); | ||||||
|  |  | ||||||
|     // Fix: Move useEffect outside conditional |     // Fix: Move useEffect outside conditional | ||||||
|   | |||||||
| @@ -29,3 +29,15 @@ export default function FormGroup({ name, label, title, className, children, des | |||||||
|         </div> |         </div> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Similar to {@link FormGroup} but allows more than one child. Due to this behaviour, there is no automatic ID assignment. | ||||||
|  |  */ | ||||||
|  | export function FormMultiGroup({ label, children }: { label: string, children: ComponentChildren }) { | ||||||
|  |     return ( | ||||||
|  |         <div className={`form-group`}> | ||||||
|  |             {label && <label>{label}</label>} | ||||||
|  |             {children} | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | } | ||||||
| @@ -31,9 +31,9 @@ export default function FormRadioGroup({ values, ...restProps }: FormRadioProps) | |||||||
|  |  | ||||||
| export function FormInlineRadioGroup({ values, ...restProps }: FormRadioProps) { | export function FormInlineRadioGroup({ values, ...restProps }: FormRadioProps) { | ||||||
|     return ( |     return ( | ||||||
|         <> |         <div role="group"> | ||||||
|             {values.map(({ value, label }) => (<FormRadio value={value} label={label} {...restProps} />))} |             {values.map(({ value, label }) => (<FormRadio value={value} label={label} {...restProps} />))} | ||||||
|         </> |         </div> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import type { RefObject } from "preact"; | |||||||
| import type { CSSProperties } from "preact/compat"; | import type { CSSProperties } from "preact/compat"; | ||||||
|  |  | ||||||
| interface NoteAutocompleteProps {     | interface NoteAutocompleteProps {     | ||||||
|  |     id?: string; | ||||||
|     inputRef?: RefObject<HTMLInputElement>; |     inputRef?: RefObject<HTMLInputElement>; | ||||||
|     text?: string; |     text?: string; | ||||||
|     placeholder?: string; |     placeholder?: string; | ||||||
| @@ -18,7 +19,7 @@ interface NoteAutocompleteProps { | |||||||
|     noteId?: string; |     noteId?: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| export default function NoteAutocomplete({ inputRef: _ref, text, placeholder, onChange, onTextChange, container, containerStyle, opts, noteId, noteIdChanged }: NoteAutocompleteProps) { | export default function NoteAutocomplete({ id, inputRef: _ref, text, placeholder, onChange, onTextChange, container, containerStyle, opts, noteId, noteIdChanged }: NoteAutocompleteProps) { | ||||||
|     const ref = _ref ?? useRef<HTMLInputElement>(null); |     const ref = _ref ?? useRef<HTMLInputElement>(null); | ||||||
|      |      | ||||||
|     useEffect(() => { |     useEffect(() => { | ||||||
| @@ -74,6 +75,7 @@ export default function NoteAutocomplete({ inputRef: _ref, text, placeholder, on | |||||||
|     return ( |     return ( | ||||||
|         <div className="input-group" style={containerStyle}> |         <div className="input-group" style={containerStyle}> | ||||||
|             <input |             <input | ||||||
|  |                 id={id} | ||||||
|                 ref={ref} |                 ref={ref} | ||||||
|                 className="note-autocomplete form-control" |                 className="note-autocomplete form-control" | ||||||
|                 placeholder={placeholder ?? t("add_link.search_note")} /> |                 placeholder={placeholder ?? t("add_link.search_note")} /> | ||||||
|   | |||||||
| @@ -190,6 +190,6 @@ export function useTriliumOptions<T extends OptionNames>(...names: T[]) { | |||||||
|  * @param prefix a prefix to add to the unique name. |  * @param prefix a prefix to add to the unique name. | ||||||
|  * @returns a name with the given prefix and a random alpanumeric string appended to it. |  * @returns a name with the given prefix and a random alpanumeric string appended to it. | ||||||
|  */ |  */ | ||||||
| export function useUniqueName(prefix: string) { | export function useUniqueName(prefix?: string) { | ||||||
|     return useMemo(() => prefix + "-" + utils.randomString(10), [ prefix]); |     return useMemo(() => (prefix ? prefix + "-" : "") + utils.randomString(10), [ prefix ]); | ||||||
| } | } | ||||||
| @@ -28,9 +28,8 @@ function EnableAiSettings() { | |||||||
|     return ( |     return ( | ||||||
|         <>             |         <>             | ||||||
|             <OptionsSection title={t("ai_llm.title")}>                             |             <OptionsSection title={t("ai_llm.title")}>                             | ||||||
|                 <FormGroup description={t("ai_llm.enable_ai_description")}> |                 <FormGroup name="ai-enabled" description={t("ai_llm.enable_ai_description")}> | ||||||
|                     <FormCheckbox                         |                     <FormCheckbox                         | ||||||
|                         name="ai-enabled" |  | ||||||
|                         label={t("ai_llm.enable_ai_features")} |                         label={t("ai_llm.enable_ai_features")} | ||||||
|                         currentValue={aiEnabled} onChange={(isEnabled) => { |                         currentValue={aiEnabled} onChange={(isEnabled) => { | ||||||
|                             if (isEnabled) { |                             if (isEnabled) { | ||||||
| @@ -56,7 +55,7 @@ function ProviderSettings() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("ai_llm.provider_configuration")}> |         <OptionsSection title={t("ai_llm.provider_configuration")}> | ||||||
|             <FormGroup label={t("ai_llm.selected_provider")} description={t("ai_llm.selected_provider_description")}> |             <FormGroup name="selected-provider" label={t("ai_llm.selected_provider")} description={t("ai_llm.selected_provider_description")}> | ||||||
|                 <FormSelect |                 <FormSelect | ||||||
|                     values={[ |                     values={[ | ||||||
|                         { value: "", text: t("ai_llm.select_provider") }, |                         { value: "", text: t("ai_llm.select_provider") }, | ||||||
| @@ -103,15 +102,14 @@ function ProviderSettings() { | |||||||
|                     <></> |                     <></> | ||||||
|             }     |             }     | ||||||
|  |  | ||||||
|             <FormGroup label={t("ai_llm.temperature")} description={t("ai_llm.temperature_description")}> |             <FormGroup name="ai-temperature" label={t("ai_llm.temperature")} description={t("ai_llm.temperature_description")}> | ||||||
|                 <FormTextBox |                 <FormTextBox | ||||||
|                     name="ai-temperature" |  | ||||||
|                     type="number" min="0" max="2" step="0.1" |                     type="number" min="0" max="2" step="0.1" | ||||||
|                     currentValue={aiTemperature} onChange={setAiTemperature} |                     currentValue={aiTemperature} onChange={setAiTemperature} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("ai_llm.system_prompt")} description={t("ai_llm.system_prompt_description")}> |             <FormGroup name="system-prompt" label={t("ai_llm.system_prompt")} description={t("ai_llm.system_prompt_description")}> | ||||||
|                 <FormTextArea |                 <FormTextArea | ||||||
|                     rows={3} |                     rows={3} | ||||||
|                     currentValue={aiSystemPrompt} onBlur={setAiSystemPrompt} |                     currentValue={aiSystemPrompt} onBlur={setAiSystemPrompt} | ||||||
| @@ -149,7 +147,7 @@ function SingleProviderSettings({ provider, title, apiKeyDescription, baseUrlDes | |||||||
|                     {!isValid && <Admonition type="caution">{validationErrorMessage}</Admonition> } |                     {!isValid && <Admonition type="caution">{validationErrorMessage}</Admonition> } | ||||||
|  |  | ||||||
|                     {apiKeyOption && ( |                     {apiKeyOption && ( | ||||||
|                         <FormGroup label={t("ai_llm.api_key")} description={apiKeyDescription}> |                         <FormGroup name="api-key" label={t("ai_llm.api_key")} description={apiKeyDescription}> | ||||||
|                             <FormTextBox |                             <FormTextBox | ||||||
|                                 type="password" autoComplete="off" |                                 type="password" autoComplete="off" | ||||||
|                                 currentValue={apiKey} onChange={setApiKey} |                                 currentValue={apiKey} onChange={setApiKey} | ||||||
| @@ -157,14 +155,14 @@ function SingleProviderSettings({ provider, title, apiKeyDescription, baseUrlDes | |||||||
|                         </FormGroup> |                         </FormGroup> | ||||||
|                     )} |                     )} | ||||||
|  |  | ||||||
|                     <FormGroup label={t("ai_llm.url")} description={baseUrlDescription}> |                     <FormGroup name="base-url" label={t("ai_llm.url")} description={baseUrlDescription}> | ||||||
|                         <FormTextBox |                         <FormTextBox | ||||||
|                             currentValue={baseUrl ?? "https://api.openai.com/v1"} onChange={setBaseUrl} |                             currentValue={baseUrl ?? "https://api.openai.com/v1"} onChange={setBaseUrl} | ||||||
|                         /> |                         /> | ||||||
|                     </FormGroup> |                     </FormGroup> | ||||||
|  |  | ||||||
|                     {isValid &&  |                     {isValid &&  | ||||||
|                         <FormGroup label={t("ai_llm.model")} description={modelDescription}> |                         <FormGroup name="model" label={t("ai_llm.model")} description={modelDescription}> | ||||||
|                             <ModelSelector provider={provider} baseUrl={baseUrl} modelOption={modelOption} /> |                             <ModelSelector provider={provider} baseUrl={baseUrl} modelOption={modelOption} /> | ||||||
|                         </FormGroup> |                         </FormGroup> | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -189,7 +189,7 @@ function Font({ title, fontFamilyOption, fontSizeOption }: { title: string, font | |||||||
|         <> |         <> | ||||||
|             <h5>{title}</h5> |             <h5>{title}</h5> | ||||||
|             <div className="row"> |             <div className="row"> | ||||||
|                 <FormGroup className="col-md-4" label={t("fonts.font_family")}> |                 <FormGroup name="font-family" className="col-md-4" label={t("fonts.font_family")}> | ||||||
|                     <FormSelectWithGroups |                     <FormSelectWithGroups | ||||||
|                         values={FONT_FAMILIES} |                         values={FONT_FAMILIES} | ||||||
|                         currentValue={fontFamily} onChange={setFontFamily} |                         currentValue={fontFamily} onChange={setFontFamily} | ||||||
| @@ -197,7 +197,7 @@ function Font({ title, fontFamilyOption, fontSizeOption }: { title: string, font | |||||||
|                     /> |                     /> | ||||||
|                 </FormGroup> |                 </FormGroup> | ||||||
|  |  | ||||||
|                 <FormGroup className="col-md-6" label={t("fonts.size")}> |                 <FormGroup name="font-size" className="col-md-6" label={t("fonts.size")}> | ||||||
|                     <FormTextBoxWithUnit |                     <FormTextBoxWithUnit | ||||||
|                         name="tree-font-size" |                         name="tree-font-size" | ||||||
|                         type="number" min={50} max={200} step={10} |                         type="number" min={50} max={200} step={10} | ||||||
| @@ -217,7 +217,7 @@ function ElectronIntegration() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("electron_integration.desktop-application")}> |         <OptionsSection title={t("electron_integration.desktop-application")}> | ||||||
|             <FormGroup label={t("electron_integration.zoom-factor")} description={t("zoom_factor.description")}> |             <FormGroup name="zoom-factor" label={t("electron_integration.zoom-factor")} description={t("zoom_factor.description")}> | ||||||
|                 <FormTextBox |                 <FormTextBox | ||||||
|                     type="number" |                     type="number" | ||||||
|                     min="0.3" max="2.0" step="0.1"                     |                     min="0.3" max="2.0" step="0.1"                     | ||||||
| @@ -226,16 +226,16 @@ function ElectronIntegration() { | |||||||
|             </FormGroup> |             </FormGroup> | ||||||
|             <hr/> |             <hr/> | ||||||
|  |  | ||||||
|             <FormGroup description={t("electron_integration.native-title-bar-description")}> |             <FormGroup name="native-title-bar" description={t("electron_integration.native-title-bar-description")}> | ||||||
|                 <FormCheckbox |                 <FormCheckbox | ||||||
|                     name="native-title-bar" label={t("electron_integration.native-title-bar")} |                     label={t("electron_integration.native-title-bar")} | ||||||
|                     currentValue={nativeTitleBarVisible} onChange={setNativeTitleBarVisible} |                     currentValue={nativeTitleBarVisible} onChange={setNativeTitleBarVisible} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup description={t("electron_integration.background-effects-description")}> |             <FormGroup name="background-effects" description={t("electron_integration.background-effects-description")}> | ||||||
|                 <FormCheckbox |                 <FormCheckbox | ||||||
|                     name="background-effects" label={t("electron_integration.background-effects")} |                     label={t("electron_integration.background-effects")} | ||||||
|                     currentValue={backgroundEffects} onChange={setBackgroundEffects} |                     currentValue={backgroundEffects} onChange={setBackgroundEffects} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
| @@ -253,9 +253,8 @@ function MaxContentWidth() { | |||||||
|             <FormText>{t("max_content_width.default_description")}</FormText> |             <FormText>{t("max_content_width.default_description")}</FormText> | ||||||
|  |  | ||||||
|             <Column md={6}> |             <Column md={6}> | ||||||
|                 <FormGroup label={t("max_content_width.max_width_label")}> |                 <FormGroup name="max-content-width" label={t("max_content_width.max_width_label")}> | ||||||
|                     <FormTextBoxWithUnit                         |                     <FormTextBoxWithUnit                         | ||||||
|                         name="max-content-width" |  | ||||||
|                         type="number" min={MIN_CONTENT_WIDTH} step="10"  |                         type="number" min={MIN_CONTENT_WIDTH} step="10"  | ||||||
|                         currentValue={maxContentWidth} onChange={setMaxContentWidth} |                         currentValue={maxContentWidth} onChange={setMaxContentWidth} | ||||||
|                         unit={t("max_content_width.max_width_unit")} |                         unit={t("max_content_width.max_width_unit")} | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import server from "../../../services/server"; | |||||||
| import toast from "../../../services/toast"; | import toast from "../../../services/toast"; | ||||||
| import Button from "../../react/Button"; | import Button from "../../react/Button"; | ||||||
| import FormCheckbox from "../../react/FormCheckbox"; | import FormCheckbox from "../../react/FormCheckbox"; | ||||||
| import FormGroup from "../../react/FormGroup"; | import FormGroup, { FormMultiGroup } from "../../react/FormGroup"; | ||||||
| import FormText from "../../react/FormText"; | import FormText from "../../react/FormText"; | ||||||
| import { useTriliumOptionBool } from "../../react/hooks"; | import { useTriliumOptionBool } from "../../react/hooks"; | ||||||
| import OptionsSection from "./components/OptionsSection"; | import OptionsSection from "./components/OptionsSection"; | ||||||
| @@ -45,7 +45,7 @@ export function AutomaticBackup() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("backup.automatic_backup")}> |         <OptionsSection title={t("backup.automatic_backup")}> | ||||||
|             <FormGroup label={t("backup.automatic_backup_description")}> |             <FormMultiGroup label={t("backup.automatic_backup_description")}> | ||||||
|                 <FormCheckbox |                 <FormCheckbox | ||||||
|                     name="daily-backup-enabled" |                     name="daily-backup-enabled" | ||||||
|                     label={t("backup.enable_daily_backup")} |                     label={t("backup.enable_daily_backup")} | ||||||
| @@ -63,7 +63,7 @@ export function AutomaticBackup() { | |||||||
|                     label={t("backup.enable_monthly_backup")} |                     label={t("backup.enable_monthly_backup")} | ||||||
|                     currentValue={monthlyBackupEnabled} onChange={setMonthlyBackupEnabled} |                     currentValue={monthlyBackupEnabled} onChange={setMonthlyBackupEnabled} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormMultiGroup> | ||||||
|  |  | ||||||
|             <FormText>{t("backup.backup_recommendation")}</FormText> |             <FormText>{t("backup.backup_recommendation")}</FormText> | ||||||
|         </OptionsSection> |         </OptionsSection> | ||||||
|   | |||||||
| @@ -32,9 +32,8 @@ function Editor() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("code-editor-options.title")}> |         <OptionsSection title={t("code-editor-options.title")}> | ||||||
|             <FormGroup description={t("vim_key_bindings.enable_vim_keybindings")}> |             <FormGroup name="vim-keymap-enabled" description={t("vim_key_bindings.enable_vim_keybindings")}> | ||||||
|                 <FormCheckbox |                 <FormCheckbox | ||||||
|                     name="vim-keymap-enabled" |  | ||||||
|                     label={t("vim_key_bindings.use_vim_keybindings_in_code_notes")} |                     label={t("vim_key_bindings.use_vim_keybindings_in_code_notes")} | ||||||
|                     currentValue={vimKeymapEnabled} onChange={setVimKeymapEnabled} |                     currentValue={vimKeymapEnabled} onChange={setVimKeymapEnabled} | ||||||
|                 /> |                 /> | ||||||
| @@ -57,7 +56,7 @@ function Appearance() { | |||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("code_theme.title")}> |         <OptionsSection title={t("code_theme.title")}> | ||||||
|             <div className="row" style={{ marginBottom: "15px" }}> |             <div className="row" style={{ marginBottom: "15px" }}> | ||||||
|                 <FormGroup label={t("code_theme.color-scheme")} className="col-md-6" style={{ marginBottom: 0 }}> |                 <FormGroup name="color-scheme" label={t("code_theme.color-scheme")} className="col-md-6" style={{ marginBottom: 0 }}> | ||||||
|                     <FormSelect  |                     <FormSelect  | ||||||
|                         values={themes} |                         values={themes} | ||||||
|                         keyProperty="id" titleProperty="name" |                         keyProperty="id" titleProperty="name" | ||||||
|   | |||||||
| @@ -18,9 +18,8 @@ export default function AutoReadOnlySize({ label, option }: AutoReadOnlySizeProp | |||||||
|         <OptionsSection title={t("text_auto_read_only_size.title")}> |         <OptionsSection title={t("text_auto_read_only_size.title")}> | ||||||
|             <FormText>{t("text_auto_read_only_size.description")}</FormText> |             <FormText>{t("text_auto_read_only_size.description")}</FormText> | ||||||
|  |  | ||||||
|             <FormGroup label={label}> |             <FormGroup name="auto-readonly-size-text" label={label}> | ||||||
|                 <FormTextBoxWithUnit                     |                 <FormTextBoxWithUnit                     | ||||||
|                     name="auto-readonly-size-text" |  | ||||||
|                     type="number" min={0} |                     type="number" min={0} | ||||||
|                     unit={t("text_auto_read_only_size.unit")} |                     unit={t("text_auto_read_only_size.unit")} | ||||||
|                     currentValue={autoReadonlyOpt} onChange={setAutoReadonlyOpt} |                     currentValue={autoReadonlyOpt} onChange={setAutoReadonlyOpt} | ||||||
|   | |||||||
| @@ -36,11 +36,11 @@ function LocalizationOptions() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("i18n.title")}> |         <OptionsSection title={t("i18n.title")}> | ||||||
|             <OptionsRow label={t("i18n.language")}> |             <OptionsRow name="language" label={t("i18n.language")}> | ||||||
|                 <LocaleSelector locales={uiLocales} currentValue={locale} onChange={setLocale} /> |                 <LocaleSelector locales={uiLocales} currentValue={locale} onChange={setLocale} /> | ||||||
|             </OptionsRow> |             </OptionsRow> | ||||||
|  |  | ||||||
|             {isElectron() && <OptionsRow label={t("i18n.formatting-locale")}> |             {isElectron() && <OptionsRow name="formatting-locale" label={t("i18n.formatting-locale")}> | ||||||
|                 <LocaleSelector locales={contentLocales} currentValue={formattingLocale} onChange={setFormattingLocale} /> |                 <LocaleSelector locales={contentLocales} currentValue={formattingLocale} onChange={setFormattingLocale} /> | ||||||
|             </OptionsRow>} |             </OptionsRow>} | ||||||
|  |  | ||||||
| @@ -65,8 +65,7 @@ function DateSettings() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <> |         <> | ||||||
|             <OptionsRow label={t("i18n.first-day-of-the-week")}> |             <OptionsRow name="first-day-of-week" label={t("i18n.first-day-of-the-week")}> | ||||||
|                 <div role="group"> |  | ||||||
|                 <FormInlineRadioGroup |                 <FormInlineRadioGroup | ||||||
|                     name="first-day-of-week" |                     name="first-day-of-week" | ||||||
|                     values={[ |                     values={[ | ||||||
| @@ -75,11 +74,9 @@ function DateSettings() { | |||||||
|                     ]} |                     ]} | ||||||
|                     currentValue={firstDayOfWeek} onChange={setFirstDayOfWeek} |                     currentValue={firstDayOfWeek} onChange={setFirstDayOfWeek} | ||||||
|                 /> |                 /> | ||||||
|                 </div> |  | ||||||
|             </OptionsRow>   |             </OptionsRow>   | ||||||
|  |  | ||||||
|             <OptionsRow label={t("i18n.first-week-of-the-year")}> |             <OptionsRow name="first-week-of-year" label={t("i18n.first-week-of-the-year")}> | ||||||
|                 <div role="group"> |  | ||||||
|                 <FormRadioGroup |                 <FormRadioGroup | ||||||
|                     name="first-week-of-year" |                     name="first-week-of-year" | ||||||
|                     currentValue={firstWeekOfYear} onChange={setFirstWeekOfYear} |                     currentValue={firstWeekOfYear} onChange={setFirstWeekOfYear} | ||||||
| @@ -89,10 +86,9 @@ function DateSettings() { | |||||||
|                         { value: "2", label: t("i18n.first-week-has-minimum-days") } |                         { value: "2", label: t("i18n.first-week-has-minimum-days") } | ||||||
|                     ]} |                     ]} | ||||||
|                 /> |                 /> | ||||||
|                 </div> |  | ||||||
|             </OptionsRow> |             </OptionsRow> | ||||||
|  |  | ||||||
|             {firstWeekOfYear === "2" && <OptionsRow label={t("i18n.min-days-in-first-week")}> |             {firstWeekOfYear === "2" && <OptionsRow name="min-days-in-first-week" label={t("i18n.min-days-in-first-week")}> | ||||||
|                 <FormSelect |                 <FormSelect | ||||||
|                     keyProperty="days" |                     keyProperty="days" | ||||||
|                     currentValue={minDaysInFirstWeek} onChange={setMinDaysInFirstWeek} |                     currentValue={minDaysInFirstWeek} onChange={setMinDaysInFirstWeek} | ||||||
| @@ -109,7 +105,7 @@ function DateSettings() { | |||||||
|                 {t("i18n.first-week-warning")} |                 {t("i18n.first-week-warning")} | ||||||
|             </Admonition> |             </Admonition> | ||||||
|  |  | ||||||
|             <OptionsRow centered> |             <OptionsRow name="restart" centered> | ||||||
|                 <Button |                 <Button | ||||||
|                     text={t("electron_integration.restart-app-button")} |                     text={t("electron_integration.restart-app-button")} | ||||||
|                     size="micro" |                     size="micro" | ||||||
|   | |||||||
| @@ -13,9 +13,8 @@ export default function ImageSettings() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("images.images_section_title")}> |         <OptionsSection title={t("images.images_section_title")}> | ||||||
|             <FormGroup description={t("images.download_images_description")}> |             <FormGroup name="download-images-automatically" description={t("images.download_images_description")}> | ||||||
|                 <FormCheckbox                     |                 <FormCheckbox                     | ||||||
|                     name="download-images-automatically" |  | ||||||
|                     label={t("images.download_images_automatically")} |                     label={t("images.download_images_automatically")} | ||||||
|                     currentValue={downloadImagesAutomatically} onChange={setDownloadImagesAutomatically} |                     currentValue={downloadImagesAutomatically} onChange={setDownloadImagesAutomatically} | ||||||
|                 /> |                 /> | ||||||
| @@ -29,18 +28,16 @@ export default function ImageSettings() { | |||||||
|                 currentValue={compressImages} onChange={setCompressImages} |                 currentValue={compressImages} onChange={setCompressImages} | ||||||
|             /> |             /> | ||||||
|  |  | ||||||
|             <FormGroup label={t("images.max_image_dimensions")} disabled={!compressImages}> |             <FormGroup name="image-max-width-height" label={t("images.max_image_dimensions")} disabled={!compressImages}> | ||||||
|                 <FormTextBoxWithUnit |                 <FormTextBoxWithUnit | ||||||
|                     name="image-max-width-height" |  | ||||||
|                     type="number" min="1" |                     type="number" min="1" | ||||||
|                     unit={t("images.max_image_dimensions_unit")} |                     unit={t("images.max_image_dimensions_unit")} | ||||||
|                     currentValue={imageMaxWidthHeight} onChange={setImageMaxWidthHeight} |                     currentValue={imageMaxWidthHeight} onChange={setImageMaxWidthHeight} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("images.jpeg_quality_description")} disabled={!compressImages}> |             <FormGroup name="image-jpeg-quality" label={t("images.jpeg_quality_description")} disabled={!compressImages}> | ||||||
|                 <FormTextBoxWithUnit                     |                 <FormTextBoxWithUnit                     | ||||||
|                     name="image-jpeg-quality" |  | ||||||
|                     min="10" max="100" type="number" |                     min="10" max="100" type="number" | ||||||
|                     unit={t("units.percentage")} |                     unit={t("units.percentage")} | ||||||
|                     currentValue={imageJpegQuality} onChange={setImageJpegQuality} |                     currentValue={imageJpegQuality} onChange={setImageJpegQuality} | ||||||
|   | |||||||
| @@ -4,7 +4,6 @@ import FormText from "../../react/FormText" | |||||||
| import OptionsSection from "./components/OptionsSection" | import OptionsSection from "./components/OptionsSection" | ||||||
| import FormCheckbox from "../../react/FormCheckbox" | import FormCheckbox from "../../react/FormCheckbox" | ||||||
| import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks" | import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks" | ||||||
| import FormGroup from "../../react/FormGroup" |  | ||||||
| import { FormInlineRadioGroup } from "../../react/FormRadioGroup" | import { FormInlineRadioGroup } from "../../react/FormRadioGroup" | ||||||
| import Admonition from "../../react/Admonition" | import Admonition from "../../react/Admonition" | ||||||
| import { useCallback, useEffect, useMemo, useState } from "preact/hooks" | import { useCallback, useEffect, useMemo, useState } from "preact/hooks" | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import FormText from "../../react/FormText"; | |||||||
| import OptionsSection from "./components/OptionsSection"; | import OptionsSection from "./components/OptionsSection"; | ||||||
| import TimeSelector from "./components/TimeSelector"; | import TimeSelector from "./components/TimeSelector"; | ||||||
| import { useMemo } from "preact/hooks"; | import { useMemo } from "preact/hooks"; | ||||||
| import { useTriliumOption, useTriliumOptionBool, useTriliumOptionInt, useTriliumOptionJson } from "../../react/hooks"; | import { useTriliumOption, useTriliumOptionBool, useTriliumOptionJson } from "../../react/hooks"; | ||||||
| import { SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons"; | import { SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons"; | ||||||
| import FormCheckbox from "../../react/FormCheckbox"; | import FormCheckbox from "../../react/FormCheckbox"; | ||||||
| import FormGroup from "../../react/FormGroup"; | import FormGroup from "../../react/FormGroup"; | ||||||
| @@ -51,7 +51,7 @@ function SearchEngineSettings() { | |||||||
|         <OptionsSection title={t("search_engine.title")}> |         <OptionsSection title={t("search_engine.title")}> | ||||||
|             <FormText>{t("search_engine.custom_search_engine_info")}</FormText> |             <FormText>{t("search_engine.custom_search_engine_info")}</FormText> | ||||||
|  |  | ||||||
|             <FormGroup label={t("search_engine.predefined_templates_label")}> |             <FormGroup name="predefined-search-engine" label={t("search_engine.predefined_templates_label")}> | ||||||
|                 <FormSelect |                 <FormSelect | ||||||
|                     values={searchEngines} |                     values={searchEngines} | ||||||
|                     currentValue={customSearchEngineUrl} |                     currentValue={customSearchEngineUrl} | ||||||
| @@ -68,14 +68,14 @@ function SearchEngineSettings() { | |||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("search_engine.custom_name_label")}> |             <FormGroup name="custom-name" label={t("search_engine.custom_name_label")}> | ||||||
|                 <FormTextBox |                 <FormTextBox | ||||||
|                     currentValue={customSearchEngineName} onChange={setCustomSearchEngineName} |                     currentValue={customSearchEngineName} onChange={setCustomSearchEngineName} | ||||||
|                     placeholder={t("search_engine.custom_name_placeholder")} |                     placeholder={t("search_engine.custom_name_placeholder")} | ||||||
|                 /> |                 /> | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup label={t("search_engine.custom_url_label")}> |             <FormGroup name="custom-url" label={t("search_engine.custom_url_label")}> | ||||||
|                 <FormTextBox |                 <FormTextBox | ||||||
|                     currentValue={customSearchEngineUrl} onChange={setCustomSearchEngineUrl} |                     currentValue={customSearchEngineUrl} onChange={setCustomSearchEngineUrl} | ||||||
|                     placeholder={t("search_engine.custom_url_placeholder")} |                     placeholder={t("search_engine.custom_url_placeholder")} | ||||||
| @@ -104,7 +104,7 @@ function NoteErasureTimeout() { | |||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("note_erasure_timeout.note_erasure_timeout_title")}> |         <OptionsSection title={t("note_erasure_timeout.note_erasure_timeout_title")}> | ||||||
|             <FormText>{t("note_erasure_timeout.note_erasure_description")}</FormText> |             <FormText>{t("note_erasure_timeout.note_erasure_description")}</FormText> | ||||||
|             <FormGroup label={t("note_erasure_timeout.erase_notes_after")}> |             <FormGroup name="erase-entities-after" label={t("note_erasure_timeout.erase_notes_after")}> | ||||||
|                 <TimeSelector            |                 <TimeSelector            | ||||||
|                     name="erase-entities-after"          |                     name="erase-entities-after"          | ||||||
|                     optionValueId="eraseEntitiesAfterTimeInSeconds" optionTimeScaleId="eraseEntitiesAfterTimeScale" |                     optionValueId="eraseEntitiesAfterTimeInSeconds" optionTimeScaleId="eraseEntitiesAfterTimeScale" | ||||||
| @@ -128,7 +128,7 @@ function AttachmentErasureTimeout() { | |||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("attachment_erasure_timeout.attachment_erasure_timeout")}> |         <OptionsSection title={t("attachment_erasure_timeout.attachment_erasure_timeout")}> | ||||||
|             <FormText>{t("attachment_erasure_timeout.attachment_auto_deletion_description")}</FormText> |             <FormText>{t("attachment_erasure_timeout.attachment_auto_deletion_description")}</FormText> | ||||||
|             <FormGroup label={t("attachment_erasure_timeout.erase_attachments_after")}> |             <FormGroup name="erase-unused-attachments-after" label={t("attachment_erasure_timeout.erase_attachments_after")}> | ||||||
|                 <TimeSelector |                 <TimeSelector | ||||||
|                     name="erase-unused-attachments-after" |                     name="erase-unused-attachments-after" | ||||||
|                     optionValueId="eraseUnusedAttachmentsAfterSeconds" optionTimeScaleId="eraseUnusedAttachmentsAfterTimeScale" |                     optionValueId="eraseUnusedAttachmentsAfterSeconds" optionTimeScaleId="eraseUnusedAttachmentsAfterTimeScale" | ||||||
| @@ -157,7 +157,7 @@ function RevisionSnapshotInterval() { | |||||||
|                     components={{ doc: <a href="https://triliumnext.github.io/Docs/Wiki/note-revisions.html" class="external" />}} |                     components={{ doc: <a href="https://triliumnext.github.io/Docs/Wiki/note-revisions.html" class="external" />}} | ||||||
|                 /> |                 /> | ||||||
|             </FormText> |             </FormText> | ||||||
|             <FormGroup label={t("revisions_snapshot_interval.snapshot_time_interval_label")}> |             <FormGroup name="revision-snapshot-time-interval" label={t("revisions_snapshot_interval.snapshot_time_interval_label")}> | ||||||
|                 <TimeSelector |                 <TimeSelector | ||||||
|                     name="revision-snapshot-time-interval" |                     name="revision-snapshot-time-interval" | ||||||
|                     optionValueId="revisionSnapshotTimeInterval" optionTimeScaleId="revisionSnapshotTimeIntervalTimeScale" |                     optionValueId="revisionSnapshotTimeInterval" optionTimeScaleId="revisionSnapshotTimeIntervalTimeScale" | ||||||
| @@ -175,9 +175,8 @@ function RevisionSnapshotLimit() { | |||||||
|         <OptionsSection title={t("revisions_snapshot_limit.note_revisions_snapshot_limit_title")}> |         <OptionsSection title={t("revisions_snapshot_limit.note_revisions_snapshot_limit_title")}> | ||||||
|             <FormText>{t("revisions_snapshot_limit.note_revisions_snapshot_limit_description")}</FormText> |             <FormText>{t("revisions_snapshot_limit.note_revisions_snapshot_limit_description")}</FormText> | ||||||
|  |  | ||||||
|             <FormGroup> |             <FormGroup name="revision-snapshot-number-limit"> | ||||||
|                 <FormTextBoxWithUnit                     |                 <FormTextBoxWithUnit                     | ||||||
|                     name="revision-snapshot-number-limit"   |  | ||||||
|                     type="number" min={-1} |                     type="number" min={-1} | ||||||
|                     currentValue={revisionSnapshotNumberLimit} |                     currentValue={revisionSnapshotNumberLimit} | ||||||
|                     unit={t("revisions_snapshot_limit.snapshot_number_limit_unit")} |                     unit={t("revisions_snapshot_limit.snapshot_number_limit_unit")} | ||||||
| @@ -246,9 +245,8 @@ function ShareSettings() { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("share.title")}> |         <OptionsSection title={t("share.title")}> | ||||||
|             <FormGroup description={t("share.redirect_bare_domain_description")}> |             <FormGroup name="redirectBareDomain" description={t("share.redirect_bare_domain_description")}> | ||||||
|                 <FormCheckbox                     |                 <FormCheckbox                     | ||||||
|                     name="redirectBareDomain" |  | ||||||
|                     label={t(t("share.redirect_bare_domain"))}    |                     label={t(t("share.redirect_bare_domain"))}    | ||||||
|                     currentValue={redirectBareDomain} |                     currentValue={redirectBareDomain} | ||||||
|                     onChange={async value => { |                     onChange={async value => { | ||||||
| @@ -269,9 +267,8 @@ function ShareSettings() { | |||||||
|                 />  |                 />  | ||||||
|             </FormGroup> |             </FormGroup> | ||||||
|  |  | ||||||
|             <FormGroup description={t("share.show_login_link_description")}> |             <FormGroup name="showLoginInShareTheme" description={t("share.show_login_link_description")}> | ||||||
|                 <FormCheckbox                     |                 <FormCheckbox                     | ||||||
|                     name="showLoginInShareTheme" |  | ||||||
|                     label={t("share.show_login_link")} |                     label={t("share.show_login_link")} | ||||||
|                     currentValue={showLogInShareTheme} onChange={setShowLogInShareTheme} |                     currentValue={showLogInShareTheme} onChange={setShowLogInShareTheme} | ||||||
|                 /> |                 /> | ||||||
|   | |||||||
| @@ -72,25 +72,22 @@ function ChangePassword() { | |||||||
|                     toast.showError(result.message); |                     toast.showError(result.message); | ||||||
|                 } |                 } | ||||||
|             }}> |             }}> | ||||||
|                 <FormGroup label={t("password.old_password")}> |                 <FormGroup name="old-password" label={t("password.old_password")}> | ||||||
|                     <FormTextBox                         |                     <FormTextBox                         | ||||||
|                         name="old-password" |  | ||||||
|                         type="password" |                         type="password" | ||||||
|                         currentValue={oldPassword} onChange={setOldPassword} |                         currentValue={oldPassword} onChange={setOldPassword} | ||||||
|                     />                     |                     />                     | ||||||
|                 </FormGroup> |                 </FormGroup> | ||||||
|  |  | ||||||
|                 <FormGroup label={t("password.new_password")}> |                 <FormGroup name="new-password1" label={t("password.new_password")}> | ||||||
|                     <FormTextBox                         |                     <FormTextBox                         | ||||||
|                         name="new-password1" |  | ||||||
|                         type="password" |                         type="password" | ||||||
|                         currentValue={newPassword1} onChange={setNewPassword1} |                         currentValue={newPassword1} onChange={setNewPassword1} | ||||||
|                     /> |                     /> | ||||||
|                 </FormGroup> |                 </FormGroup> | ||||||
|  |  | ||||||
|                 <FormGroup label={t("password.new_password_confirmation")}> |                 <FormGroup name="new-password2" label={t("password.new_password_confirmation")}> | ||||||
|                     <FormTextBox                         |                     <FormTextBox                         | ||||||
|                         name="new-password2" |  | ||||||
|                         type="password" |                         type="password" | ||||||
|                         currentValue={newPassword2} onChange={setNewPassword2} |                         currentValue={newPassword2} onChange={setNewPassword2} | ||||||
|                     /> |                     /> | ||||||
| @@ -114,7 +111,7 @@ function ProtectedSessionTimeout() { | |||||||
|                 <a class="tn-link" href="https://triliumnext.github.io/Docs/Wiki/protected-notes.html" className="external">{t("password.wiki")}</a> {t("password.for_more_info")} |                 <a class="tn-link" href="https://triliumnext.github.io/Docs/Wiki/protected-notes.html" className="external">{t("password.wiki")}</a> {t("password.for_more_info")} | ||||||
|             </FormText> |             </FormText> | ||||||
|              |              | ||||||
|             <FormGroup label={t("password.protected_session_timeout_label")}> |             <FormGroup name="protected-session-timeout" label={t("password.protected_session_timeout_label")}> | ||||||
|                 <TimeSelector                     |                 <TimeSelector                     | ||||||
|                     name="protected-session-timeout" |                     name="protected-session-timeout" | ||||||
|                     optionValueId="protectedSessionTimeout" optionTimeScaleId="protectedSessionTimeoutTimeScale" |                     optionValueId="protectedSessionTimeout" optionTimeScaleId="protectedSessionTimeoutTimeScale" | ||||||
|   | |||||||
| @@ -81,9 +81,8 @@ export default function ShortcutSettings() { | |||||||
|                 <RawHtml html={t("shortcuts.electron_documentation")} /> |                 <RawHtml html={t("shortcuts.electron_documentation")} /> | ||||||
|             </FormText> |             </FormText> | ||||||
|  |  | ||||||
|             <FormGroup> |             <FormGroup name="keyboard-shortcut-filter"> | ||||||
|                 <FormTextBox                     |                 <FormTextBox                     | ||||||
|                     name="keyboard-shortcut-filter" |  | ||||||
|                     placeholder={t("shortcuts.type_text_to_filter")} |                     placeholder={t("shortcuts.type_text_to_filter")} | ||||||
|                     currentValue={filter} onChange={(value) => setFilter(value.toLowerCase())} |                     currentValue={filter} onChange={(value) => setFilter(value.toLowerCase())} | ||||||
|                 /> |                 /> | ||||||
|   | |||||||
| @@ -39,9 +39,8 @@ function ElectronSpellcheckSettings() { | |||||||
|                 currentValue={spellCheckEnabled} onChange={setSpellCheckEnabled} |                 currentValue={spellCheckEnabled} onChange={setSpellCheckEnabled} | ||||||
|             /> |             /> | ||||||
|  |  | ||||||
|             <FormGroup label={t("spellcheck.language_code_label")} description={t("spellcheck.multiple_languages_info")}> |             <FormGroup name="spell-check-languages" label={t("spellcheck.language_code_label")} description={t("spellcheck.multiple_languages_info")}> | ||||||
|                 <FormTextBox                                         |                 <FormTextBox                                         | ||||||
|                     name="spell-check-languages" |  | ||||||
|                     placeholder={t("spellcheck.language_code_placeholder")} |                     placeholder={t("spellcheck.language_code_placeholder")} | ||||||
|                     currentValue={spellCheckLanguageCode} onChange={setSpellCheckLanguageCode} |                     currentValue={spellCheckLanguageCode} onChange={setSpellCheckLanguageCode} | ||||||
|                 /> |                 /> | ||||||
|   | |||||||
| @@ -37,28 +37,27 @@ export function SyncConfiguration() { | |||||||
|                 }); |                 }); | ||||||
|                 e.preventDefault(); |                 e.preventDefault(); | ||||||
|             }}> |             }}> | ||||||
|                 <FormGroup label={t("sync_2.server_address")}> |                 <FormGroup name="sync-server-host" label={t("sync_2.server_address")}> | ||||||
|                     <FormTextBox                         |                     <FormTextBox                         | ||||||
|                         name="sync-server-host" |  | ||||||
|                         placeholder="https://<host>:<port>" |                         placeholder="https://<host>:<port>" | ||||||
|                         currentValue={syncServerHost.current} onChange={(newValue) => syncServerHost.current = newValue} |                         currentValue={syncServerHost.current} onChange={(newValue) => syncServerHost.current = newValue} | ||||||
|                     /> |                     /> | ||||||
|                 </FormGroup> |                 </FormGroup> | ||||||
|  |  | ||||||
|                 <FormGroup label={t("sync_2.proxy_label")} description={<> |                 <FormGroup name="sync-proxy" label={t("sync_2.proxy_label")} | ||||||
|  |                     description={<> | ||||||
|                         <strong>{t("sync_2.note")}:</strong> {t("sync_2.note_description")}<br/> |                         <strong>{t("sync_2.note")}:</strong> {t("sync_2.note_description")}<br/> | ||||||
|                     <RawHtml html={t("sync_2.special_value_description")} /></>} |                         <RawHtml html={t("sync_2.special_value_description")} /> | ||||||
|  |                     </>} | ||||||
|                 > |                 > | ||||||
|                     <FormTextBox                         |                     <FormTextBox                         | ||||||
|                         name="sync-proxy" |  | ||||||
|                         placeholder="https://<host>:<port>" |                         placeholder="https://<host>:<port>" | ||||||
|                         currentValue={syncProxy.current} onChange={(newValue) => syncProxy.current = newValue} |                         currentValue={syncProxy.current} onChange={(newValue) => syncProxy.current = newValue} | ||||||
|                     /> |                     /> | ||||||
|                 </FormGroup> |                 </FormGroup> | ||||||
|  |  | ||||||
|                 <FormGroup label={t("sync_2.timeout")}> |                 <FormGroup name="sync-server-timeout" label={t("sync_2.timeout")}> | ||||||
|                     <FormTextBoxWithUnit                         |                     <FormTextBoxWithUnit                         | ||||||
|                         name="sync-server-timeout" |  | ||||||
|                         min={1} max={10000000} type="number" |                         min={1} max={10000000} type="number" | ||||||
|                         unit={t("sync_2.timeout_unit")} |                         unit={t("sync_2.timeout_unit")} | ||||||
|                         currentValue={syncServerTimeout.current} onChange={(newValue) => syncServerTimeout.current = newValue} |                         currentValue={syncServerTimeout.current} onChange={(newValue) => syncServerTimeout.current = newValue} | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ function CodeBlockStyle() { | |||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("highlighting.title")}>             |         <OptionsSection title={t("highlighting.title")}>             | ||||||
|             <div className="row" style={{ marginBottom: "15px" }}> |             <div className="row" style={{ marginBottom: "15px" }}> | ||||||
|                 <FormGroup className="col-md-6" label={t("highlighting.color-scheme")} style={{ marginBottom: 0 }}> |                 <FormGroup name="theme" className="col-md-6" label={t("highlighting.color-scheme")} style={{ marginBottom: 0 }}> | ||||||
|                     <FormSelectWithGroups |                     <FormSelectWithGroups | ||||||
|                         values={themes} |                         values={themes} | ||||||
|                         keyProperty="val" titleProperty="title" |                         keyProperty="val" titleProperty="title" | ||||||
| @@ -244,7 +244,7 @@ function TableOfContent() { | |||||||
|         <OptionsSection title={t("table_of_contents.title")}> |         <OptionsSection title={t("table_of_contents.title")}> | ||||||
|             <FormText>{t("table_of_contents.description")}</FormText> |             <FormText>{t("table_of_contents.description")}</FormText> | ||||||
|  |  | ||||||
|             <FormGroup> |             <FormGroup name="min-toc-headings"> | ||||||
|                 <FormTextBoxWithUnit |                 <FormTextBoxWithUnit | ||||||
|                     type="number" |                     type="number" | ||||||
|                     min={0} max={999999999999999} step={1} |                     min={0} max={999999999999999} step={1} | ||||||
| @@ -300,21 +300,20 @@ function DateTimeFormatOptions() { | |||||||
|                 /> |                 /> | ||||||
|             </FormText> |             </FormText> | ||||||
|              |              | ||||||
|             <FormGroup className="row align-items-center"> |             <div className="row align-items-center"> | ||||||
|               <FormGroup className="col-md-6" label={t("custom_date_time_format.format_string")}> |               <FormGroup name="custom-date-time-format" className="col-md-6" label={t("custom_date_time_format.format_string")}> | ||||||
|                   <FormTextBox                         |                   <FormTextBox                         | ||||||
|                         name="custom-date-time-format" |  | ||||||
|                         placeholder="YYYY-MM-DD HH:mm" |                         placeholder="YYYY-MM-DD HH:mm" | ||||||
|                         currentValue={customDateTimeFormat || "YYYY-MM-DD HH:mm"} onChange={setCustomDateTimeFormat} |                         currentValue={customDateTimeFormat || "YYYY-MM-DD HH:mm"} onChange={setCustomDateTimeFormat} | ||||||
|                   /> |                   /> | ||||||
|               </FormGroup> |               </FormGroup> | ||||||
|  |  | ||||||
|               <FormGroup className="col-md-6" label={t("custom_date_time_format.formatted_time")}> |               <FormGroup name="formatted-date" className="col-md-6" label={t("custom_date_time_format.formatted_time")}> | ||||||
|                 <div className="formatted-date"> |                 <div> | ||||||
|                     {formatDateTime(new Date(), customDateTimeFormat)} |                     {formatDateTime(new Date(), customDateTimeFormat)} | ||||||
|                 </div> |                 </div> | ||||||
|               </FormGroup> |               </FormGroup> | ||||||
|             </FormGroup> |             </div> | ||||||
|         </OptionsSection> |         </OptionsSection> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user