diff --git a/src/common/index.js b/src/common/index.js index 1a48bc25c..391172c77 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -1,3 +1,4 @@ export { default as Model } from './Model'; export { default as Collection } from './Collection'; export { default as View } from './View'; +export { default as Module } from './module'; diff --git a/src/trait_manager/index.js b/src/trait_manager/index.js index 544a859ba..1f561662f 100644 --- a/src/trait_manager/index.js +++ b/src/trait_manager/index.js @@ -1,3 +1,4 @@ +import { debounce } from 'underscore'; import defaults from './config/config'; import TraitsView from './view/TraitsView'; import TraitView from './view/TraitView'; @@ -6,7 +7,7 @@ import TraitCheckboxView from './view/TraitCheckboxView'; import TraitNumberView from './view/TraitNumberView'; import TraitColorView from './view/TraitColorView'; import TraitButtonView from './view/TraitButtonView'; -import Module from 'common/module'; +import { Model, Module } from 'common'; export const evAll = 'trait'; export const evPfx = `${evAll}:`; @@ -54,12 +55,49 @@ export default () => { init(config = {}) { this.__initConfig(defaults, config); const c = this.config; + const model = new Model(); + this.model = model; + const { em } = this; const ppfx = c.pStylePrefix; this.types = { ...typesDef }; ppfx && (c.stylePrefix = `${ppfx}${c.stylePrefix}`); + + const upAll = debounce(() => this.__upSel()); + model.listenTo(em, 'component:toggled', upAll); + + const update = debounce(() => this.__onUp()); + model.listenTo(em, 'trait:update', update); + return this; }, + __upSel() { + this.select(this.em.getSelected()); + }, + + __onUp() { + this.select(this.getSelected()); + }, + + select(component) { + const traits = component ? component.getTraits() : []; + this.model.set({ component, traits }); + this.__trgCustom(); + }, + + getSelected() { + return this.model.get('component') || null; + }, + + getCurrent() { + return this.model.get('traits') || []; + }, + + __trgCustom(opts = {}) { + this.__ctn = this.__ctn || opts.container; + this.em.trigger(this.events.custom, { container: this.__ctn }); + }, + postRender() { this.__appendTo(); }, diff --git a/src/trait_manager/model/Trait.js b/src/trait_manager/model/Trait.js index d1cbae5d7..988fc6f9b 100644 --- a/src/trait_manager/model/Trait.js +++ b/src/trait_manager/model/Trait.js @@ -1,55 +1,80 @@ -import Backbone from 'backbone'; +import { Model } from 'common'; import { isUndefined } from 'underscore'; -export default Backbone.Model.extend({ - defaults: { - type: 'text', // text, number, range, select - label: '', - name: '', - min: '', - max: '', - unit: '', - step: 1, - value: '', - target: '', - default: '', - placeholder: '', - changeProp: 0, - options: [] - }, - +export default class Trait extends Model { initialize() { - const target = this.get('target'); - const name = this.get('name'); - const changeProp = this.get('changeProp'); + const { target, name, changeProp } = this.attributes; !this.get('id') && this.set('id', name); if (target) { this.target = target; this.unset('target'); - const targetEvent = changeProp - ? `change:${name}` - : `change:attributes:${name}`; + const targetEvent = changeProp ? `change:${name}` : `change:attributes:${name}`; this.listenTo(target, targetEvent, this.targetUpdated); } - }, + } + + /** + * Get trait id. + * @returns {String} + */ + getId() { + return this.get('id'); + } + + /** + * Get the trait type. + * @returns {String} + */ + getType() { + return this.get('type'); + } + + /** + * Get trait name. + * @returns {String} + */ + getName() { + return this.get('name'); + } /** - * Return all the propeties - * @returns {Object} + * Get trait label. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.locale=true] Use the locale string from i18n module + * @returns {String} */ + getLabel(opts = {}) { + const { locale = true } = opts; + const id = this.getId(); + const name = this.get('label') || this.getName(); + return (locale && this.em?.t(`traitManager.traits.labels.${id}`)) || name; + } + + setValue(value, opts = {}) { + const valueOpts = {}; + if (opts.partial) { + valueOpts.avoidStore = true; + } + this.setTargetValue(value, valueOpts); + } + props() { return this.attributes; - }, + } targetUpdated() { const value = this.getTargetValue(); this.set({ value }, { fromTarget: 1 }); - }, + this.em?.trigger('trait:update', { + trait: this, + component: this.target, + }); + } getValue() { return this.getTargetValue(); - }, + } getTargetValue() { const name = this.get('name'); @@ -63,7 +88,7 @@ export default Backbone.Model.extend({ } return !isUndefined(value) ? value : ''; - }, + } setTargetValue(value, opts = {}) { const target = this.target; @@ -84,7 +109,7 @@ export default Backbone.Model.extend({ attrs[name] = valueToSet; target.set('attributes', attrs, opts); } - }, + } setValueFromInput(value, final = 1, opts = {}) { const toSet = { value }; @@ -95,12 +120,8 @@ export default Backbone.Model.extend({ this.set('value', '', opts); this.set(toSet, opts); } - }, + } - /** - * Get the initial value of the trait - * @return {string} - */ getInitValue() { const target = this.target; const name = this.get('name'); @@ -113,4 +134,20 @@ export default Backbone.Model.extend({ return value || this.get('value') || this.get('default'); } -}); +} + +Trait.prototype.defaults = { + type: 'text', // text, number, range, select + label: '', + name: '', + min: '', + max: '', + unit: '', + step: 1, + value: '', + target: '', + default: '', + placeholder: '', + changeProp: 0, + options: [], +}; diff --git a/src/trait_manager/model/Traits.js b/src/trait_manager/model/Traits.js index cf8708e6b..2f7584567 100644 --- a/src/trait_manager/model/Traits.js +++ b/src/trait_manager/model/Traits.js @@ -17,6 +17,7 @@ export default Backbone.Collection.extend({ }, handleAdd(model) { + model.em = this.em; const target = this.target; if (target) { @@ -50,5 +51,5 @@ export default Backbone.Collection.extend({ } return Backbone.Collection.prototype.add.apply(this, [models, opt]); - } + }, });