Skip to content

Commit

Permalink
Refactor Panels TS GrapesJS#5144
Browse files Browse the repository at this point in the history
  • Loading branch information
artf authored and pety-dc committed Aug 14, 2023
1 parent e246f4b commit 3cc8469
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 68 deletions.
31 changes: 14 additions & 17 deletions src/panels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -73,31 +73,28 @@ export default class PanelManager extends Module<PanelsConfig> {
* @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<string, any>[]) {
return this.panels.add(panel);
addPanel(panel: Panel | PanelProperties) {
return this.panels.add(panel as Panel);
}

/**
* Remove a panel from the collection
* @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);
}

Expand Down Expand Up @@ -145,7 +142,7 @@ export default class PanelManager extends Module<PanelsConfig> {
*/
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;
}

/**
Expand All @@ -167,7 +164,7 @@ export default class PanelManager extends Module<PanelsConfig> {
*/
removeButton(panelId: string, button: any) {
var pn = this.getPanel(panelId);
return pn && pn.get('buttons').remove(button);
return pn && pn.buttons.remove(button);
}

/**
Expand All @@ -181,7 +178,7 @@ export default class PanelManager extends Module<PanelsConfig> {
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;
Expand Down
66 changes: 59 additions & 7 deletions src/panels/model/Panel.ts
Original file line number Diff line number Diff line change
@@ -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<PanelManager> {
/** @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<Required<PanelProperties>, 'buttons'> {
buttons: Buttons;
[key: string]: unknown;
}

export default class Panel extends ModuleModel<PanelManager, PanelPropertiesDefined> {
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) {
Expand All @@ -23,9 +75,9 @@ export default class Panel extends ModuleModel<PanelManager> {

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);
}
}
48 changes: 25 additions & 23 deletions src/panels/view/PanelView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ButtonsView from './ButtonsView';

export default class PanelView extends ModuleView<Panel> {
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);
Expand All @@ -18,14 +18,14 @@ export default class PanelView extends ModuleView<Panel> {
* 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() {
Expand All @@ -47,38 +47,40 @@ export default class PanelView extends ModuleView<Panel> {
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({
tc,
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');
Expand All @@ -101,7 +103,7 @@ export default class PanelView extends ModuleView<Panel> {
height,
};
},
...resizable,
...(resizable && typeof resizable !== 'boolean' ? resizable : {}),
});
resizer.blur = () => {};
resizer.focus(this.el);
Expand All @@ -122,7 +124,7 @@ export default class PanelView extends ModuleView<Panel> {
$el.append(buttonsView.render().el);
}

$el.append(this.model.get('content'));
$el.append(this.model.get('content')!);
return this;
}
}
5 changes: 2 additions & 3 deletions src/panels/view/PanelsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export default class PanelsView extends ModuleView<Panels> {
* */
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;
Expand All @@ -48,8 +47,8 @@ export default class PanelsView extends ModuleView<Panels> {
// 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);
Expand Down
32 changes: 14 additions & 18 deletions test/specs/panels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand All @@ -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', () => {
Expand All @@ -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', () => {
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -106,27 +102,27 @@ 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);
});
});

describe('Removes Panel', () => {
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');
});

Expand Down

0 comments on commit 3cc8469

Please sign in to comment.