mirror of https://github.com/artf/grapesjs.git
27 changed files with 3153 additions and 4007 deletions
@ -1,6 +1,35 @@ |
|||
import Backbone from 'backbone'; |
|||
import Backbone, { AddOptions } from 'backbone'; |
|||
import { isArray, isObject, isUndefined } from 'underscore'; |
|||
import Model from './Model'; |
|||
|
|||
export default class Collection< |
|||
TModel extends Model = Model |
|||
> extends Backbone.Collection<TModel> {} |
|||
type Module<TModel extends Model> = TModel extends Model<infer M> ? M : unknown; |
|||
type ModelConstructor<TModel extends Model> = { new (mod: Module<TModel>, attr: any): TModel }; |
|||
|
|||
export default class Collection<TModel extends Model = Model> extends Backbone.Collection<TModel> { |
|||
module!: Module<TModel>; |
|||
private newModel!: ModelConstructor<TModel>; |
|||
|
|||
add(model: Array<Record<string, any>> | TModel, options?: AddOptions): TModel; |
|||
add(models: Array<Array<Record<string, any>> | TModel>, options?: AddOptions): TModel[]; |
|||
add(model?: unknown, options?: AddOptions): any { |
|||
//Note: the undefined case needed because backbonejs not handle the reset() correctly
|
|||
var models = isArray(model) ? model : !isUndefined(model) ? [model] : undefined; |
|||
|
|||
models = models?.map(m => (m instanceof this.newModel ? m : new this.newModel(this.module, m))) ?? [undefined]; |
|||
|
|||
return super.add(isArray(model) ? models : models[0], options); |
|||
} |
|||
|
|||
constructor( |
|||
module: Module<TModel>, |
|||
models: TModel[] | Array<Record<string, any>>, |
|||
modelConstructor: ModelConstructor<TModel> |
|||
) { |
|||
super(models, { module, modelConstructor }); |
|||
} |
|||
|
|||
preinitialize(models?: TModel[] | Array<Record<string, any>>, options?: any) { |
|||
this.newModel = options.modelConstructor; |
|||
this.module = options.module; |
|||
} |
|||
} |
|||
|
|||
@ -1,29 +1,46 @@ |
|||
import Backbone from 'backbone'; |
|||
import Collection from './Collection'; |
|||
import Model from './Model'; |
|||
import Module, { IBaseModule } from './Module'; |
|||
import { IBaseModule } from './Module'; |
|||
|
|||
export default class View<TModel extends Model = Model, TElement extends Element = HTMLElement> extends Backbone.View< |
|||
TModel, |
|||
TElement |
|||
> { |
|||
type ModuleFromModel<TModel extends Model> = TModel extends Model<infer M> ? M : unknown; |
|||
type Module<TItem extends Model | Collection> = TItem extends Collection<infer M> |
|||
? ModuleFromModel<M> |
|||
: TItem extends Model<infer M> |
|||
? M |
|||
: unknown; |
|||
|
|||
type TCollection<TItem extends Model | Collection> = TItem extends Collection ? TItem : unknown; |
|||
|
|||
export default class View< |
|||
TModel extends Model | Collection = Model, |
|||
TElement extends Element = HTMLElement |
|||
> extends Backbone.View<TModel extends Model ? TModel : undefined, TElement> { |
|||
protected get pfx() { |
|||
return this.ppfx + this.config.stylePrefix || ''; |
|||
return this.ppfx + (this.config as any).stylePrefix || ''; |
|||
} |
|||
|
|||
protected get ppfx() { |
|||
return (this.em.config as any).stylePrefix || ''; |
|||
return this.em.config.stylePrefix || ''; |
|||
} |
|||
|
|||
protected get module(): TModel extends Model<infer M> ? M : unknown { |
|||
//console.log((this.collection.first as any).module)
|
|||
return this.model?.module ?? (this.collection as any).module; |
|||
collection!: TModel extends Model ? Collection<Model> : TModel; |
|||
|
|||
protected get module(): Module<TModel> { |
|||
return (this.model as any)?.module ?? this.collection.module; |
|||
} |
|||
|
|||
protected get em() { |
|||
return this.module.em; |
|||
} |
|||
|
|||
protected get config(): TModel extends Model<infer M> ? (M extends IBaseModule<infer C> ? C : unknown) : unknown { |
|||
protected get config(): Module<TModel> extends IBaseModule<infer C> ? C : unknown { |
|||
return this.module.config as any; |
|||
} |
|||
|
|||
public className!: string; |
|||
|
|||
preinitialize(options?: any) { |
|||
this.className = ''; |
|||
} |
|||
} |
|||
|
|||
@ -1,245 +0,0 @@ |
|||
/** |
|||
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/panels/config/config.js)
|
|||
* ```js
|
|||
* const editor = grapesjs.init({ |
|||
* panels: { |
|||
* // options
|
|||
* } |
|||
* }) |
|||
* ``` |
|||
* |
|||
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance |
|||
* |
|||
* ```js
|
|||
* const panelManager = editor.Panels; |
|||
* ``` |
|||
* |
|||
* * [addPanel](#addpanel) |
|||
* * [addButton](#addbutton) |
|||
* * [getButton](#getbutton) |
|||
* * [getPanel](#getpanel) |
|||
* * [getPanels](#getpanels) |
|||
* * [getPanelsEl](#getpanelsel) |
|||
* * [removePanel](#removepanel) |
|||
* * [removeButton](#removebutton) |
|||
* |
|||
* @module Panels |
|||
*/ |
|||
import defaults from './config/config'; |
|||
import Panel from './model/Panel'; |
|||
import Panels from './model/Panels'; |
|||
import PanelsView from './view/PanelsView'; |
|||
|
|||
export default () => { |
|||
var c = {}; |
|||
var panels, PanelsViewObj; |
|||
|
|||
return { |
|||
/** |
|||
* Name of the module |
|||
* @type {String} |
|||
* @private |
|||
*/ |
|||
name: 'Panels', |
|||
|
|||
/** |
|||
* Initialize module. Automatically called with a new instance of the editor |
|||
* @param {Object} config Configurations |
|||
* @private |
|||
*/ |
|||
init(config) { |
|||
c = config || {}; |
|||
for (var name in defaults) { |
|||
if (!(name in c)) c[name] = defaults[name]; |
|||
} |
|||
|
|||
var ppfx = c.pStylePrefix; |
|||
if (ppfx) c.stylePrefix = ppfx + c.stylePrefix; |
|||
|
|||
panels = new Panels(c.defaults); |
|||
return this; |
|||
}, |
|||
|
|||
/** |
|||
* Returns the collection of panels |
|||
* @return {Collection} Collection of panel |
|||
*/ |
|||
getPanels() { |
|||
return panels; |
|||
}, |
|||
|
|||
/** |
|||
* Returns panels element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getPanelsEl() { |
|||
return PanelsViewObj && PanelsViewObj.el; |
|||
}, |
|||
|
|||
/** |
|||
* Add new panel to the collection |
|||
* @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 : [...], |
|||
* }); |
|||
*/ |
|||
addPanel(panel) { |
|||
return panels.add(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 newPanel = panelManager.removePanel('myNewPanel'); |
|||
* |
|||
*/ |
|||
removePanel(panel) { |
|||
return panels.remove(panel); |
|||
}, |
|||
|
|||
/** |
|||
* Get panel by ID |
|||
* @param {string} id Id string |
|||
* @return {Panel|null} |
|||
* @example |
|||
* var myPanel = panelManager.getPanel('myNewPanel'); |
|||
*/ |
|||
getPanel(id) { |
|||
var res = panels.where({ id }); |
|||
return res.length ? res[0] : null; |
|||
}, |
|||
|
|||
/** |
|||
* Add button to the panel |
|||
* @param {string} panelId Panel's ID |
|||
* @param {Object|Button} button Button object or instance of Button |
|||
* @return {Button|null} Added button. Useful in case passed button was an Object |
|||
* @example |
|||
* var newButton = panelManager.addButton('myNewPanel',{ |
|||
* id: 'myNewButton', |
|||
* className: 'someClass', |
|||
* command: 'someCommand', |
|||
* attributes: { title: 'Some title'}, |
|||
* active: false, |
|||
* }); |
|||
* // It's also possible to pass the command as an object
|
|||
* // with .run and .stop methods
|
|||
* ... |
|||
* command: { |
|||
* run: function(editor) { |
|||
* ... |
|||
* }, |
|||
* stop: function(editor) { |
|||
* ... |
|||
* } |
|||
* }, |
|||
* // Or simply like a function which will be evaluated as a single .run command
|
|||
* ... |
|||
* command: function(editor) { |
|||
* ... |
|||
* } |
|||
*/ |
|||
addButton(panelId, button) { |
|||
var pn = this.getPanel(panelId); |
|||
return pn ? pn.get('buttons').add(button) : null; |
|||
}, |
|||
|
|||
/** |
|||
* Remove button from the panel |
|||
* @param {String} panelId Panel's ID |
|||
* @param {String} buttonId Button's ID |
|||
* @return {Button|null} Removed button. |
|||
* @example |
|||
* const removedButton = panelManager.addButton('myNewPanel',{ |
|||
* id: 'myNewButton', |
|||
* className: 'someClass', |
|||
* command: 'someCommand', |
|||
* attributes: { title: 'Some title'}, |
|||
* active: false, |
|||
* }); |
|||
* |
|||
* const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton'); |
|||
* |
|||
*/ |
|||
removeButton(panelId, button) { |
|||
var pn = this.getPanel(panelId); |
|||
return pn && pn.get('buttons').remove(button); |
|||
}, |
|||
|
|||
/** |
|||
* Get button from the panel |
|||
* @param {string} panelId Panel's ID |
|||
* @param {string} id Button's ID |
|||
* @return {Button|null} |
|||
* @example |
|||
* var button = panelManager.getButton('myPanel','myButton'); |
|||
*/ |
|||
getButton(panelId, id) { |
|||
var pn = this.getPanel(panelId); |
|||
if (pn) { |
|||
var res = pn.get('buttons').where({ id }); |
|||
return res.length ? res[0] : null; |
|||
} |
|||
return null; |
|||
}, |
|||
|
|||
/** |
|||
* Render panels and buttons |
|||
* @return {HTMLElement} |
|||
* @private |
|||
*/ |
|||
render() { |
|||
PanelsViewObj && PanelsViewObj.remove(); |
|||
PanelsViewObj = new PanelsView({ |
|||
collection: panels, |
|||
config: c, |
|||
}); |
|||
return PanelsViewObj.render().el; |
|||
}, |
|||
|
|||
/** |
|||
* Active activable buttons |
|||
* @private |
|||
*/ |
|||
active() { |
|||
this.getPanels().each(p => { |
|||
p.get('buttons').each(btn => { |
|||
btn.get('active') && btn.trigger('updateActive'); |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* Disable buttons flagged as disabled |
|||
* @private |
|||
*/ |
|||
disableButtons() { |
|||
this.getPanels().each(p => { |
|||
p.get('buttons').each(btn => { |
|||
if (btn.get('disable')) btn.trigger('change:disable'); |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
destroy() { |
|||
panels.reset(); |
|||
panels.stopListening(); |
|||
PanelsViewObj && PanelsViewObj.remove(); |
|||
[c, panels, PanelsViewObj].forEach(i => (i = {})); |
|||
}, |
|||
|
|||
Panel, |
|||
}; |
|||
}; |
|||
@ -0,0 +1,232 @@ |
|||
/** |
|||
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/panels/config/config.js)
|
|||
* ```js
|
|||
* const editor = grapesjs.init({ |
|||
* panels: { |
|||
* // options
|
|||
* } |
|||
* }) |
|||
* ``` |
|||
* |
|||
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance |
|||
* |
|||
* ```js
|
|||
* const panelManager = editor.Panels; |
|||
* ``` |
|||
* |
|||
* * [addPanel](#addpanel) |
|||
* * [addButton](#addbutton) |
|||
* * [getButton](#getbutton) |
|||
* * [getPanel](#getpanel) |
|||
* * [getPanels](#getpanels) |
|||
* * [getPanelsEl](#getpanelsel) |
|||
* * [removePanel](#removepanel) |
|||
* * [removeButton](#removebutton) |
|||
* |
|||
* @module Panels |
|||
*/ |
|||
import { Module } from '../abstract'; |
|||
import EditorModel from '../editor/model/Editor'; |
|||
import defaults from './config/config'; |
|||
import Button from './model/Button'; |
|||
import Panel from './model/Panel'; |
|||
import Panels from './model/Panels'; |
|||
import PanelsView from './view/PanelsView'; |
|||
|
|||
export default class PanelManager extends Module<typeof defaults> { |
|||
//config = {};
|
|||
panels: Panels; |
|||
PanelsViewObj?: PanelsView; |
|||
|
|||
/** |
|||
* Initialize module. Automatically called with a new instance of the editor |
|||
* @param {Object} config Configurations |
|||
* @private |
|||
*/ |
|||
constructor(em: EditorModel) { |
|||
super(em, 'Panels', defaults); |
|||
this.panels = new Panels(this, this.config.defaults); |
|||
for (var name in defaults) { |
|||
//@ts-ignore
|
|||
if (!(name in this.config)) this.config[name] = defaults[name]; |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* Returns the collection of panels |
|||
* @return {Collection} Collection of panel |
|||
*/ |
|||
getPanels() { |
|||
return this.panels; |
|||
} |
|||
|
|||
/** |
|||
* Returns panels element |
|||
* @return {HTMLElement} |
|||
*/ |
|||
getPanelsEl() { |
|||
return this.PanelsViewObj && this.PanelsViewObj.el; |
|||
} |
|||
|
|||
/** |
|||
* Add new panel to the collection |
|||
* @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 : [...], |
|||
* }); |
|||
*/ |
|||
addPanel(panel: Panel | Array<Record<string, any>>) { |
|||
return this.panels.add(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 newPanel = panelManager.removePanel('myNewPanel'); |
|||
* |
|||
*/ |
|||
removePanel(panel: Panel) { |
|||
return this.panels.remove(panel); |
|||
} |
|||
|
|||
/** |
|||
* Get panel by ID |
|||
* @param {string} id Id string |
|||
* @return {Panel|null} |
|||
* @example |
|||
* var myPanel = panelManager.getPanel('myNewPanel'); |
|||
*/ |
|||
getPanel(id: string) { |
|||
var res = this.panels.where({ id }); |
|||
return res.length ? res[0] : null; |
|||
} |
|||
|
|||
/** |
|||
* Add button to the panel |
|||
* @param {string} panelId Panel's ID |
|||
* @param {Object|Button} button Button object or instance of Button |
|||
* @return {Button|null} Added button. Useful in case passed button was an Object |
|||
* @example |
|||
* var newButton = panelManager.addButton('myNewPanel',{ |
|||
* id: 'myNewButton', |
|||
* className: 'someClass', |
|||
* command: 'someCommand', |
|||
* attributes: { title: 'Some title'}, |
|||
* active: false, |
|||
* }); |
|||
* // It's also possible to pass the command as an object
|
|||
* // with .run and .stop methods
|
|||
* ... |
|||
* command: { |
|||
* run: function(editor) { |
|||
* ... |
|||
* }, |
|||
* stop: function(editor) { |
|||
* ... |
|||
* } |
|||
* }, |
|||
* // Or simply like a function which will be evaluated as a single .run command
|
|||
* ... |
|||
* command: function(editor) { |
|||
* ... |
|||
* } |
|||
*/ |
|||
addButton(panelId: string, button: any) { |
|||
var pn = this.getPanel(panelId); |
|||
return pn ? pn.get('buttons').add(button) : null; |
|||
} |
|||
|
|||
/** |
|||
* Remove button from the panel |
|||
* @param {String} panelId Panel's ID |
|||
* @param {String} buttonId Button's ID |
|||
* @return {Button|null} Removed button. |
|||
* @example |
|||
* const removedButton = panelManager.addButton('myNewPanel',{ |
|||
* id: 'myNewButton', |
|||
* className: 'someClass', |
|||
* command: 'someCommand', |
|||
* attributes: { title: 'Some title'}, |
|||
* active: false, |
|||
* }); |
|||
* |
|||
* const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton'); |
|||
* |
|||
*/ |
|||
removeButton(panelId: string, button: any) { |
|||
var pn = this.getPanel(panelId); |
|||
return pn && pn.get('buttons').remove(button); |
|||
} |
|||
|
|||
/** |
|||
* Get button from the panel |
|||
* @param {string} panelId Panel's ID |
|||
* @param {string} id Button's ID |
|||
* @return {Button|null} |
|||
* @example |
|||
* var button = panelManager.getButton('myPanel','myButton'); |
|||
*/ |
|||
getButton(panelId: string, id: string) { |
|||
var pn = this.getPanel(panelId); |
|||
if (pn) { |
|||
var res = pn.get('buttons').where({ id }); |
|||
return res.length ? res[0] : null; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* Render panels and buttons |
|||
* @return {HTMLElement} |
|||
*/ |
|||
render() { |
|||
this.PanelsViewObj && this.PanelsViewObj.remove(); |
|||
this.PanelsViewObj = new PanelsView(this.panels); |
|||
return this.PanelsViewObj.render().el; |
|||
} |
|||
|
|||
/** |
|||
* Active activable buttons |
|||
* @private |
|||
*/ |
|||
active() { |
|||
this.getPanels().each(p => { |
|||
//@ts-ignore
|
|||
p.get('buttons').each(btn => { |
|||
btn.get('active') && btn.trigger('updateActive'); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Disable buttons flagged as disabled |
|||
* @private |
|||
*/ |
|||
disableButtons() { |
|||
this.getPanels().each(p => { |
|||
//@ts-ignore
|
|||
p.get('buttons').each(btn => { |
|||
if (btn.get('disable')) btn.trigger('change:disable'); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
destroy() { |
|||
this.panels.reset(); |
|||
this.panels.stopListening(); |
|||
this.PanelsViewObj && this.PanelsViewObj.remove(); |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
import { Model } from '../../common'; |
|||
|
|||
export default class Button extends Model { |
|||
defaults() { |
|||
return { |
|||
id: '', |
|||
label: '', |
|||
tagName: 'span', |
|||
className: '', |
|||
command: '', |
|||
context: '', |
|||
buttons: [], |
|||
attributes: {}, |
|||
options: {}, |
|||
active: false, |
|||
dragDrop: false, |
|||
togglable: true, |
|||
runDefaultCommand: true, |
|||
stopDefaultCommand: false, |
|||
disable: false, |
|||
}; |
|||
} |
|||
|
|||
initialize(options) { |
|||
if (this.get('buttons').length) { |
|||
var Buttons = require('./Buttons').default; |
|||
this.set('buttons', new Buttons(this.get('buttons'))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
import PanelManager from '..'; |
|||
import { Model } from '../../abstract'; |
|||
import EditorModel from '../../editor/model/Editor'; |
|||
import Buttons from './Buttons'; |
|||
|
|||
export default class Button extends Model<PanelManager> { |
|||
defaults() { |
|||
return { |
|||
id: '', |
|||
label: '', |
|||
tagName: 'span', |
|||
className: '', |
|||
command: '', |
|||
context: '', |
|||
buttons: [], |
|||
attributes: {}, |
|||
options: {}, |
|||
active: false, |
|||
dragDrop: false, |
|||
togglable: true, |
|||
runDefaultCommand: true, |
|||
stopDefaultCommand: false, |
|||
disable: false, |
|||
}; |
|||
} |
|||
|
|||
get className(): string { |
|||
return this.get('className'); |
|||
} |
|||
|
|||
get command(): string { |
|||
return this.get('command'); |
|||
} |
|||
|
|||
get active(): boolean { |
|||
return this.get('active'); |
|||
} |
|||
set active(isActive: boolean) { |
|||
this.set('active', isActive); |
|||
} |
|||
|
|||
get togglable(): boolean { |
|||
return this.get('togglable'); |
|||
} |
|||
|
|||
get runDefaultCommand(): boolean { |
|||
return this.get('runDefaultCommand'); |
|||
} |
|||
get stopDefaultCommand(): boolean { |
|||
return this.get('stopDefaultCommand'); |
|||
} |
|||
get disable(): boolean { |
|||
return this.get('disable'); |
|||
} |
|||
|
|||
constructor(module: PanelManager, options: any) { |
|||
super(module, options); |
|||
if (this.get('buttons').length) { |
|||
this.set('buttons', new Buttons(this.module, this.get('buttons'))); |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
import { Model } from '../../common'; |
|||
import Buttons from './Buttons'; |
|||
|
|||
export default class Panel extends Model { |
|||
defaults() { |
|||
return { |
|||
id: '', |
|||
content: '', |
|||
visible: true, |
|||
buttons: [], |
|||
attributes: {}, |
|||
}; |
|||
} |
|||
|
|||
initialize(options) { |
|||
this.btn = this.get('buttons') || []; |
|||
this.buttons = new Buttons(this.btn); |
|||
this.set('buttons', this.buttons); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
import PanelManager from '..'; |
|||
import { Model } from '../../abstract'; |
|||
import Buttons from './Buttons'; |
|||
|
|||
export default class Panel extends Model<PanelManager> { |
|||
defaults() { |
|||
return { |
|||
id: '', |
|||
content: '', |
|||
visible: true, |
|||
buttons: [], |
|||
attributes: {}, |
|||
}; |
|||
} |
|||
|
|||
get buttons() { |
|||
return this.get('buttons'); |
|||
} |
|||
|
|||
private set buttons(buttons: Buttons) { |
|||
this.set('buttons', buttons); |
|||
} |
|||
|
|||
view?: any; |
|||
|
|||
constructor(module: PanelManager, options: any) { |
|||
super(module, options); |
|||
var btn = this.get('buttons') || []; |
|||
this.buttons = new Buttons(module, btn); |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
import { Collection } from '../../common'; |
|||
import Panel from './Panel'; |
|||
|
|||
export default class Panels extends Collection {} |
|||
|
|||
Panels.prototype.model = Panel; |
|||
@ -0,0 +1,11 @@ |
|||
import PanelManager from '..'; |
|||
import { Collection } from '../../abstract'; |
|||
import Panel from './Panel'; |
|||
|
|||
export default class Panels extends Collection<Panel> { |
|||
constructor(module: PanelManager, models: Panel[] | Array<Record<string, any>>) { |
|||
super(module, models, Panel); |
|||
} |
|||
} |
|||
|
|||
Panels.prototype.model = Panel; |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue