diff --git a/src/public/app/services/i18n.js b/src/public/app/services/i18n.js index f09e8d881..a777db038 100644 --- a/src/public/app/services/i18n.js +++ b/src/public/app/services/i18n.js @@ -10,7 +10,7 @@ await i18next debug: true, backend: { loadPath: `/${window.glob.assetPath}/translations/{{lng}}/{{ns}}.json` - } + } }); -export const t = i18next.t; \ No newline at end of file +export const t = i18next.t; diff --git a/src/public/app/widgets/attribute_widgets/attribute_detail.js b/src/public/app/widgets/attribute_widgets/attribute_detail.js index 3fadd3dab..ce84cd4a3 100644 --- a/src/public/app/widgets/attribute_widgets/attribute_detail.js +++ b/src/public/app/widgets/attribute_widgets/attribute_detail.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import server from "../../services/server.js"; import froca from "../../services/froca.js"; import linkService from "../../services/link.js"; @@ -68,25 +69,25 @@ const TPL = `
-
+
${t('attribute_detail.attr_detail_title')}
- +
-
+
${t('attribute_detail.attr_is_owned_by')}
- - + + - + - + - + title="${t('attribute_detail.promoted_title')}"> + - + - + - + - + - + - - + +
Name:
${t('attribute_detail.name')}
Value:${t('attribute_detail.value')}
Target note:${t('attribute_detail.target_note')}
@@ -94,12 +95,12 @@ const TPL = `
Promoted:${t('attribute_detail.promoted')}
Alias:${t('attribute_detail.promoted_alias')}
@@ -107,48 +108,48 @@ const TPL = `
Multiplicity:${t('attribute_detail.multiplicity')}
Type:${t('attribute_detail.label_type')}
Precision:${t('attribute_detail.precision')}
- digits + ${t('attribute_detail.digits')}
Inverse relation:${t('attribute_detail.inverse_relation')}
Inheritable:
${t('attribute_detail.inheritable')}
@@ -156,127 +157,112 @@ const TPL = `
+ ${t('attribute_detail.save_and_close')} + ${t('attribute_detail.delete')}
`; const DISPLAYED_NOTES = 10; const ATTR_TITLES = { - "label": "Label detail", - "label-definition": "Label definition detail", - "relation": "Relation detail", - "relation-definition": "Relation definition detail" + "label": t('attribute_detail.label'), + "label-definition": t('attribute_detail.label_definition'), + "relation": t('attribute_detail.relation'), + "relation-definition": t('attribute_detail.relation_definition') }; const ATTR_HELP = { "label": { - "disableVersioning": "disables auto-versioning. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting", - "calendarRoot": "marks note which should be used as root for day notes. Only one should be marked as such.", - "archived": "notes with this label won't be visible by default in search results (also in Jump To, Add Link dialogs etc).", - "excludeFromExport": "notes (with their sub-tree) won't be included in any note export", - "run": `defines on which events script should run. Possible values are: - `, - "runOnInstance": "Define which trilium instance should run this on. Default to all instances.", - "runAtHour": "On which hour should this run. Should be used together with #run=hourly. Can be defined multiple times for more runs during the day.", - "disableInclusion": "scripts with this label won't be included into parent script execution.", - "sorted": "keeps child notes sorted by title alphabetically", - "sortDirection": "ASC (the default) or DESC", - "sortFoldersFirst": "Folders (notes with children) should be sorted on top", - "top": "keep given note on top in its parent (applies only on sorted parents)", - "hidePromotedAttributes": "Hide promoted attributes on this note", - "readOnly": "editor is in read only mode. Works only for text and code notes.", - "autoReadOnlyDisabled": "text/code notes can be set automatically into read mode when they are too large. You can disable this behavior on per-note basis by adding this label to the note", - "appCss": "marks CSS notes which are loaded into the Trilium application and can thus be used to modify Trilium's looks.", - "appTheme": "marks CSS notes which are full Trilium themes and are thus available in Trilium options.", - "cssClass": "value of this label is then added as CSS class to the node representing given note in the tree. This can be useful for advanced theming. Can be used in template notes.", - "iconClass": "value of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.", - "pageSize": "number of items per page in note listing", - "customRequestHandler": 'see Custom request handler', - "customResourceProvider": 'see Custom request handler', - "widget": "marks this note as a custom widget which will be added to the Trilium component tree", - "workspace": "marks this note as a workspace which allows easy hoisting", - "workspaceIconClass": "defines box icon CSS class which will be used in tab when hoisted to this note", - "workspaceTabBackgroundColor": "CSS color used in the note tab when hoisted to this note", - "workspaceCalendarRoot": "Defines per-workspace calendar root", - "workspaceTemplate": "This note will appear in the selection of available template when creating new note, but only when hoisted into a workspace containing this template", - "searchHome": "new search notes will be created as children of this note", - "workspaceSearchHome": "new search notes will be created as children of this note when hoisted to some ancestor of this workspace note", - "inbox": "default inbox location for new notes - when you create a note using \"new note\" button in the sidebar, notes will be created as child notes in the note marked as with #inbox label.", - "workspaceInbox": "default inbox location for new notes when hoisted to some ancestor of this workspace note", - "sqlConsoleHome": "default location of SQL console notes", - "bookmarkFolder": "note with this label will appear in bookmarks as folder (allowing access to its children)", - "shareHiddenFromTree": "this note is hidden from left navigation tree, but still accessible with its URL", - "shareExternalLink": "note will act as a link to an external website in the share tree", - "shareAlias": "define an alias using which the note will be available under https://your_trilium_host/share/[your_alias]", - "shareOmitDefaultCss": "default share page CSS will be omitted. Use when you make extensive styling changes.", - "shareRoot": "marks note which is served on /share root.", - "shareDescription": "define text to be added to the HTML meta tag for description", - "shareRaw": "note will be served in its raw format, without HTML wrapper", - "shareDisallowRobotIndexing": `will forbid robot indexing of this note via X-Robots-Tag: noindex header`, - "shareCredentials": "require credentials to access this shared note. Value is expected to be in format 'username:password'. Don't forget to make this inheritable to apply to child-notes/images.", - "shareIndex": "note with this this label will list all roots of shared notes", - "displayRelations": "comma delimited names of relations which should be displayed. All other ones will be hidden.", - "hideRelations": "comma delimited names of relations which should be hidden. All other ones will be displayed.", - "titleTemplate": `default title of notes created as children of this note. The value is evaluated as JavaScript string - and thus can be enriched with dynamic content via the injected now and parentNote variables. Examples: - - - - See wiki with details, API docs for parentNote and now for details.`, - "template": "This note will appear in the selection of available template when creating new note", - "toc": "#toc or #toc=show will force the Table of Contents to be shown, #toc=hide will force hiding it. If the label doesn't exist, the global setting is observed", - "color": "defines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f", - "keyboardShortcut": "Defines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.", - "keepCurrentHoisting": "Opening this link won't change hoisting even if the note is not displayable in the current hoisted subtree.", - "executeButton": "Title of the button which will execute the current code note", - "executeDescription": "Longer description of the current code note displayed together with the execute button", - "excludeFromNoteMap": "Notes with this label will be hidden from the Note Map", - "newNotesOnTop": "New notes will be created at the top of the parent note, not on the bottom.", - "hideHighlightWidget": "Hide Hightlight List widget" + "disableVersioning": t('attribute_detail.disable_versioning'), + "calendarRoot": t('attribute_detail.calendar_root'), + "archived": t('attribute_detail.archived'), + "excludeFromExport": t('attribute_detail.exclude_from_export'), + "run": t('attribute_detail.run'), + "runOnInstance": t('attribute_detail.run_on_instance'), + "runAtHour": t('attribute_detail.run_at_hour'), + "disableInclusion": t('attribute_detail.disable_inclusion'), + "sorted": t('attribute_detail.sorted'), + "sortDirection": t('attribute_detail.sort_direction'), + "sortFoldersFirst": t('attribute_detail.sort_folders_first'), + "top": t('attribute_detail.top'), + "hidePromotedAttributes": t('attribute_detail.hide_promoted_attributes'), + "readOnly": t('attribute_detail.read_only'), + "autoReadOnlyDisabled": t('attribute_detail.auto_read_only_disabled'), + "appCss": t('attribute_detail.app_css'), + "appTheme": t('attribute_detail.app_theme'), + "cssClass": t('attribute_detail.css_class'), + "iconClass": t('attribute_detail.icon_class'), + "pageSize": t('attribute_detail.page_size'), + "customRequestHandler": t('attribute_detail.custom_request_handler'), + "customResourceProvider": t('attribute_detail.custom_resource_provider'), + "widget": t('attribute_detail.widget'), + "workspace": t('attribute_detail.workspace'), + "workspaceIconClass": t('attribute_detail.workspace_icon_class'), + "workspaceTabBackgroundColor": t('attribute_detail.workspace_tab_background_color'), + "workspaceCalendarRoot": t('attribute_detail.workspace_calendar_root'), + "workspaceTemplate": t('attribute_detail.workspace_template'), + "searchHome": t('attribute_detail.search_home'), + "workspaceSearchHome": t('attribute_detail.workspace_search_home'), + "inbox": t('attribute_detail.inbox'), + "workspaceInbox": t('attribute_detail.workspace_inbox'), + "sqlConsoleHome": t('attribute_detail.sql_console_home'), + "bookmarkFolder": t('attribute_detail.bookmark_folder'), + "shareHiddenFromTree": t('attribute_detail.share_hidden_from_tree'), + "shareExternalLink": t('attribute_detail.share_external_link'), + "shareAlias": t('attribute_detail.share_alias'), + "shareOmitDefaultCss": t('attribute_detail.share_omit_default_css'), + "shareRoot": t('attribute_detail.share_root'), + "shareDescription": t('attribute_detail.share_description'), + "shareRaw": t('attribute_detail.share_raw'), + "shareDisallowRobotIndexing": t('attribute_detail.share_disallow_robot_indexing'), + "shareCredentials": t('attribute_detail.share_credentials'), + "shareIndex": t('attribute_detail.share_index'), + "displayRelations": t('attribute_detail.display_relations'), + "hideRelations": t('attribute_detail.hide_relations'), + "titleTemplate": t('attribute_detail.title_template'), + "template": t('attribute_detail.template'), + "toc": t('attribute_detail.toc'), + "color": t('attribute_detail.color'), + "keyboardShortcut": t('attribute_detail.keyboard_shortcut'), + "keepCurrentHoisting": t('attribute_detail.keep_current_hoisting'), + "executeButton": t('attribute_detail.execute_button'), + "executeDescription": t('attribute_detail.execute_description'), + "excludeFromNoteMap": t('attribute_detail.exclude_from_note_map'), + "newNotesOnTop": t('attribute_detail.new_notes_on_top'), + "hideHighlightWidget": t('attribute_detail.hide_highlight_widget') }, "relation": { - "runOnNoteCreation": "executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script.", - "runOnChildNoteCreation": "executes when new note is created under the note where this relation is defined", - "runOnNoteTitleChange": "executes when note title is changed (includes note creation as well)", - "runOnNoteContentChange": "executes when note content is changed (includes note creation as well).", - "runOnNoteChange": "executes when note is changed (includes note creation as well). Does not include content changes", - "runOnNoteDeletion": "executes when note is being deleted", - "runOnBranchCreation": "executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note.", - "runOnBranchChange": "executes when a branch is updated.", - "runOnBranchDeletion": "executes when a branch is deleted. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted).", - "runOnAttributeCreation": "executes when new attribute is created for the note which defines this relation", - "runOnAttributeChange": " executes when the attribute is changed of a note which defines this relation. This is triggered also when the attribute is deleted", - "template": "note's attributes will be inherited even without a parent-child relationship, note's content and subtree will be added to instance notes if empty. See documentation for details.", - "inherit": "note's attributes will be inherited even without a parent-child relationship. See template relation for a similar concept. See attribute inheritance in the documentation.", - "renderNote": 'notes of type "render HTML note" will be rendered using a code note (HTML or script) and it is necessary to point using this relation to which note should be rendered', - "widget": "target of this relation will be executed and rendered as a widget in the sidebar", - "shareCss": "CSS note which will be injected into the share page. CSS note must be in the shared sub-tree as well. Consider using 'shareHiddenFromTree' and 'shareOmitDefaultCss' as well.", - "shareJs": "JavaScript note which will be injected into the share page. JS note must be in the shared sub-tree as well. Consider using 'shareHiddenFromTree'.", - "shareTemplate": "Embedded JavaScript note that will be used as the template for displaying the shared note. Falls back to the default template. Consider using 'shareHiddenFromTree'.", - "shareFavicon": "Favicon note to be set in the shared page. Typically you want to set it to share root and make it inheritable. Favicon note must be in the shared sub-tree as well. Consider using 'shareHiddenFromTree'.", + "runOnNoteCreation": t('attribute_detail.run_on_note_creation'), + "runOnChildNoteCreation": t('attribute_detail.run_on_child_note_creation'), + "runOnNoteTitleChange": t('attribute_detail.run_on_note_title_change'), + "runOnNoteContentChange": t('attribute_detail.run_on_note_content_change'), + "runOnNoteChange": t('attribute_detail.run_on_note_change'), + "runOnNoteDeletion": t('attribute_detail.run_on_note_deletion'), + "runOnBranchCreation": t('attribute_detail.run_on_branch_creation'), + "runOnBranchChange": t('attribute_detail.run_on_branch_change'), + "runOnBranchDeletion": t('attribute_detail.run_on_branch_deletion'), + "runOnAttributeCreation": t('attribute_detail.run_on_attribute_creation'), + "runOnAttributeChange": t('attribute_detail.run_on_attribute_change'), + "template": t('attribute_detail.relation_template'), + "inherit": t('attribute_detail.inherit'), + "renderNote": t('attribute_detail.render_note'), + "widget": t('attribute_detail.widget_relation'), + "shareCss": t('attribute_detail.share_css'), + "shareJs": t('attribute_detail.share_js'), + "shareTemplate": t('attribute_detail.share_template'), + "shareFavicon": t('attribute_detail.share_favicon') } }; @@ -454,7 +440,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { .show() .empty() .append(attribute.type === 'label' ? 'Label' : 'Relation') - .append(' is owned by note ') + .append(` ${t("attribute_detail.is_owned_by_note")} `) .append(await linkService.createLink(attribute.noteId)) } @@ -615,7 +601,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { this.$relatedNotesContainer.hide(); } else { this.$relatedNotesContainer.show(); - this.$relatedNotesTitle.text(`Other notes with ${this.attribute.type} name "${this.attribute.name}"`); + this.$relatedNotesTitle.text(t("attribute_detail.other_notes_with_name", {attributeType: this.attribute.type, attributeName: this.attribute.name})); this.$relatedNotesList.empty(); @@ -633,7 +619,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { } if (results.length > DISPLAYED_NOTES) { - this.$relatedNotesMoreNotes.show().text(`... and ${count - DISPLAYED_NOTES} more.`); + this.$relatedNotesMoreNotes.show().text(t("attribute_detail.and_more", {count: count - DISPLAYED_NOTES})); } else { this.$relatedNotesMoreNotes.hide(); } diff --git a/src/public/app/widgets/attribute_widgets/attribute_editor.js b/src/public/app/widgets/attribute_widgets/attribute_editor.js index 303a577b5..aa86ec5cc 100644 --- a/src/public/app/widgets/attribute_widgets/attribute_editor.js +++ b/src/public/app/widgets/attribute_widgets/attribute_editor.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import NoteContextAwareWidget from "../note_context_aware_widget.js"; import noteAutocompleteService from "../../services/note_autocomplete.js"; import server from "../../services/server.js"; @@ -11,11 +12,11 @@ import attributeService from "../../services/attributes.js"; import linkService from "../../services/link.js"; const HELP_TEXT = ` -

