mirror of
https://github.com/zadam/trilium.git
synced 2025-03-03 02:23:34 +08:00
keyboard shortcuts for ribbon tabs
This commit is contained in:
parent
9e1c9782ff
commit
0351d7eff1
17 changed files with 195 additions and 38 deletions
3
TODO
3
TODO
|
@ -1,7 +1,4 @@
|
|||
- all ribbon tabs should have assignable shortcut
|
||||
- new icon
|
||||
- green theme
|
||||
- polish becca entities API
|
||||
- separate private and public APIs in becca entities
|
||||
- handle FIXMEs
|
||||
- fix Steel Blue example
|
||||
|
|
|
@ -3,3 +3,8 @@
|
|||
- isDeleted = 0 by default
|
||||
- rename openTabs to openNoteContexts
|
||||
- migrate black theme to dark theme
|
||||
- unify readOnly handling to a single attribute:
|
||||
* readOnly - like now
|
||||
* readOnly=auto - like without readOnly (used to override inherited readOnly)
|
||||
* readOnly=never - like autoReadOnlyDisabled
|
||||
- remove focusOnAttributesKeyboardShortcut
|
||||
|
|
|
@ -161,31 +161,34 @@ export default class RibbonContainer extends NoteContextAwareWidget {
|
|||
this.$tabContainer.on('click', '.ribbon-tab-title', e => {
|
||||
const $ribbonTitle = $(e.target).closest('.ribbon-tab-title');
|
||||
|
||||
const activate = !$ribbonTitle.hasClass("active");
|
||||
|
||||
this.$tabContainer.find('.ribbon-tab-title').removeClass("active");
|
||||
this.$bodyContainer.find('.ribbon-body').removeClass("active");
|
||||
|
||||
if (activate) {
|
||||
const ribbonComponendId = $ribbonTitle.attr('data-ribbon-component-id');
|
||||
|
||||
this.lastActiveComponentId = ribbonComponendId;
|
||||
|
||||
this.$tabContainer.find(`.ribbon-tab-title[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active");
|
||||
this.$bodyContainer.find(`.ribbon-body[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active");
|
||||
|
||||
const activeChild = this.getActiveRibbonWidget();
|
||||
|
||||
if (activeChild) {
|
||||
activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.lastActiveComponentId = null;
|
||||
}
|
||||
this.toggleRibbonTab($ribbonTitle);
|
||||
});
|
||||
}
|
||||
|
||||
toggleRibbonTab($ribbonTitle) {
|
||||
const activate = !$ribbonTitle.hasClass("active");
|
||||
|
||||
this.$tabContainer.find('.ribbon-tab-title').removeClass("active");
|
||||
this.$bodyContainer.find('.ribbon-body').removeClass("active");
|
||||
|
||||
if (activate) {
|
||||
const ribbonComponendId = $ribbonTitle.attr('data-ribbon-component-id');
|
||||
|
||||
this.lastActiveComponentId = ribbonComponendId;
|
||||
|
||||
this.$tabContainer.find(`.ribbon-tab-title[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active");
|
||||
this.$bodyContainer.find(`.ribbon-body[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active");
|
||||
|
||||
const activeChild = this.getActiveRibbonWidget();
|
||||
|
||||
if (activeChild) {
|
||||
activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath});
|
||||
}
|
||||
} else {
|
||||
this.lastActiveComponentId = null;
|
||||
}
|
||||
}
|
||||
|
||||
async refreshWithNote(note, noExplicitActivation = false) {
|
||||
this.lastNoteType = note.type;
|
||||
|
||||
|
@ -202,6 +205,7 @@ export default class RibbonContainer extends NoteContextAwareWidget {
|
|||
|
||||
const $ribbonTitle = $('<div class="ribbon-tab-title">')
|
||||
.attr('data-ribbon-component-id', ribbonWidget.componentId)
|
||||
.attr('data-ribbon-component-name', ribbonWidget.name)
|
||||
.append($('<span class="ribbon-tab-title-icon">')
|
||||
.addClass(ret.icon)
|
||||
.attr("title", ret.title))
|
||||
|
@ -234,10 +238,56 @@ export default class RibbonContainer extends NoteContextAwareWidget {
|
|||
}
|
||||
}
|
||||
|
||||
isRibbonTabActive(name) {
|
||||
const $ribbonComponent = this.$widget.find(`.ribbon-tab-title[data-ribbon-component-name='${name}']`);
|
||||
|
||||
return $ribbonComponent.hasClass("active");
|
||||
}
|
||||
|
||||
refreshRibbonContainerCommand() {
|
||||
this.refreshWithNote(this.note, true);
|
||||
}
|
||||
|
||||
ensureOwnedAttributesAreOpen(ntxId) {
|
||||
if (this.isNoteContext(ntxId) && !this.isRibbonTabActive('ownedAttributes')) {
|
||||
this.toggleRibbonTabWithName('ownedAttributes', ntxId);
|
||||
}
|
||||
}
|
||||
|
||||
addNewLabelEvent({ntxId}) {
|
||||
this.ensureOwnedAttributesAreOpen(ntxId);
|
||||
}
|
||||
|
||||
addNewRelationEvent({ntxId}) {
|
||||
this.ensureOwnedAttributesAreOpen(ntxId);
|
||||
}
|
||||
|
||||
toggleRibbonTabWithName(name, ntxId) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const $ribbonComponent = this.$widget.find(`.ribbon-tab-title[data-ribbon-component-name='${name}']`);
|
||||
|
||||
if ($ribbonComponent) {
|
||||
this.toggleRibbonTab($ribbonComponent);
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(name, data) {
|
||||
const PREFIX = "toggleRibbonTab";
|
||||
|
||||
if (name.startsWith(PREFIX)) {
|
||||
let componentName = name.substr(PREFIX.length);
|
||||
componentName = componentName[0].toLowerCase() + componentName.substr(1);
|
||||
|
||||
this.toggleRibbonTabWithName(componentName, data.ntxId);
|
||||
}
|
||||
else {
|
||||
return super.handleEvent(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
async handleEventInChildren(name, data) {
|
||||
if (['activeContextChanged', 'setNoteContext'].includes(name)) {
|
||||
// won't trigger .refresh();
|
||||
|
|
|
@ -46,6 +46,10 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
|
|||
this.child(this.noteTypeWidget, this.protectedNoteSwitchWidget, this.editabilitySelectWidget);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return "basicProperties";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note && (this.note.type === 'text' || this.note.type === 'code');
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ const TPL = `
|
|||
</div>
|
||||
`;
|
||||
export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "bookProperties";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note && this.note.type === 'book';
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ const TPL = `
|
|||
</div>`;
|
||||
|
||||
export default class FilePropertiesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "fileProperties";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note && this.note.type === 'file';
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@ const TPL = `
|
|||
</div>`;
|
||||
|
||||
export default class ImagePropertiesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "imageProperties";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note && this.note.type === 'image';
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ const TPL = `
|
|||
</div>`;
|
||||
|
||||
export default class InheritedAttributesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "inheritedAttributes";
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ const TPL = `
|
|||
</div>`;
|
||||
|
||||
export default class LinkMapWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "linkMap";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ const TPL = `
|
|||
</div>
|
||||
`;
|
||||
export default class NoteInfoWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "noteInfo";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ const TPL = `
|
|||
</div>`;
|
||||
|
||||
export default class NotePathsWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "notePaths";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return this.note;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ const TPL = `
|
|||
</div>
|
||||
</div>`;
|
||||
|
||||
/**
|
||||
* TODO: figure out better name or conceptualize better.
|
||||
*/
|
||||
export default class NotePropertiesWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return this.note && !!this.note.getLabelValue('pageUrl');
|
||||
|
|
|
@ -22,6 +22,10 @@ const TPL = `
|
|||
`;
|
||||
|
||||
export default class OwnedAttributeListWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "ownedAttributes";
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
@ -35,6 +35,10 @@ const TPL = `
|
|||
`;
|
||||
|
||||
export default class PromotedAttributesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "promotedAttributes";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
|
|
@ -23,7 +23,6 @@ import Limit from "../search_options/limit.js";
|
|||
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
|
||||
import Debug from "../search_options/debug.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import toast from "../../services/toast.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="search-definition-widget">
|
||||
|
|
|
@ -31,6 +31,10 @@ const TPL = `
|
|||
`;
|
||||
|
||||
export default class SimilarNotesWidget extends NoteContextAwareWidget {
|
||||
get name() {
|
||||
return "similarNotes";
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
&& this.note.type !== 'search'
|
||||
|
|
|
@ -236,12 +236,6 @@ const DEFAULT_KEYBOARD_ACTIONS = [
|
|||
description: "Shows Note Source dialog",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "showLinkMap",
|
||||
defaultShortcuts: [],
|
||||
description: "Shows Link Map dialog",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "showOptions",
|
||||
defaultShortcuts: [],
|
||||
|
@ -324,12 +318,6 @@ const DEFAULT_KEYBOARD_ACTIONS = [
|
|||
separator: "Attributes (labels & relations)"
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "focusOnAttributes",
|
||||
defaultShortcuts: ["Alt+A"],
|
||||
description: "Put focus into attribute editor",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "addNewLabel",
|
||||
defaultShortcuts: ["Alt+L"],
|
||||
|
@ -343,6 +331,77 @@ const DEFAULT_KEYBOARD_ACTIONS = [
|
|||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: "Ribbon tabs"
|
||||
},
|
||||
|
||||
{
|
||||
actionName: "toggleRibbonTabBasicProperties",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Basic Properties",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabBookProperties",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Book Properties",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabFileProperties",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle File Properties",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabImageProperties",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Image Properties",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabOwnedAttributes",
|
||||
defaultShortcuts: ["Alt+A"],
|
||||
description: "Toggle Owned Attributes",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabInheritedAttributes",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Inherited Attributes",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabPromotedAttributes",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Promoted Attributes",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabLinkMap",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Link Map",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNoteInfo",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Note Info",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabNotePaths",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Note Paths",
|
||||
scope: "window"
|
||||
},
|
||||
{
|
||||
actionName: "toggleRibbonTabSimilarNotes",
|
||||
defaultShortcuts: [],
|
||||
description: "Toggle Similar Notes",
|
||||
scope: "window"
|
||||
},
|
||||
|
||||
{
|
||||
separator: "Other"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue