From fd7de5c0e7e3b85c3923e35744a7ebb3be13d956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6?= Date: Fri, 29 Sep 2023 16:52:07 +0200 Subject: [PATCH] feat: support new file menu entry order, rename `if` to `enabled` and remove unused `templateName` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ --- __tests__/newFileMenu.spec.ts | 44 +++++++++++++++++++++-------------- lib/index.ts | 7 +++++- lib/newFileMenu.ts | 36 ++++++++++++++-------------- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/__tests__/newFileMenu.spec.ts b/__tests__/newFileMenu.spec.ts index 8a7054ad..c6e26de0 100644 --- a/__tests__/newFileMenu.spec.ts +++ b/__tests__/newFileMenu.spec.ts @@ -112,15 +112,22 @@ describe('NewFileMenu addEntry', () => { id: 123456, displayName: '123456', templateName: 'New file.txt', - iconClass: 'icon-filetype-text', handler: () => {}, } as unknown as Entry) - }).toThrowError('Invalid id or displayName property') + }).toThrowError('Invalid entry') expect(() => { newFileMenu.registerEntry({ - id: 'empty-file', - displayName: 123456, + id: 123456, + displayName: '123456', + iconSvgInline: '', + } as unknown as Entry) + }).toThrowError('Invalid entry') + + expect(() => { + newFileMenu.registerEntry({ + id: 123456, + displayName: '123456', templateName: 'New file.txt', iconClass: 'icon-filetype-text', handler: () => {}, @@ -130,12 +137,12 @@ describe('NewFileMenu addEntry', () => { expect(() => { newFileMenu.registerEntry({ id: 'empty-file', - displayName: '123456', - templateName: 123465, + displayName: 123456, + templateName: 'New file.txt', iconClass: 'icon-filetype-text', handler: () => {}, } as unknown as Entry) - }).toThrowError('Invalid templateName property') + }).toThrowError('Invalid id or displayName property') expect(() => { newFileMenu.registerEntry({ @@ -163,10 +170,10 @@ describe('NewFileMenu addEntry', () => { displayName: '123456', templateName: 'New file.txt', iconClass: 'icon-filetype-text', - if: true, + enabled: true, handler: () => {}, } as unknown as Entry) - }).toThrowError('Invalid if property') + }).toThrowError('Invalid enabled property') expect(() => { newFileMenu.registerEntry({ @@ -174,17 +181,20 @@ describe('NewFileMenu addEntry', () => { displayName: '123456', templateName: 'New file.txt', iconClass: 'icon-filetype-text', - handler: 'handler', + order: true, + handler: () => {}, } as unknown as Entry) - }).toThrowError('Invalid handler property') + }).toThrowError('Invalid order property') expect(() => { newFileMenu.registerEntry({ id: 'empty-file', displayName: '123456', + templateName: 'New file.txt', iconClass: 'icon-filetype-text', + handler: 'handler', } as unknown as Entry) - }).toThrowError('At least a templateName or a handler must be provided') + }).toThrowError('Invalid handler property') }) }) @@ -245,7 +255,7 @@ describe('NewFileMenu getEntries filter', () => { displayName: 'Create empty file', templateName: 'New file', iconClass: 'icon-file', - if: folder => (folder.permissions & Permission.CREATE) !== 0, + enabled: folder => (folder.permissions & Permission.CREATE) !== 0, handler: () => {}, } newFileMenu.registerEntry(entry1) @@ -255,7 +265,7 @@ describe('NewFileMenu getEntries filter', () => { displayName: 'Create new markdown file', templateName: 'New text.md', iconClass: 'icon-filetype-text', - if: folder => (folder.permissions & Permission.CREATE) !== 0, + enabled: folder => (folder.permissions & Permission.CREATE) !== 0, handler: () => {}, } newFileMenu.registerEntry(entry2) @@ -281,7 +291,7 @@ describe('NewFileMenu getEntries filter', () => { displayName: 'Create empty file', templateName: 'New file', iconClass: 'icon-file', - if: folder => (folder.permissions & Permission.CREATE) !== 0, + enabled: folder => (folder.permissions & Permission.CREATE) !== 0, handler: () => {}, } newFileMenu.registerEntry(entry1) @@ -291,7 +301,7 @@ describe('NewFileMenu getEntries filter', () => { displayName: 'Create new markdown file', templateName: 'New text.md', iconClass: 'icon-filetype-text', - if: folder => (folder.permissions & Permission.CREATE) !== 0, + enabled: folder => (folder.permissions & Permission.CREATE) !== 0, handler: () => {}, } newFileMenu.registerEntry(entry2) @@ -324,7 +334,7 @@ describe('NewFileMenu getEntries filter', () => { displayName: 'Create new markdown file', templateName: 'New text.md', iconClass: 'icon-filetype-text', - if: folder => (folder.permissions & Permission.CREATE) !== 0, + enabled: folder => (folder.permissions & Permission.CREATE) !== 0, handler: () => {}, } newFileMenu.registerEntry(entry2) diff --git a/lib/index.ts b/lib/index.ts index 88f5770f..2c280c0d 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -70,5 +70,10 @@ export const removeNewFileMenuEntry = function(entry: Entry | string) { */ export const getNewFileMenuEntries = function(context?: Folder) { const newFileMenu = getNewFileMenu() - return newFileMenu.getEntries(context) + return newFileMenu.getEntries(context).sort((a: Entry, b: Entry) => { + if (a.order !== undefined && b.order !== undefined) { + return a.order - b.order + } + return a.displayName.localeCompare(b.displayName) + }) } diff --git a/lib/newFileMenu.ts b/lib/newFileMenu.ts index b0287512..f88c310f 100644 --- a/lib/newFileMenu.ts +++ b/lib/newFileMenu.ts @@ -26,29 +26,35 @@ import logger from './utils/logger' export interface Entry { /** Unique ID */ id: string + /** Translatable string displayed in the menu */ displayName: string - /** Default new file name */ - templateName?: string + /** * Condition wether this entry is shown or not - * @param {Folder} context the creation context. Usually the current folder + * @param context the creation context. Usually the current folder */ - if?: (context: Folder) => boolean + enabled?: (context: Folder) => boolean + /** * Either iconSvgInline or iconClass must be defined * Svg as inline string. */ iconSvgInline?: string + /** * Existing icon css class * @deprecated use iconSvgInline instead */ iconClass?: string + + /** Order of the entry in the menu */ + order?: number + /** * Function to be run after creation - * @param {Folder} context the creation context. Usually the current folder - * @param {Node[]} content list of file/folders present in the context folder + * @param context the creation context. Usually the current folder + * @param content list of file/folders present in the context folder */ handler: (context: Folder, content: Node[]) => void } @@ -83,7 +89,7 @@ export class NewFileMenu { public getEntries(context?: Folder): Array { if (context) { return this._entries - .filter(entry => typeof entry.if === 'function' ? entry.if(context) : true) + .filter(entry => typeof entry.enabled === 'function' ? entry.enabled(context) : true) } return this._entries } @@ -93,7 +99,7 @@ export class NewFileMenu { } private validateEntry(entry: Entry) { - if (!entry.id || !entry.displayName || !(entry.iconSvgInline || entry.iconClass || entry.handler)) { + if (!entry.id || !entry.displayName || !(entry.iconSvgInline || entry.iconClass) || !entry.handler) { throw new Error('Invalid entry') } @@ -107,20 +113,16 @@ export class NewFileMenu { throw new Error('Invalid icon provided') } - if (entry.if !== undefined && typeof entry.if !== 'function') { - throw new Error('Invalid if property') - } - - if (entry.templateName && typeof entry.templateName !== 'string') { - throw new Error('Invalid templateName property') + if (entry.enabled !== undefined && typeof entry.enabled !== 'function') { + throw new Error('Invalid enabled property') } - if (entry.handler && typeof entry.handler !== 'function') { + if (typeof entry.handler !== 'function') { throw new Error('Invalid handler property') } - if (!entry.templateName && !entry.handler) { - throw new Error('At least a templateName or a handler must be provided') + if ('order' in entry && typeof entry.order !== 'number') { + throw new Error('Invalid order property') } if (this.getEntryIndex(entry.id) !== -1) {