diff --git a/package/spec/editor/api/DropDownMenuItems-spec.js b/package/spec/editor/api/DropDownMenuItems-spec.js new file mode 100644 index 0000000000..76d3d942e9 --- /dev/null +++ b/package/spec/editor/api/DropDownMenuItems-spec.js @@ -0,0 +1,72 @@ +import {DropDownMenuItems} from 'pageflow/editor/api/DropDownMenuItems'; + +import sinon from 'sinon'; + +describe('DropDownMenuItems', () => { + describe('#register/#findAllByMenuName', () => { + it( + 'allows getting a list of menu items by menu name', + () => { + var dropDownMenuItems = new DropDownMenuItems(); + + dropDownMenuItems.register({ + name: 'custom', + label: 'Custom Item', + selected: () => {} + }, { + menuName: 'someMenu', + }); + + var menuItem = dropDownMenuItems.findAllByMenuName('someMenu')[0]; + + expect(menuItem.name).toBe('custom'); + } + ); + + it( + 'only returns the list of menu items for the specified menu name', + () => { + var dropDownMenuItems = new DropDownMenuItems(); + + dropDownMenuItems.register({ + name: 'custom', + label: 'Custom Item', + selected: () => {} + }, { + menuName: 'someOtherMenu', + }); + + var menuItems = dropDownMenuItems.findAllByMenuName('someMenu'); + + expect(menuItems.length).toBe(0); + } + ); + + it( + 'allows registering multiple menu items per menu name', + () => { + var dropDownMenuItems = new DropDownMenuItems(); + + dropDownMenuItems.register({ + name: 'custom1', + label: 'Custom Item 1', + selected: () => {} + }, { + menuName: 'someMenu', + }); + + dropDownMenuItems.register({ + name: 'custom2', + label: 'Custom Item 2', + selected: () => {} + }, { + menuName: 'someMenu', + }); + + var menuItems = dropDownMenuItems.findAllByMenuName('someMenu'); + + expect(menuItems.length).toBe(2); + } + ); + }); +}); diff --git a/package/spec/editor/views/inputs/FileInputView-spec.js b/package/spec/editor/views/inputs/FileInputView-spec.js index cb866410be..a5d4e1dd76 100644 --- a/package/spec/editor/views/inputs/FileInputView-spec.js +++ b/package/spec/editor/views/inputs/FileInputView-spec.js @@ -3,6 +3,7 @@ import Backbone from 'backbone'; import * as support from '$support'; import {DropDownButton} from '$support/dominos/editor'; +import {editor} from 'pageflow/editor'; describe('FileInputView', () => { let testContext; @@ -65,6 +66,42 @@ describe('FileInputView', () => { }); }); + it('can render additional drop down menu item registered via editor API', () => { + const fixture = support.factories.imageFilesFixture({ + imageFileAttributes: {perma_id: 5} + }); + const model = new Configuration({ + file_id: 5, + }); + const handler = jest.fn(); + + editor.dropDownMenuItems.register({ + name: 'api_custom', + label: 'Custom Item added via editor API', + selected: handler + }, { + menuName: 'backdropImageFileInput', + } + ) + + var fileInputView = new FileInputView({ + collection: fixture.imageFiles, + model: model, + propertyName: 'file_id', + dropDownMenuName: 'backdropImageFileInput' + }); + + fileInputView.render(); + var dropDownButton = DropDownButton.find(fileInputView); + dropDownButton.selectMenuItemByLabel('Custom Item added via editor API'); + + expect(handler).toHaveBeenCalledWith({ + inputModel: model, + propertyName: 'file_id', + file: fixture.imageFile + }); + }); + it('supports nested items in additional drop down menu items', () => { const fixture = support.factories.imageFilesFixture({ imageFileAttributes: {perma_id: 5} diff --git a/package/src/editor/api/DropDownMenuItems.js b/package/src/editor/api/DropDownMenuItems.js new file mode 100644 index 0000000000..054a3f0b7d --- /dev/null +++ b/package/src/editor/api/DropDownMenuItems.js @@ -0,0 +1,14 @@ +import {Object} from 'pageflow/ui'; + +export const DropDownMenuItems = Object.extend({ + initialize: function() { + this.menuItems = {}; + }, + register: function(menuItem, {menuName}) { + this.menuItems[menuName] = this.menuItems[menuName] || []; + this.menuItems[menuName].push(menuItem); + }, + findAllByMenuName: function(menuName) { + return this.menuItems[menuName] || []; + } +}); diff --git a/package/src/editor/api/index.js b/package/src/editor/api/index.js index bd5dfa8e97..01ee2b31b3 100644 --- a/package/src/editor/api/index.js +++ b/package/src/editor/api/index.js @@ -3,6 +3,7 @@ import _ from 'underscore'; import {Object} from 'pageflow/ui'; import {CommonPageConfigurationTabs} from './CommonPageConfigurationTabs'; +import {DropDownMenuItems} from './DropDownMenuItems'; import {FailuresAPI} from './Failures'; import {FileTypes} from './FileTypes'; import {FileImporters} from './FileImporters' @@ -79,6 +80,12 @@ export const EditorApi = Object.extend( * @memberof editor */ this.fileImporters = new FileImporters(); + + /** + * List of additional menu items for dropdown menus + * @memberof editor + */ + this.dropDownMenuItems = new DropDownMenuItems(); }, /** diff --git a/package/src/editor/views/inputs/FileInputView.js b/package/src/editor/views/inputs/FileInputView.js index 68df139983..30787d90e2 100644 --- a/package/src/editor/views/inputs/FileInputView.js +++ b/package/src/editor/views/inputs/FileInputView.js @@ -145,6 +145,13 @@ export const FileInputView = Marionette.ItemView.extend({ items.add(this._createCustomMenuItem(file, item)); }); + if (this.options.dropDownMenuName) { + const customItems = editor.dropDownMenuItems.findAllByMenuName(this.options.dropDownMenuName); + _.each(customItems, item => { + items.add(this._createCustomMenuItem(file, item)); + }); + } + items.add(new FileInputView.EditFileSettingsMenuItem({ name: 'edit_file_settings', label: I18n.t('pageflow.editor.views.inputs.file_input.edit_file_settings')