From 48c1f061c431200a356bb559b8fcdbc2d189fd4c Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Wed, 14 Jun 2023 13:27:52 +0400 Subject: [PATCH] Refactor Panels TS #5144 --- src/panels/index.ts | 31 ++++++++-------- src/panels/model/Panel.ts | 66 +++++++++++++++++++++++++++++++---- src/panels/view/PanelView.ts | 48 +++++++++++++------------ src/panels/view/PanelsView.ts | 5 ++- test/specs/panels/index.ts | 32 ++++++++--------- 5 files changed, 114 insertions(+), 68 deletions(-) diff --git a/src/panels/index.ts b/src/panels/index.ts index c05277bfe..9916e6999 100644 --- a/src/panels/index.ts +++ b/src/panels/index.ts @@ -28,7 +28,7 @@ import { Module } from '../abstract'; import EditorModel from '../editor/model/Editor'; import defaults, { PanelsConfig } from './config/config'; -import Panel from './model/Panel'; +import Panel, { PanelProperties } from './model/Panel'; import Panels from './model/Panels'; import PanelsView from './view/PanelsView'; @@ -73,14 +73,14 @@ export default class PanelManager extends Module { * @param {Object|Panel} panel Object with right properties or an instance of Panel * @return {Panel} Added panel. Useful in case passed argument was an Object * @example - * var newPanel = panelManager.addPanel({ - * id: 'myNewPanel', - * visible : true, - * buttons : [...], + * const newPanel = panelManager.addPanel({ + * id: 'myNewPanel', + * visible: true, + * buttons: [...], * }); */ - addPanel(panel: Panel | Record[]) { - return this.panels.add(panel); + addPanel(panel: Panel | PanelProperties) { + return this.panels.add(panel as Panel); } /** @@ -88,16 +88,13 @@ export default class PanelManager extends Module { * @param {Object|Panel|String} panel Object with right properties or an instance of Panel or Painel id * @return {Panel} Removed panel. Useful in case passed argument was an Object * @example - * const newPanel = panelManager.removePanel({ - * id: 'myNewPanel', - * visible : true, - * buttons : [...], - * }); - * + * const somePanel = panelManager.getPanel('somePanel'); + * const newPanel = panelManager.removePanel(somePanel); + * // or with id * const newPanel = panelManager.removePanel('myNewPanel'); * */ - removePanel(panel: Panel) { + removePanel(panel: Panel | string) { return this.panels.remove(panel); } @@ -145,7 +142,7 @@ export default class PanelManager extends Module { */ addButton(panelId: string, button: any) { var pn = this.getPanel(panelId); - return pn ? pn.get('buttons').add(button) : null; + return pn ? pn.buttons.add(button) : null; } /** @@ -167,7 +164,7 @@ export default class PanelManager extends Module { */ removeButton(panelId: string, button: any) { var pn = this.getPanel(panelId); - return pn && pn.get('buttons').remove(button); + return pn && pn.buttons.remove(button); } /** @@ -181,7 +178,7 @@ export default class PanelManager extends Module { getButton(panelId: string, id: string) { var pn = this.getPanel(panelId); if (pn) { - var res = pn.get('buttons').where({ id }); + var res = pn.buttons.where({ id }); return res.length ? res[0] : null; } return null; diff --git a/src/panels/model/Panel.ts b/src/panels/model/Panel.ts index d818002f5..0d45f5495 100644 --- a/src/panels/model/Panel.ts +++ b/src/panels/model/Panel.ts @@ -1,20 +1,72 @@ import PanelManager from '..'; import { ModuleModel } from '../../abstract'; +import { ObjectAny } from '../../common'; +import { ResizerOptions } from '../../utils/Resizer'; import Buttons from './Buttons'; -export default class Panel extends ModuleModel { +/** @private */ +export interface PanelProperties { + /** + * Panel id. + */ + id: string; + + /** + * Panel content. + */ + content?: string; + + /** + * Panel visibility. + * @default true + */ + visible?: boolean; + + /** + * Panel buttons. + * @default [] + */ + buttons?: ObjectAny[]; + + /** + * Panel attributes. + * @default {} + */ + attributes?: ObjectAny; + + /** + * Specify element query where to append the panel + */ + appendTo?: string; + + /** + * Resizable options. + */ + resizable?: boolean | ResizerOptions; + + el?: string; + + appendContent?: HTMLElement; +} + +export interface PanelPropertiesDefined extends Omit, 'buttons'> { + buttons: Buttons; + [key: string]: unknown; +} + +export default class Panel extends ModuleModel { defaults() { return { id: '', content: '', visible: true, - buttons: [], + buttons: [] as unknown as Buttons, attributes: {}, }; } get buttons() { - return this.get('buttons'); + return this.get('buttons')!; } private set buttons(buttons: Buttons) { @@ -23,9 +75,9 @@ export default class Panel extends ModuleModel { view?: any; - constructor(module: PanelManager, options: any) { - super(module, options); - var btn = this.get('buttons') || []; - this.buttons = new Buttons(module, btn); + constructor(module: PanelManager, options: PanelProperties) { + super(module, options as unknown as PanelPropertiesDefined); + const btn = this.get('buttons') || []; + this.buttons = new Buttons(module, btn as any); } } diff --git a/src/panels/view/PanelView.ts b/src/panels/view/PanelView.ts index 2291fa522..76dd56e08 100644 --- a/src/panels/view/PanelView.ts +++ b/src/panels/view/PanelView.ts @@ -5,7 +5,7 @@ import ButtonsView from './ButtonsView'; export default class PanelView extends ModuleView { constructor(model: Panel) { - super({ model, el: model.get('el') }); + super({ model, el: model.get('el') as string }); this.className = this.pfx + 'panel'; this.id = this.pfx + model.get('id'); this.listenTo(model, 'change:appendContent', this.appendContent); @@ -18,14 +18,14 @@ export default class PanelView extends ModuleView { * Append content of the panel * */ appendContent() { - this.$el.append(this.model.get('appendContent')); + this.$el.append(this.model.get('appendContent')!); } /** * Update content * */ updateContent() { - this.$el.html(this.model.get('content')); + this.$el.html(this.model.get('content')!); } toggleVisible() { @@ -47,24 +47,26 @@ export default class PanelView extends ModuleView { const resizable = this.model.get('resizable'); if (editor && resizable) { - var resz = resizable === true ? [1, 1, 1, 1] : resizable; - var resLen = resz.length; - var tc, + const resz = resizable === true ? [true, true, true, true] : resizable; + const resLen = (resz as boolean[]).length; + let tc, cr, bc, - cl = 0; + cl = false; // Choose which sides of the panel are resizable if (resLen == 2) { - tc = resz[0]; - bc = resz[0]; - cr = resz[1]; - cl = resz[1]; + const resBools = resz as boolean[]; + tc = resBools[0]; + bc = resBools[0]; + cr = resBools[1]; + cl = resBools[1]; } else if (resLen == 4) { - tc = resz[0]; - cr = resz[1]; - bc = resz[2]; - cl = resz[3]; + const resBools = resz as boolean[]; + tc = resBools[0]; + cr = resBools[1]; + bc = resBools[2]; + cl = resBools[3]; } const resizer: Resizer = new editor.Utils.Resizer({ @@ -72,13 +74,13 @@ export default class PanelView extends ModuleView { cr, bc, cl, - tl: 0, - tr: 0, - bl: 0, - br: 0, + tl: false, + tr: false, + bl: false, + br: false, appendTo: this.el, - silentFrames: 1, - avoidContainerUpdate: 1, + silentFrames: true, + avoidContainerUpdate: true, prefix: editor.getConfig().stylePrefix, onEnd() { em && em.trigger('change:canvasOffset'); @@ -101,7 +103,7 @@ export default class PanelView extends ModuleView { height, }; }, - ...resizable, + ...(resizable && typeof resizable !== 'boolean' ? resizable : {}), }); resizer.blur = () => {}; resizer.focus(this.el); @@ -122,7 +124,7 @@ export default class PanelView extends ModuleView { $el.append(buttonsView.render().el); } - $el.append(this.model.get('content')); + $el.append(this.model.get('content')!); return this; } } diff --git a/src/panels/view/PanelsView.ts b/src/panels/view/PanelsView.ts index 2ce780467..c800e3aba 100644 --- a/src/panels/view/PanelsView.ts +++ b/src/panels/view/PanelsView.ts @@ -39,7 +39,6 @@ export default class PanelsView extends ModuleView { * */ private addToCollection(model: Panel, fragmentEl?: DocumentFragment) { const fragment = fragmentEl || null; - const config = this.config; const el = model.get('el'); const view = new PanelView(model); const rendered = view.render().el; @@ -48,8 +47,8 @@ export default class PanelsView extends ModuleView { // Do nothing if the panel was requested to be another element if (el) { } else if (appendTo) { - var appendEl = document.querySelector(appendTo); - appendEl.appendChild(rendered); + const appendEl = document.querySelector(appendTo); + appendEl?.appendChild(rendered); } else { if (fragment) { fragment.appendChild(rendered); diff --git a/test/specs/panels/index.ts b/test/specs/panels/index.ts index 2c903db88..e4e390ea5 100644 --- a/test/specs/panels/index.ts +++ b/test/specs/panels/index.ts @@ -4,18 +4,14 @@ import Editor from '../../../src/editor/model/Editor'; describe('Panels', () => { describe('Main', () => { - var em; - var obj; + let em: Editor; + let obj: Panels; beforeEach(() => { em = new Editor({}); obj = new Panels(em); }); - afterEach(() => { - obj = null; - }); - test('Object exists', () => { expect(obj).toBeTruthy(); }); @@ -31,7 +27,7 @@ describe('Panels', () => { test('New panel has no buttons', () => { var panel = obj.addPanel({ id: 'test' }); - expect(panel.get('buttons').length).toEqual(0); + expect(panel.buttons.length).toEqual(0); }); test('Adds new panel correctly via Panel instance', () => { @@ -57,8 +53,8 @@ describe('Panels', () => { test('Add button correctly', () => { var panel = obj.addPanel({ id: 'test' }); var btn = obj.addButton('test', { id: 'btn' }); - expect(panel.get('buttons').length).toEqual(1); - expect(panel.get('buttons').at(0).get('id')).toEqual('btn'); + expect(panel.buttons.length).toEqual(1); + expect(panel.buttons.at(0).get('id')).toEqual('btn'); }); test('getButton returns null in case there is no requested panel', () => { @@ -83,7 +79,7 @@ describe('Panels', () => { test('Active correctly activable buttons', () => { const fn = jest.fn(); obj.addPanel({ id: 'test' }); - const btn = obj.addButton('test', { id: 'btn', active: true }); + const btn = obj.addButton('test', { id: 'btn', active: true })!; btn.on('updateActive', fn); obj.active(); expect(fn).toBeCalledTimes(1); @@ -92,7 +88,7 @@ describe('Panels', () => { test('Disable correctly buttons flagged as disabled', () => { const fn = jest.fn(); obj.addPanel({ id: 'test' }); - const btn = obj.addButton('test', { id: 'btn', disable: true }); + const btn = obj.addButton('test', { id: 'btn', disable: true })!; btn.on('change:disable', fn); obj.disableButtons(); expect(fn).toBeCalledTimes(1); @@ -106,19 +102,19 @@ describe('Panels', () => { test('Remove button correctly with object', () => { var panel = obj.addPanel({ id: 'test' }); var btn = obj.addButton('test', { id: 'btn' }); - expect(panel.get('buttons').length).toEqual(1); - expect(panel.get('buttons').at(0).get('id')).toEqual('btn'); + expect(panel.buttons.length).toEqual(1); + expect(panel.buttons.at(0).get('id')).toEqual('btn'); expect(obj.removeButton('test', { id: 'btn' })).toEqual(btn); - expect(panel.get('buttons').length).toEqual(0); + expect(panel.buttons.length).toEqual(0); }); test('Remove button correctly with sting', () => { var panel = obj.addPanel({ id: 'test' }); var btn = obj.addButton('test', { id: 'btn' }); - expect(panel.get('buttons').length).toEqual(1); - expect(panel.get('buttons').at(0).get('id')).toEqual('btn'); + expect(panel.buttons.length).toEqual(1); + expect(panel.buttons.at(0).get('id')).toEqual('btn'); expect(obj.removeButton('test', 'btn')).toEqual(btn); - expect(panel.get('buttons').length).toEqual(0); + expect(panel.buttons.length).toEqual(0); }); }); @@ -126,7 +122,7 @@ describe('Panels', () => { test('Removes panel correctly via object', () => { var panel = obj.addPanel({ id: 'test' }); expect(panel.get('id')).toEqual('test'); - obj.removePanel({ id: 'test' }); + obj.removePanel('test'); expect(panel.get('id')).toEqual('test'); });