js/src/shared/ModuleBrowser/ModuleBrowserController.js
//KB.Backbone.ModuleBrowser
var ModuleDefinitions = require('shared/ModuleBrowser/ModuleBrowserDefinitions');
var ModuleDefModel = require('shared/ModuleBrowser/ModuleDefinitionModel');
var ModuleBrowserDescription = require('shared/ModuleBrowser/ModuleBrowserDescriptions');
var ModuleBrowserNavigation = require('shared/ModuleBrowser/ModuleBrowserNavigation');
var Checks = require('common/Checks');
var Notice = require('common/Notice');
var Payload = require('common/Payload');
var Ajax = require('common/Ajax');
var TinyMCE = require('common/TinyMCE');
var Config = require('common/Config');
var tplModuleBrowser = require('templates/backend/modulebrowser/module-browser.hbs');
module.exports = Backbone.View.extend({
initialize: function (options) {
this.options = options || {};
this.isOpen = false;
this.area = this.options.area;
this.viewMode = this.getViewMode();
this.modulesDefinitions = new ModuleDefinitions(this.prepareAssignedModules(), {
model: ModuleDefModel,
area: this.options.area
}).setup();
// render and append the skeleton markup to the browsers root element
this.$el.append(tplModuleBrowser({viewMode: this.getViewModeClass()}));
this.$backdrop = jQuery('<div class="kb-module-browser--backdrop"></div>');
// render the list sub view
//this.subviews.ModulesList = new ModuleBrowserList({
// el: jQuery('.modules-list', this.$el),
// browser: this
//});
this.$list = jQuery('.modules-list', this.$el);
// render description sub view
this.subviews.ModuleDescription = new ModuleBrowserDescription({
el: jQuery('.module-description', this.$el),
browser: this
});
// render tab navigation subview
this.subviews.Navigation = new ModuleBrowserNavigation({
el: jQuery('.module-categories', this.$el),
cats: this.modulesDefinitions.categories,
browser: this
});
// bind to navigation views custom change event
this.listenTo(this.subviews.Navigation, 'browser:change', this.update);
this.bindHandlers();
},
// element tag
tagName: 'div',
// element id
id: 'module-browser',
//element class
className: 'kb-overlay',
//events
events: {
'click .close-browser': 'close',
'click .module-browser--switch__list-view': 'toggleViewMode',
'click .module-browser--switch__grid-view': 'toggleViewMode'
},
subviews: {},
toggleViewMode: function () {
jQuery('.module-browser-wrapper', this.$el).toggleClass('module-browser--list-view module-browser--grid-view');
var abbr = 'mdb_' + this.area.model.get('id') + '_state';
var curr = store.get(abbr);
if (curr == 'list') {
this.viewMode = 'grid';
store.set(abbr, 'grid');
} else {
this.viewMode = 'list';
store.set(abbr, 'list');
}
},
// this method gets called when the user clicks on 'add module'
// prepares the modules for the browser
// calls 'open'
render: function () {
this.open();
},
getViewMode: function () {
var abbr = 'mdb_' + this.area.model.get('id') + '_state';
if (store.get(abbr)) {
return store.get(abbr);
} else {
store.set(abbr, 'list');
}
return 'list';
},
getViewModeClass: function () {
if (this.viewMode === 'list') {
return 'module-browser--list-view';
} else {
return 'module-browser--grid-view';
}
},
bindHandlers: function () {
var that = this;
jQuery('body').on('click', function (e) {
if (that.isOpen) {
if (jQuery(e.target).is('.kb-module-browser--backdrop')) {
that.close();
}
}
});
jQuery(document).keydown(function (e) {
if (!that.isOpen) {
return;
}
switch (e.which) {
case 27:
that.close();
break;
default:
return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
},
open: function () {
// render root element
this.$el.appendTo('body');
this.$backdrop.appendTo('body');
// add class to root element of wp admin screen
jQuery('#wpwrap').addClass('module-browser-open');
jQuery('.kb-nano').nanoScroller({
flash: true,
contentClass: 'kb-nano-content'
});
this.isOpen = true;
},
// close the browser
// TODO clean up and remove all references & bindings
close: function () {
jQuery('#wpwrap').removeClass('module-browser-open');
this.trigger('browser:close');
this.$backdrop.detach();
this.$el.detach();
this.isOpen = false;
},
// update list view upon navigation
update: function (cat) {
var id = cat.model.get('id');
var modules = this.modulesDefinitions.getModules(id);
//this.subviews.ModulesList.setModules(modules).update();
cat.renderList();
// this.listenTo(this.subviews.ModulesList, 'loadDetails', this.loadDetails);
},
// update details in description view
loadDetails: function (model) {
this.subviews.ModuleDescription.model = model;
this.subviews.ModuleDescription.update();
},
// create module action
createModule: function (module) {
var Area, data;
// check if capability is right for this action
if (Checks.userCan('create_kontentblocks')) {
} else {
Notice.notice('You\'re not allowed to do this', 'error');
}
// check if block limit isn't reached
Area = KB.Areas.get(this.options.area.model.get('id'));
if (!Checks.blockLimit(Area)) {
Notice.notice('Limit for this area reached', 'error');
return false;
}
// prepare data to send
data = {
action: 'createNewModule',
'class': module.get('settings').class,
globalModule: module.get('globalModule'),
parentObject: module.get('parentObject'),
parentObjectId: module.get('parentObjectId'),
areaContext: this.options.area.model.get('context'),
area: this.options.area.model.get('id'),
_ajax_nonce: Config.getNonce('create'),
frontend: KB.appData.config.frontend,
submodule: false
};
if (this.options.area.model.get('parent_id')) {
data.postId = this.options.area.model.get('parent_id');
}
this.close();
Ajax.send(data, this.success, this);
},
// create module success callback
// TODO Re-initialize ui components
success: function (res) {
var model, data;
data = res.data;
this.options.area.$modulesList.append(data.html);
model = KB.ObjectProxy.add(KB.Modules.add(data.module));
this.options.area.attachModule(model);
this.parseAdditionalJSON(data.json);
model.View.trigger('toggle.open');
setTimeout(function () {
KB.Fields.trigger('newModule', model.View);
TinyMCE.addEditor(model.View.$el);
}, 150);
this.trigger('browser.module.created', {res: res})
// repaint
// add module to collection
},
parseAdditionalJSON: function (json) {
// create the object if it doesn't exist already
if (!KB.payload.Fields) {
KB.payload.Fields = {};
}
_.extend(KB.payload.Fields, json.Fields);
Payload.parseAdditionalJSON(json); // this will add new fields to the FieldConfigs collection
},
// helper method to convert list of assigned classnames to object with module definitions
prepareAssignedModules: function () {
var assignedModules = this.area.model.get('assignedModules');
var fullDefs = [];
// @TODO a module class which was assigned to an area is not necessarily present
_.each(Payload.getPayload('ModuleDefinitions'), function (module) {
if (_.indexOf(assignedModules, module.settings.class) !== -1) {
fullDefs.push(module);
}
});
KB.Events.trigger('module.browser.setup.defs', this, fullDefs);
return fullDefs;
}
});