To add label, just type e.g. #rock or if you want to add also value then e.g. #year = 2020

+

${t("attribute_editor.help_text_body1")}

-

For relation, type ~author = @ which should bring up an autocomplete where you can look up the desired note.

+

${t("attribute_editor.help_text_body2")}

-

Alternatively you can add label and relation using the + button on the right side.

`; +

${t("attribute_editor.help_text_body3")}

`; const TPL = `
@@ -71,8 +72,8 @@ const TPL = `
-
-
+
+
@@ -217,13 +218,13 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget { y: e.pageY, orientation: 'left', items: [ - {title: `Add new label `, command: "addNewLabel", uiIcon: "bx bx-hash"}, - {title: `Add new relation `, command: "addNewRelation", uiIcon: "bx bx-transfer"}, - {title: "----"}, - {title: "Add new label definition", command: "addNewLabelDefinition", uiIcon: "bx bx-empty"}, - {title: "Add new relation definition", command: "addNewRelationDefinition", uiIcon: "bx bx-empty"}, + { title: t("attribute_editor.add_new_label"), command: "addNewLabel", uiIcon: "bx bx-hash" }, + { title: t("attribute_editor.add_new_relation"), command: "addNewRelation", uiIcon: "bx bx-transfer" }, + { title: "----" }, + { title: t("attribute_editor.add_new_label_definition"), command: "addNewLabelDefinition", uiIcon: "bx bx-empty" }, + { title: t("attribute_editor.add_new_relation_definition"), command: "addNewRelationDefinition", uiIcon: "bx bx-empty" }, ], - selectMenuItemHandler: ({command}) => this.handleAddNewAttributeCommand(command) + selectMenuItemHandler: ({ command }) => this.handleAddNewAttributeCommand(command) }); } diff --git a/src/public/app/widgets/bulk_actions/abstract_bulk_action.js b/src/public/app/widgets/bulk_actions/abstract_bulk_action.js index 6bb01d256..634f3d073 100644 --- a/src/public/app/widgets/bulk_actions/abstract_bulk_action.js +++ b/src/public/app/widgets/bulk_actions/abstract_bulk_action.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import server from "../../services/server.js"; import ws from "../../services/ws.js"; import utils from "../../services/utils.js"; @@ -14,7 +15,7 @@ export default class AbstractBulkAction { $rendered.find('.action-conf-del') .on('click', () => this.deleteAction()) - .attr('title', 'Remove this search action'); + .attr('title', t('abstract_bulk_action.remove_this_search_action')); utils.initHelpDropdown($rendered); diff --git a/src/public/app/widgets/bulk_actions/execute_script.js b/src/public/app/widgets/bulk_actions/execute_script.js index 69d8e3cd9..c4740ff0d 100644 --- a/src/public/app/widgets/bulk_actions/execute_script.js +++ b/src/public/app/widgets/bulk_actions/execute_script.js @@ -1,10 +1,11 @@ +import { t } from "../../services/i18n.js"; import SpacedUpdate from "../../services/spaced_update.js"; import AbstractBulkAction from "./abstract_bulk_action.js"; const TPL = ` - Execute script: + ${t('execute_script.execute_script')} @@ -35,7 +36,7 @@ const TPL = ` export default class ExecuteScriptBulkAction extends AbstractBulkAction { static get actionName() { return "executeScript"; } - static get actionTitle() { return "Execute script"; } + static get actionTitle() { return t("execute_script.execute_script"); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/label/add_label.js b/src/public/app/widgets/bulk_actions/label/add_label.js index 8e120e0ce..ba678dc7c 100644 --- a/src/public/app/widgets/bulk_actions/label/add_label.js +++ b/src/public/app/widgets/bulk_actions/label/add_label.js @@ -1,3 +1,4 @@ +import { t } from "../../../services/i18n.js"; import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; @@ -5,31 +6,31 @@ const TPL = `
-
Add label
+
${t("add_label.add_label")}
+ title="${t("add_label.label_name_title")}"/> -
to value
+
${t("add_label.to_value")}
- +
@@ -39,7 +40,7 @@ const TPL = ` export default class AddLabelBulkAction extends AbstractBulkAction { static get actionName() { return "addLabel"; } - static get actionTitle() { return "Add label"; } + static get actionTitle() { return t("add_label.add_label"); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/label/delete_label.js b/src/public/app/widgets/bulk_actions/label/delete_label.js index 76490ca56..ba2c393a0 100644 --- a/src/public/app/widgets/bulk_actions/label/delete_label.js +++ b/src/public/app/widgets/bulk_actions/label/delete_label.js @@ -1,17 +1,18 @@ +import { t } from "../../../services/i18n.js"; import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; const TPL = ` - Delete label: + ${t("delete_label.delete_label")} + title="${t("delete_label.label_name_title")}" + placeholder="${t("delete_label.label_name_placeholder")}"/> @@ -20,7 +21,7 @@ const TPL = ` export default class DeleteLabelBulkAction extends AbstractBulkAction { static get actionName() { return "deleteLabel"; } - static get actionTitle() { return "Delete label"; } + static get actionTitle() { return t("delete_label.delete_label"); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/label/rename_label.js b/src/public/app/widgets/bulk_actions/label/rename_label.js index ec66dede0..c250e795c 100644 --- a/src/public/app/widgets/bulk_actions/label/rename_label.js +++ b/src/public/app/widgets/bulk_actions/label/rename_label.js @@ -1,3 +1,4 @@ +import { t } from "../../../services/i18n.js"; import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; @@ -5,21 +6,21 @@ const TPL = `
-
Rename label from:
+
${t("rename_label.rename_label_from")}
+ title="${t("rename_label.name_title")}"/> -
To:
+
${t("rename_label.to")}
+ title="${t("rename_label.name_title")}"/>
@@ -29,7 +30,7 @@ const TPL = ` export default class RenameLabelBulkAction extends AbstractBulkAction { static get actionName() { return "renameLabel"; } - static get actionTitle() { return "Rename label"; } + static get actionTitle() { return t("rename_label.rename_label"); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/label/update_label_value.js b/src/public/app/widgets/bulk_actions/label/update_label_value.js index 3a0829fff..e2729f0da 100644 --- a/src/public/app/widgets/bulk_actions/label/update_label_value.js +++ b/src/public/app/widgets/bulk_actions/label/update_label_value.js @@ -1,3 +1,4 @@ +import { t } from "../../../services/i18n.js"; import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; @@ -5,26 +6,26 @@ const TPL = `
-
Update label value
+
${t("update_label_value.update_label_value")}
+ title="${t("update_label_value.label_name_title")}"/> -
to value
+
${t("update_label_value.to_value")}
- +
@@ -34,7 +35,7 @@ const TPL = ` export default class UpdateLabelValueBulkAction extends AbstractBulkAction { static get actionName() { return "updateLabelValue"; } - static get actionTitle() { return "Update label value"; } + static get actionTitle() { return t("update_label_value.update_label_value"); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/note/delete_note.js b/src/public/app/widgets/bulk_actions/note/delete_note.js index 585a32749..572099a66 100644 --- a/src/public/app/widgets/bulk_actions/note/delete_note.js +++ b/src/public/app/widgets/bulk_actions/note/delete_note.js @@ -1,3 +1,4 @@ +import { t } from "../../../services/i18n.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; const TPL = ` @@ -5,17 +6,17 @@ const TPL = ` - Delete matched notes + ${t("delete_note.delete_matched_notes")} @@ -25,7 +26,7 @@ const TPL = ` export default class DeleteNoteBulkAction extends AbstractBulkAction { static get actionName() { return "deleteNote"; } - static get actionTitle() { return "Delete note"; } + static get actionTitle() { return t("delete_note.delete_note"); } doRender() { return $(TPL); diff --git a/src/public/app/widgets/bulk_actions/note/delete_revisions.js b/src/public/app/widgets/bulk_actions/note/delete_revisions.js index 61b665ec1..2637ddcb3 100644 --- a/src/public/app/widgets/bulk_actions/note/delete_revisions.js +++ b/src/public/app/widgets/bulk_actions/note/delete_revisions.js @@ -1,27 +1,26 @@ +import { t } from "../../../services/i18n.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; const TPL = ` - - Delete note revisions + ${t('delete_revisions.delete_note_revisions')} - `; export default class DeleteRevisionsBulkAction extends AbstractBulkAction { static get actionName() { return "deleteRevisions"; } - static get actionTitle() { return "Delete note revisions"; } + static get actionTitle() { return t('delete_revisions.delete_note_revisions'); } doRender() { return $(TPL); diff --git a/src/public/app/widgets/bulk_actions/note/move_note.js b/src/public/app/widgets/bulk_actions/note/move_note.js index ba11e9f70..43332d7cc 100644 --- a/src/public/app/widgets/bulk_actions/note/move_note.js +++ b/src/public/app/widgets/bulk_actions/note/move_note.js @@ -1,3 +1,4 @@ +import { t } from "../../../services/i18n.js"; import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; import noteAutocompleteService from "../../../services/note_autocomplete.js"; @@ -6,12 +7,12 @@ const TPL = `
-
Move note
+
${t('move_note.move_note')}
-
to
+
${t('move_note.to')}
- +
@@ -19,12 +20,12 @@ const TPL = ` @@ -35,7 +36,7 @@ const TPL = ` export default class MoveNoteBulkAction extends AbstractBulkAction { static get actionName() { return "moveNote"; } - static get actionTitle() { return "Move note"; } + static get actionTitle() { return t('move_note.move_note'); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/note/rename_note.js b/src/public/app/widgets/bulk_actions/note/rename_note.js index 0d3a2ebf1..58832956e 100644 --- a/src/public/app/widgets/bulk_actions/note/rename_note.js +++ b/src/public/app/widgets/bulk_actions/note/rename_note.js @@ -1,31 +1,32 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; +import { t } from "../../../services/i18n.js"; const TPL = `
-
Rename note title to:
+
${t('rename_note.rename_note_title_to')}
+ placeholder="${t('rename_note.new_note_title')}" + title="${t('rename_note.click_help_icon')}"/>
@@ -35,7 +36,7 @@ const TPL = ` export default class RenameNoteBulkAction extends AbstractBulkAction { static get actionName() { return "renameNote"; } - static get actionTitle() { return "Rename note"; } + static get actionTitle() { return t('rename_note.rename_note'); } doRender() { const $action = $(TPL); diff --git a/src/public/app/widgets/bulk_actions/relation/add_relation.js b/src/public/app/widgets/bulk_actions/relation/add_relation.js index 846aa870e..de8240c7d 100644 --- a/src/public/app/widgets/bulk_actions/relation/add_relation.js +++ b/src/public/app/widgets/bulk_actions/relation/add_relation.js @@ -1,24 +1,25 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; import noteAutocompleteService from "../../../services/note_autocomplete.js"; +import { t } from "../../../services/i18n.js"; const TPL = `
-
Add relation
+
${t('add_relation.add_relation')}
+ title="${t('add_relation.allowed_characters')}"/> -
to
+
${t('add_relation.to')}
- +
@@ -26,7 +27,7 @@ const TPL = ` @@ -36,7 +37,7 @@ const TPL = ` export default class AddRelationBulkAction extends AbstractBulkAction { static get actionName() { return "addRelation"; } - static get actionTitle() { return "Add relation"; } + static get actionTitle() { return t('add_relation.add_relation'); } doRender() { const $action = $(TPL); @@ -55,7 +56,7 @@ export default class AddRelationBulkAction extends AbstractBulkAction { relationName: $relationName.val(), targetNoteId: $targetNote.getSelectedNoteId() }); - }, 1000) + }, 1000); $relationName.on('input', () => spacedUpdate.scheduleUpdate()); $targetNote.on('input', () => spacedUpdate.scheduleUpdate()); diff --git a/src/public/app/widgets/bulk_actions/relation/delete_relation.js b/src/public/app/widgets/bulk_actions/relation/delete_relation.js index 86cd99c50..f382841a8 100644 --- a/src/public/app/widgets/bulk_actions/relation/delete_relation.js +++ b/src/public/app/widgets/bulk_actions/relation/delete_relation.js @@ -1,18 +1,19 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; +import { t } from "../../../services/i18n.js"; const TPL = ` - Delete relation: + ${t('delete_relation.delete_relation')}
+ placeholder="${t('delete_relation.relation_name')}" + title="${t('delete_relation.allowed_characters')}"/>
@@ -22,7 +23,7 @@ const TPL = ` export default class DeleteRelationBulkAction extends AbstractBulkAction { static get actionName() { return "deleteRelation"; } - static get actionTitle() { return "Delete relation"; } + static get actionTitle() { return t('delete_relation.delete_relation'); } doRender() { const $action = $(TPL); @@ -31,7 +32,7 @@ export default class DeleteRelationBulkAction extends AbstractBulkAction { const spacedUpdate = new SpacedUpdate(async () => { await this.saveAction({ relationName: $relationName.val() }); - }, 1000) + }, 1000); $relationName.on('input', () => spacedUpdate.scheduleUpdate()); diff --git a/src/public/app/widgets/bulk_actions/relation/rename_relation.js b/src/public/app/widgets/bulk_actions/relation/rename_relation.js index 9d5c674cf..a2b3e9886 100644 --- a/src/public/app/widgets/bulk_actions/relation/rename_relation.js +++ b/src/public/app/widgets/bulk_actions/relation/rename_relation.js @@ -1,25 +1,26 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; +import { t } from "../../../services/i18n.js"; const TPL = `
-
Rename relation from:
+
${t('rename_relation.rename_relation_from')}
+ title="${t('rename_relation.allowed_characters')}"/> -
To:
+
${t('rename_relation.to')}
+ title="${t('rename_relation.allowed_characters')}"/>
@@ -29,7 +30,7 @@ const TPL = ` export default class RenameRelationBulkAction extends AbstractBulkAction { static get actionName() { return "renameRelation"; } - static get actionTitle() { return "Rename relation"; } + static get actionTitle() { return t('rename_relation.rename_relation'); } doRender() { const $action = $(TPL); @@ -45,7 +46,7 @@ export default class RenameRelationBulkAction extends AbstractBulkAction { oldRelationName: $oldRelationName.val(), newRelationName: $newRelationName.val() }); - }, 1000) + }, 1000); $oldRelationName.on('input', () => spacedUpdate.scheduleUpdate()); $newRelationName.on('input', () => spacedUpdate.scheduleUpdate()); diff --git a/src/public/app/widgets/bulk_actions/relation/update_relation_target.js b/src/public/app/widgets/bulk_actions/relation/update_relation_target.js index 5c4b98d73..019bfdd5c 100644 --- a/src/public/app/widgets/bulk_actions/relation/update_relation_target.js +++ b/src/public/app/widgets/bulk_actions/relation/update_relation_target.js @@ -1,24 +1,25 @@ import SpacedUpdate from "../../../services/spaced_update.js"; import AbstractBulkAction from "../abstract_bulk_action.js"; import noteAutocompleteService from "../../../services/note_autocomplete.js"; +import { t } from "../../../services/i18n.js"; const TPL = `
-
Update relation
+
${t('update_relation_target.update_relation')}
+ title="${t('update_relation_target.allowed_characters')}"/> -
to
+
${t('update_relation_target.to')}
- +
@@ -26,11 +27,11 @@ const TPL = ` @@ -41,7 +42,7 @@ const TPL = ` export default class UpdateRelationTargetBulkAction extends AbstractBulkAction { static get actionName() { return "updateRelationTarget"; } - static get actionTitle() { return "Update relation target"; } + static get actionTitle() { return t('update_relation_target.update_relation_target'); } doRender() { const $action = $(TPL); @@ -60,7 +61,7 @@ export default class UpdateRelationTargetBulkAction extends AbstractBulkAction { relationName: $relationName.val(), targetNoteId: $targetNote.getSelectedNoteId() }); - }, 1000) + }, 1000); $relationName.on('input', () => spacedUpdate.scheduleUpdate()); $targetNote.on('input', () => spacedUpdate.scheduleUpdate()); diff --git a/src/public/app/widgets/buttons/attachments_actions.js b/src/public/app/widgets/buttons/attachments_actions.js index c62030171..a7bdf70ab 100644 --- a/src/public/app/widgets/buttons/attachments_actions.js +++ b/src/public/app/widgets/buttons/attachments_actions.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import BasicWidget from "../basic_widget.js"; import server from "../../services/server.js"; import dialogService from "../../services/dialog.js"; @@ -32,15 +33,15 @@ const TPL = ` @@ -70,26 +71,24 @@ export default class AttachmentActionsWidget extends BasicWidget { const result = await server.upload(`attachments/${this.attachmentId}/file`, fileToUpload); if (result.uploaded) { - toastService.showMessage("New attachment revision has been uploaded."); + toastService.showMessage(t('attachments_actions.upload_success')); } else { - toastService.showError("Upload of a new attachment revision failed."); + toastService.showError(t('attachments_actions.upload_failed')); } }); if (!this.isFullDetail) { - // we deactivate this button because the WatchedFileUpdateStatusWidget assumes only one visible attachment - // in a note context, so it doesn't work in a list const $openAttachmentButton = this.$widget.find("[data-trigger-command='openAttachment']"); $openAttachmentButton .addClass("disabled") .append($(' (?)') - .attr("title", "Opening attachment externally is available only from the detail page, please first click on the attachment detail first and repeat the action.") + .attr("title", t('attachments_actions.open_externally_detail_page')) ); const $openAttachmentCustomButton = this.$widget.find("[data-trigger-command='openAttachmentCustom']"); $openAttachmentCustomButton .addClass("disabled") .append($(' (?)') - .attr("title", "Opening attachment externally is available only from the detail page, please first click on the attachment detail first and repeat the action.") + .attr("title", t('attachments_actions.open_externally_detail_page')) ); } if (!utils.isElectron()){ @@ -97,7 +96,7 @@ export default class AttachmentActionsWidget extends BasicWidget { $openAttachmentCustomButton .addClass("disabled") .append($(' (?)') - .attr("title", "Custom opening of attachments can only be done from the client.") + .attr("title", t('attachments_actions.open_custom_client_only')) ); } } @@ -123,29 +122,29 @@ export default class AttachmentActionsWidget extends BasicWidget { } async deleteAttachmentCommand() { - if (!await dialogService.confirm(`Are you sure you want to delete attachment '${this.attachment.title}'?`)) { + if (!await dialogService.confirm(t('attachments_actions.delete_confirm', { title: this.attachment.title }))) { return; } await server.remove(`attachments/${this.attachmentId}`); - toastService.showMessage(`Attachment '${this.attachment.title}' has been deleted.`); + toastService.showMessage(t('attachments_actions.delete_success', { title: this.attachment.title })); } async convertAttachmentIntoNoteCommand() { - if (!await dialogService.confirm(`Are you sure you want to convert attachment '${this.attachment.title}' into a separate note?`)) { + if (!await dialogService.confirm(t('attachments_actions.convert_confirm', { title: this.attachment.title }))) { return; } const {note: newNote} = await server.post(`attachments/${this.attachmentId}/convert-to-note`) - toastService.showMessage(`Attachment '${this.attachment.title}' has been converted to note.`); + toastService.showMessage(t('attachments_actions.convert_success', { title: this.attachment.title })); await ws.waitForMaxKnownEntityChangeId(); await appContext.tabManager.getActiveContext().setNote(newNote.noteId); } async renameAttachmentCommand() { const attachmentTitle = await dialogService.prompt({ - title: "Rename attachment", - message: "Please enter new attachment's name", + title: t('attachments_actions.rename_attachment'), + message: t('attachments_actions.enter_new_name'), defaultValue: this.attachment.title }); diff --git a/src/public/app/widgets/buttons/calendar.js b/src/public/app/widgets/buttons/calendar.js index f05aedd9a..3980ca8b3 100644 --- a/src/public/app/widgets/buttons/calendar.js +++ b/src/public/app/widgets/buttons/calendar.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import libraryLoader from "../../services/library_loader.js"; import utils from "../../services/utils.js"; import dateNoteService from "../../services/date_notes.js"; @@ -23,7 +24,7 @@ const DROPDOWN_TPL = `
- Mon TueWed Thu Fri Sat Sun + ${t("calendar.mon")} ${t("calendar.tue")}${t("calendar.wed")} ${t("calendar.thu")} ${t("calendar.fri")} ${t("calendar.sat")} ${t("calendar.sun")}
`; @@ -63,7 +64,7 @@ export default class CalendarWidget extends RightDropdownButtonWidget { this.hideDropdown(); } else { - toastService.showError("Cannot find day note"); + toastService.showError(t("calendar.cannot_find_day_note")); } }); } @@ -153,23 +154,23 @@ export default class CalendarWidget extends RightDropdownButtonWidget { this.date.setDate(1); this.date.setMonth(this.date.getMonth() - 1); - this.$label.html(`${this.monthsAsString(this.date.getMonth())} ${this.date.getFullYear()}`); + this.$label.html(`${t(this.monthsAsString(this.date.getMonth()).toLowerCase())} ${this.date.getFullYear()}`); } monthsAsString(monthIndex) { return [ - 'January', - 'Febuary', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' + t("calendar.january"), + t("calendar.febuary"), + t("calendar.march"), + t("calendar.april"), + t("calendar.may"), + t("calendar.june"), + t("calendar.july"), + t("calendar.august"), + t("calendar.september"), + t("calendar.october"), + t("calendar.november"), + t("calendar.december") ][monthIndex]; } } diff --git a/src/public/app/widgets/buttons/close_pane_button.js b/src/public/app/widgets/buttons/close_pane_button.js index 220fd2cca..b236894f0 100644 --- a/src/public/app/widgets/buttons/close_pane_button.js +++ b/src/public/app/widgets/buttons/close_pane_button.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import OnClickButtonWidget from "./onclick_button.js"; export default class ClosePaneButton extends OnClickButtonWidget { @@ -15,7 +16,7 @@ export default class ClosePaneButton extends OnClickButtonWidget { super(); this.icon("bx-x") - .title("Close this pane") + .title(t("close_pane_button.close_this_pane")) .titlePlacement("bottom") .onClick((widget, e) => { // to avoid split pane container detecting click within the pane which would try to activate this diff --git a/src/public/app/widgets/buttons/create_pane_button.js b/src/public/app/widgets/buttons/create_pane_button.js index e608803a9..1c072548a 100644 --- a/src/public/app/widgets/buttons/create_pane_button.js +++ b/src/public/app/widgets/buttons/create_pane_button.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import OnClickButtonWidget from "./onclick_button.js"; export default class CreatePaneButton extends OnClickButtonWidget { @@ -5,7 +6,7 @@ export default class CreatePaneButton extends OnClickButtonWidget { super(); this.icon("bx-dock-right") - .title("Create new split") + .title(t("create_pane_button.create_new_split")) .titlePlacement("bottom") .onClick(widget => widget.triggerCommand("openNewNoteSplit", { ntxId: widget.getClosestNtxId() })) .class("icon-action"); diff --git a/src/public/app/widgets/buttons/edit_button.js b/src/public/app/widgets/buttons/edit_button.js index daf29c097..50c490dc2 100644 --- a/src/public/app/widgets/buttons/edit_button.js +++ b/src/public/app/widgets/buttons/edit_button.js @@ -2,6 +2,7 @@ import OnClickButtonWidget from "./onclick_button.js"; import appContext from "../../components/app_context.js"; import attributeService from "../../services/attributes.js"; import protectedSessionHolder from "../../services/protected_session_holder.js"; +import { t } from "../../services/i18n.js"; export default class EditButton extends OnClickButtonWidget { isEnabled() { @@ -14,7 +15,7 @@ export default class EditButton extends OnClickButtonWidget { super(); this.icon("bx-edit-alt") - .title("Edit this note") + .title(t("edit_button.edit_this_note")) .titlePlacement("bottom") .onClick(widget => { this.noteContext.viewScope.readOnlyTemporarilyDisabled = true; diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index ad7806f0e..e4aed7ba7 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import BasicWidget from "../basic_widget.js"; import utils from "../../services/utils.js"; import UpdateAvailableWidget from "./update_available.js"; @@ -103,7 +104,7 @@ const TPL = ` `; diff --git a/src/public/app/widgets/buttons/onclick_button.js b/src/public/app/widgets/buttons/onclick_button.js index 11aa53e4a..f8f087f1f 100644 --- a/src/public/app/widgets/buttons/onclick_button.js +++ b/src/public/app/widgets/buttons/onclick_button.js @@ -1,4 +1,5 @@ import AbstractButtonWidget from "./abstract_button.js"; +import { t } from "../../services/i18n.js"; export default class OnClickButtonWidget extends AbstractButtonWidget { doRender() { @@ -12,7 +13,7 @@ export default class OnClickButtonWidget extends AbstractButtonWidget { this.settings.onClick(this, e); }); } else { - console.warn(`Button widget '${this.componentId}' has no defined click handler`, this.settings); + console.warn(t("onclick_button.no_click_handler", { componentId: this.componentId }), this.settings); } if (this.settings.onAuxClick) { diff --git a/src/public/app/widgets/buttons/protected_session_status.js b/src/public/app/widgets/buttons/protected_session_status.js index b218e6bde..2a9a14f14 100644 --- a/src/public/app/widgets/buttons/protected_session_status.js +++ b/src/public/app/widgets/buttons/protected_session_status.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import protectedSessionHolder from "../../services/protected_session_holder.js"; import CommandButtonWidget from "./command_button.js"; @@ -12,8 +13,8 @@ export default class ProtectedSessionStatusWidget extends CommandButtonWidget { : "bx-shield-quarter"; this.settings.title = () => protectedSessionHolder.isProtectedSessionAvailable() - ? "Protected session is active. Click to leave protected session." - : "Click to enter protected session"; + ? t("protected_session_status.active") + : t("protected_session_status.inactive"); this.settings.command = () => protectedSessionHolder.isProtectedSessionAvailable() ? "leaveProtectedSession" diff --git a/src/public/app/widgets/buttons/revisions_button.js b/src/public/app/widgets/buttons/revisions_button.js index 43cd66028..b3c0bbbcf 100644 --- a/src/public/app/widgets/buttons/revisions_button.js +++ b/src/public/app/widgets/buttons/revisions_button.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import CommandButtonWidget from "./command_button.js"; export default class RevisionsButton extends CommandButtonWidget { @@ -5,7 +6,7 @@ export default class RevisionsButton extends CommandButtonWidget { super(); this.icon('bx-history') - .title("Note Revisions") + .title(t("revisions_button.note_revisions")) .command("showRevisions") .titlePlacement("bottom") .class("icon-action"); diff --git a/src/public/app/widgets/buttons/update_available.js b/src/public/app/widgets/buttons/update_available.js index 0523d276e..50351cf0e 100644 --- a/src/public/app/widgets/buttons/update_available.js +++ b/src/public/app/widgets/buttons/update_available.js @@ -1,3 +1,4 @@ +import { t } from "../../services/i18n.js"; import BasicWidget from "../basic_widget.js"; const TPL = ` @@ -23,7 +24,7 @@ const TPL = ` } - + `; diff --git a/src/public/app/widgets/dialogs/about.js b/src/public/app/widgets/dialogs/about.js index 61241d66f..c381bacd3 100644 --- a/src/public/app/widgets/dialogs/about.js +++ b/src/public/app/widgets/dialogs/about.js @@ -15,7 +15,7 @@ const TPL = ` @@ -95,7 +96,7 @@ export default class BulkActionsDialog extends BasicWidget { includeDescendants: this.$includeDescendants.is(":checked") }); - toastService.showMessage("Bulk actions have been executed successfully.", 3000); + toastService.showMessage(t('bulk_actions.bulk_actions_executed'), 3000); utils.closeActiveDialog(); }); @@ -120,7 +121,7 @@ export default class BulkActionsDialog extends BasicWidget { if (actions.length > 0) { this.$existingActionList.append(...actions.map(action => action.render())); } else { - this.$existingActionList.append($("

None yet ... add an action by clicking one of the available ones above.

")) + this.$existingActionList.append($("

").text(t('bulk_actions.none_yet'))) } } diff --git a/src/public/app/widgets/dialogs/clone_to.js b/src/public/app/widgets/dialogs/clone_to.js index 850cdef4c..b578ed4ae 100644 --- a/src/public/app/widgets/dialogs/clone_to.js +++ b/src/public/app/widgets/dialogs/clone_to.js @@ -6,15 +6,16 @@ import froca from "../../services/froca.js"; import branchService from "../../services/branches.js"; import appContext from "../../components/app_context.js"; import BasicWidget from "../basic_widget.js"; +import { t } from "../../services/i18n.js"; const TPL = `