Skip to content
Code-Schnipsel Gruppen Projekte
BrickEdit.js 26,7 KiB
Newer Older
Henning Leutz's avatar
Henning Leutz committed
/**
Henning Leutz's avatar
Henning Leutz committed
 * BrickEdit Panel
Henning Leutz's avatar
Henning Leutz committed
 * Edit and change a Brick
Henning Leutz's avatar
Henning Leutz committed
 *
Henning Leutz's avatar
Henning Leutz committed
 * @module package/quiqqer/bricks/bin/BrickEdit
Henning Leutz's avatar
Henning Leutz committed
 * @author www.pcsg.de (Henning Leutz)
 *
 * @event onLoaded [ this ]
 * @event onSave [ this ]
Henning Leutz's avatar
Henning Leutz committed
 * @event onDelete [ this ]
Henning Leutz's avatar
Henning Leutz committed
 */
Henning Leutz's avatar
Henning Leutz committed
define('package/quiqqer/bricks/bin/BrickEdit', [
Henning Leutz's avatar
Henning Leutz committed

    'qui/QUI',
    'qui/controls/desktop/Panel',
Henning Leutz's avatar
Henning Leutz committed
    'qui/controls/windows/Confirm',
Henning Leutz's avatar
Henning Leutz committed
    'package/quiqqer/bricks/bin/BrickAreas',
Henning Leutz's avatar
Henning Leutz committed
    'Ajax',
    'Locale',
    'qui/utils/Form',
Henning Leutz's avatar
Henning Leutz committed
    'utils/Controls',
    'utils/Template',
    'package/quiqqer/bricks/bin/Bricks',
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
    'css!package/quiqqer/bricks/bin/BrickEdit.css'
Henning Leutz's avatar
Henning Leutz committed

], function (QUI, QUIPanel, QUIConfirm, BrickAreas, QUIAjax, QUILocale,
             Projects, QUIFormUtils, ControlUtils, Template, Bricks) {
Henning Leutz's avatar
Henning Leutz committed
    "use strict";

Henning Leutz's avatar
Henning Leutz committed
    var lg = 'quiqqer/bricks';

Henning Leutz's avatar
Henning Leutz committed
    return new Class({

Henning Leutz's avatar
Henning Leutz committed
        Extends: QUIPanel,
        Type   : 'package/quiqqer/bricks/bin/BrickEdit',
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
        Binds: [
Henning Leutz's avatar
Henning Leutz committed
            '$onInject',
            '$onCreate',
            '$onDestroy',

            'showInformation',
            'showSettings',
            'showExtras',
            'showContent',

            '$load',
            '$unload',
Henning Leutz's avatar
Henning Leutz committed
            'save',
            'del',
            '$onCategoryEnter',
            '$onCategoryLeave'
Henning Leutz's avatar
Henning Leutz committed
        ],

Henning Leutz's avatar
Henning Leutz committed
        options: {
            id         : false,
            projectName: false,
            projectLang: false
Henning Leutz's avatar
Henning Leutz committed
        },

        initialize: function (options) {
Michael's avatar
Michael committed
            this.parent(options);
Henning Leutz's avatar
Henning Leutz committed

            this.$availableBricks   = [];
            this.$availableSettings = [];
            this.$customfields      = [];
            this.$loaded            = false;
Henning Leutz's avatar
Henning Leutz committed

            this.$Container = null;
            this.$Editor    = false;
            this.$Areas     = false;
Henning Leutz's avatar
Henning Leutz committed

            this.addEvents({
                onInject       : this.$onInject,
                onCreate       : this.$onCreate,
                onDestroy      : this.$onDestroy,
                onResize       : function () {
                    var controls = QUI.Controls.getControlsInElement(this.getContent());
                    controls.each(function (Control) {
                        if ("resize" in Control) {
                            Control.resize();
                        }
                    });
                }.bind(this),
                onCategoryEnter: this.$onCategoryEnter,
                onCategoryLeave: this.$onCategoryLeave
Henning Leutz's avatar
Henning Leutz committed
        },

        /**
         * event : on create
Henning Leutz's avatar
Henning Leutz committed
         */
        $onCreate: function () {
            this.setAttributes({
                icon : 'fa fa-spinner fa-spin',
                title: '...'
            });
                name     : 'save',
                textimage: 'fa fa-save',
                text     : QUILocale.get('quiqqer/system', 'save'),
                events   : {
                    click: this.save
                }
            });
                name  : 'delete',
                icon  : 'fa fa-trash-o',
                title : QUILocale.get('quiqqer/system', 'delete'),
                events: {
                    click: this.del
                },
                styles: {
                    'float': 'right'
                }
            });

            this.addCategory({
                name  : 'information',
                icon  : 'fa fa-file-o',
                text  : QUILocale.get('quiqqer/system', 'information'),
                events: {
                    onClick: this.showInformation
Henning Leutz's avatar
Henning Leutz committed

            this.addCategory({
                name  : 'settings',
                icon  : 'fa fa-magic',
                text  : QUILocale.get('quiqqer/system', 'properties'),
                events: {
                    onClick: this.showSettings

            this.addCategory({
                name  : 'extra',
                icon  : 'fa fa-gears',
                text  : QUILocale.get('quiqqer/system', 'settings'),
                events: {
                    onClick: this.showExtras
                name  : 'content',
                icon  : 'fa fa-file-text-o',
                text  : QUILocale.get('quiqqer/system', 'content'),
                events: {
                    onClick: this.showContent
Henning Leutz's avatar
Henning Leutz committed
        },

        /**
         * event : on inject
         */
        $onInject: function () {
            this.Loader.show();
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
            QUIAjax.get([
                'package_quiqqer_bricks_ajax_getBrick',
                'package_quiqqer_bricks_ajax_getAvailableBricks',
                'package_quiqqer_bricks_ajax_getPanelCategories'
            ], function (brick, bricks, categories) {
Henning Leutz's avatar
Henning Leutz committed
                /**
                 * @param {{availableSettings:object}} data
                 * @param {{attributes:object}} data
                 * @param {{settings:object}} data
                 */
Henning Leutz's avatar
Henning Leutz committed
                this.$availableBricks = bricks;
                this.$availableSettings = brick.availableSettings;
                this.$customfields      = brick.customfields;
Henning Leutz's avatar
Henning Leutz committed

                this.setAttribute('data', brick);
Henning Leutz's avatar
Henning Leutz committed

                this.setAttributes({
                    icon : 'fa fa-th',
                    title: QUILocale.get('quiqqer/bricks', 'panel.title', {
                        brickId   : this.getAttribute('id'),
                        brickTitle: brick.attributes.title
                    })
                });
Henning Leutz's avatar
Henning Leutz committed

                this.getContent().setStyles({
                    position: 'relative'
                });

                this.$Container = new Element('div', {
                    'class': 'quiqqer-bricks-container'
                }).inject(this.getContent());

                // brick xml settings
                var type = brick.attributes.type;
                var data = bricks.filter(function (entry) {
                    return entry.control === type;
                });

                if (data.length && data[0].hasContent === 0) {
                    this.getCategory('content').hide();
                }

                for (var i = 0, len = categories.length; i < len; i++) {
                    this.addCategory(categories[i]);
                }

                this.refresh();

                this.fireEvent('loaded', [this]);
                this.getCategory('information').click();
                this.$loaded = true;
            }.bind(this), {
                'package': 'quiqqer/brick',
                brickId  : this.getAttribute('id')
            });
Henning Leutz's avatar
Henning Leutz committed
        },

        /**
         * event : on destroy
         */
        $onDestroy: function () {
            if (this.$Editor) {
Henning Leutz's avatar
Henning Leutz committed
                this.$Editor.destroy();
            }

            if (this.$Areas) {
                this.$Areas.destroy();
            }
Henning Leutz's avatar
Henning Leutz committed
        },

        /**
         * Saves the brick
Henning Leutz's avatar
Henning Leutz committed
         *
         * @return Promise
         */
        save: function () {
            this.Loader.show();
            this.$unload();

            var self = this,
                data = self.getAttribute('data');
            data.customfields = self.$customfields;
            return Bricks.saveBrick(self.getAttribute('id'), data).then(function () {
                QUI.getMessageHandler().then(function (MH) {
                    MH.addSuccess(
                        QUILocale.get(lg, 'message.brick.save.success')
                    );

                self.fireEvent('save', [self]);

                if (self.getActiveCategory().getAttribute('name')) {

                }

                self.Loader.hide();
Henning Leutz's avatar
Henning Leutz committed
        /**
         * Delete the brick
         */
            var self = this,
                data = this.getAttribute('data');
Henning Leutz's avatar
Henning Leutz committed

            new QUIConfirm({
Henning Leutz's avatar
Henning Leutz committed
                title      : QUILocale.get(lg, 'window.brick.delete.title'),
                text       : QUILocale.get(lg, 'window.brick.delete.text', {
                    brickId   : self.getAttribute('id'),
                    brickTitle: data.attributes.title
                }),
Henning Leutz's avatar
Henning Leutz committed
                information: QUILocale.get(lg, 'window.brick.delete.information'),
                icon       : 'fa fa-trash',
                texticon   : 'fa fa-trash',
Henning Leutz's avatar
Henning Leutz committed
                maxHeight  : 300,
                maxWidth   : 600,
                autoclose  : false,
                events     : {
                    onSubmit: function (Win) {
Henning Leutz's avatar
Henning Leutz committed
                        Win.Loader.show();

                        Bricks.deleteBricks([self.getAttribute('id')]).then(function () {
Henning Leutz's avatar
Henning Leutz committed
                            Win.close();
                            self.fireEvent('delete');
Henning Leutz's avatar
Henning Leutz committed
                    }
                }
            }).open();
        },

        /**
         * event on button active
         *
         * @return Promise
Henning Leutz's avatar
Henning Leutz committed
         */
        $load: function () {
            QUIFormUtils.setDataToForm(
                this.getAttribute('data').attributes,
                this.$Container.getElement('form')
            );

            QUIFormUtils.setDataToForm(
                this.getAttribute('data').settings,
                this.$Container.getElement('form')
            );
        },

        /**
         * event unload category
         */
            if (!this.$loaded) {
                return;
            }

            if (!this.getActiveCategory()) {
                return;
            }

            var Form   = this.getContent().getElement('form'),
                unload = this.getActiveCategory().getAttribute('name'),
                data   = this.getAttribute('data');
            switch (unload) {
                case 'extra':
                case 'settings':
                case 'content':
                    break;

                default:
                    data.attributes = Object.merge(
                        data.attributes,
                        QUIFormUtils.getFormData(Form)
                    );
            if (Form && Form.getElement('[name="frontendTitle"]')) {
                data.attributes.frontendTitle = Form.getElement('[name="frontendTitle"]').value;
            }

            if (unload === 'settings' && this.$Areas) {
Henning Leutz's avatar
Henning Leutz committed
                data.attributes.areas = this.$Areas.getAreas().join(',');
Henning Leutz's avatar
Henning Leutz committed
                    fieldData    = QUIFormUtils.getFormData(Form);

                for (var key in fieldData) {

                    if (!fieldData.hasOwnProperty(key)) {
                        continue;
                    }

                    if (!key.match('flexible')) {
                        continue;
                    }

                    if (fieldData[key]) {
                        flexibleList.push(key);
                    }
                }

                this.$customfields = flexibleList;
Henning Leutz's avatar
Henning Leutz committed
            if (unload === 'extra') {
                data.settings = Object.merge(
                    data.settings,
                    QUIFormUtils.getFormData(Form)
                );
            if (unload === 'content' && this.$Editor) {
                data.attributes.content = this.$Editor.getContent();
            }

            this.setAttribute('data', data);
        },

        /**
         * Information template
         *
         * @returns {Promise}
         */
        showInformation: function () {
            var self = this;
            return this.$hideCategory().then(function () {
                return Template.get('ajax/brick/templates/information', false, {
                    'package': 'quiqqer/bricks'
            }).then(function (html) {
                self.$Container.set('html', html);
                self.$load();
            }).then(function () {
                return self.$showCategory();
            }).then(function () {
                self.Loader.hide();
            });
        },

        /**
         * Settings template
         *
         * @returns {Promise}
         */
        showSettings: function () {
            var self = this;

            return this.$hideCategory().then(function () {
                return new Promise(function (resolve, reject) {
                    Template.get('ajax/brick/templates/settings', function (result) {
                        self.$Container.set('html', result);

                        // areas
                        var Content      = self.getContent(),
                            areas        = [],
                            attributes   = self.getAttribute('data').attributes,
                            customfields = self.$customfields;

                        if (attributes.areas) {
                            areas = attributes.areas
                                              .replace(/^,*/, '')
                                              .replace(/,*$/, '')
                                              .split(',');
                        // areas
                        self.$Areas = new BrickAreas({
                            brickId    : self.getAttribute('id'),
                            projectName: self.getAttribute('projectName'),
                            projectLang: self.getAttribute('projectLang'),
                            areas      : areas,
                            styles     : {
                                height: 120
                            }
                        }).inject(Content.getElement('.quiqqer-bricks-areas'));
                        // flexble settings
                        var i, len, data;
                        var TBody = Content.getElement('.brick-table-flexible tbody');
                        for (i = 0, len = self.$availableSettings.length; i < len; i++) {
                            data = self.$availableSettings[i];
                            new Element('tr', {
                                'class': i % 2 ? 'odd' : 'even',
                                html   : '<td>' +
                                '<label>' +
                                '<input type="checkbox" name="flexible-' + data.name + '" />' +
                                '<span>' + QUILocale.get(data.text[0], data.text[1]) + '</span>' +
                                '</label>' +
                                '</td>'
                            }).inject(TBody);
                        }
                        if (customfields) {
                            var name;
                            var Form = Content.getElement('form');
                            for (i = 0, len = customfields.length; i < len; i++) {
                                name = customfields[i];
                                if (typeof Form.elements[name] !== 'undefined') {
                                    Form.elements[name].checked = true;
                                }
                                if (typeof Form.elements['flexible-' + name] !== 'undefined') {
                                    Form.elements['flexible-' + name].checked = true;
                                }
Henning Leutz's avatar
Henning Leutz committed

                        resolve();
                    }, {
                        'package': 'quiqqer/bricks',
                        onError  : reject
                    });
            }).then(function () {
                return self.$showCategory();
            }).then(function () {
                self.Loader.hide();
            }).catch(function (err) {
                console.error(err);
                self.Loader.hide();
            });
        },

        /**
         * Setting extras
         *
         * @returns {Promise}
         */
        showExtras: function () {
            var self = this;
            return this.$hideCategory().then(function () {
                return Template.get('ajax/brick/templates/extras', false, {
                    'package': 'quiqqer/bricks'
            }).then(function (html) {
                self.$Container.set('html', html);
                self.$load();

                return self.$createExtraData();
            }).then(function () {
                return self.$showCategory();
            }).then(function () {
                self.Loader.hide();
            });
         * Setting content
Henning Leutz's avatar
Henning Leutz committed
         *
         * @returns {Promise}
Henning Leutz's avatar
Henning Leutz committed
         */
        showContent: function () {
            var self = this;
Henning Leutz's avatar
Henning Leutz committed

            return this.$hideCategory().then(function () {
                return Template.get('ajax/brick/templates/content', false, {
                    'package': 'quiqqer/bricks'
            }).then(function (html) {
                self.$Container.set('html', html);
                return self.$createContentEditor();
            }).then(function () {
                return self.$showCategory();
            }).then(function () {
                self.Loader.hide();
            }).catch(function (err) {
                console.error(err);
                self.Loader.hide();
            });
        },

        /**
         * Create the editor, if the brick type is a content type
         *
         * @return Promise
         */
        $createContentEditor: function () {
            var self = this;
            return new Promise(function (resolve) {
                var TableBody = self.$Container.getElement('table.brick-edit-content tbody'),
Henning Leutz's avatar
Henning Leutz committed
                    TD        = new Element('td'),
                    TR        = new Element('tr', {
                        'class': 'odd'
Henning Leutz's avatar
Henning Leutz committed

                TD.inject(TR);
                TR.inject(TableBody);
Henning Leutz's avatar
Henning Leutz committed

                var contentSize = self.getContent().getSize();
Henning Leutz's avatar
Henning Leutz committed

                require(['classes/editor/Manager'], function (EditorManager) {
                    new EditorManager().getEditor(null, function (Editor) {
                        self.$Editor = Editor;
                        self.$Editor.setAttribute('showLoader', false);
                            self.getAttribute('projectName'),
                            self.getAttribute('projectLang')
                        self.$Editor.setProject(Project);
                        if ((contentSize.y - 100) > height) {
                            height = contentSize.y - 100;

                        var EditorContainer = new Element('div', {
Henning Leutz's avatar
Henning Leutz committed
                            styles: {
                                clear  : 'both',
                                'float': 'left',
                                height : height,
                                width  : '100%'
Michael's avatar
Michael committed
                        }).inject(TD);
                        self.$Editor.addEvent('onLoaded', resolve);
                        self.$Editor.inject(EditorContainer);
                        self.$Editor.setHeight(EditorContainer.getSize().y);
                        self.$Editor.setWidth(EditorContainer.getSize().x);
                        self.$Editor.setContent(
                            self.getAttribute('data').attributes.content
Henning Leutz's avatar
Henning Leutz committed
        },

        /**
         * Create the extra settings table
Henning Leutz's avatar
Henning Leutz committed
         */
        $createExtraData: function () {
            return new Promise(function (resolve, reject) {
                var TableExtra = this.$Elm.getElement('table.brick-edit-extra-header'),
                    TableBody  = TableExtra.getElement('tbody');
Henning Leutz's avatar
Henning Leutz committed

                TableBody.getElement('[name="frontendTitle"]').value =
                    this.getAttribute('data').attributes.frontendTitle;
Michael's avatar
Michael committed
                if (!this.$availableSettings || !this.$availableSettings.length) {
                    TableExtra.setStyle('display', 'none');
Henning Leutz's avatar
Henning Leutz committed
                        html: QUILocale.get(lg, 'window.brick.no.extra.settings')
                    }).inject(TableExtra, 'before');

Henning Leutz's avatar
Henning Leutz committed

                TableExtra.setStyle('display', null);
Henning Leutz's avatar
Henning Leutz committed

                var i, len, Row, text, Value, setting, extraFieldId;
Henning Leutz's avatar
Henning Leutz committed

                    id   = this.getId(),
                    Form = this.getContent().getElement('form');
Henning Leutz's avatar
Henning Leutz committed

Michael's avatar
Michael committed
                for (i = 0, len = this.$availableSettings.length; i < len; i++) {
                    setting      = this.$availableSettings[i];
Michael's avatar
Michael committed
                    extraFieldId = 'extraField_' + id + '_' + i;
Henning Leutz's avatar
Henning Leutz committed

                    if (typeOf(setting.text) === 'array') {
Henning Leutz's avatar
Henning Leutz committed
                        text = QUILocale.get(setting.text[0], setting.text[1]);
                    Row = new Element('tr', {
                        'class': i % 2 ? 'odd' : 'even',
Henning Leutz's avatar
Henning Leutz committed
                        html   : '<td>' +
                        '    <label class="quiqqer-bricks-areas" for="' + extraFieldId + '">' +
                        text +
                        '    </label>' +
                        '</td>' +
                        '<td></td>'
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
                    if (setting.type !== 'select') {
                        Value = new Element('input', {
Henning Leutz's avatar
Henning Leutz committed
                            type   : setting.type,
                            name   : setting.name,
                            'class': setting.class,
                            id     : extraFieldId
                        }).inject(Row.getElement('td:last-child'));

                        if (setting['data-qui'] !== '') {
                            Value.set('data-qui', setting['data-qui']);
                        }
Henning Leutz's avatar
Henning Leutz committed

                        continue;
                    }

                    Value = new Element('select', {
Henning Leutz's avatar
Henning Leutz committed
                        name   : setting.name,
                        'class': setting.class,
                        id     : extraFieldId
                    }).inject(Row.getElement('td:last-child'));
Michael's avatar
Michael committed
                    for (var c = 0, clen = setting.options.length; c < clen; c++) {
                        text = setting.options[c].text;

                        if (typeOf(setting.options[c].text) === 'array') {
                            text = QUILocale.get(
Henning Leutz's avatar
Henning Leutz committed
                                setting.options[c].text[0],
                                setting.options[c].text[1]
Henning Leutz's avatar
Henning Leutz committed
                            html : text,
                            value: setting.options[c].value
Henning Leutz's avatar
Henning Leutz committed
                    }
                TableExtra.setStyle('display', null);
                QUIFormUtils.setDataToForm(
                    this.getAttribute('data').settings,
                    Form
                );
                QUI.parse(TableExtra).then(function () {
                    return ControlUtils.parse(TableExtra);
                    // set project to the controls
                    TableExtra.getElements('[data-quiid]').each(function (Elm) {
                        var Control = QUI.Controls.getById(
                            Elm.get('data-quiid')
                        );

Michael's avatar
Michael committed
                        if ('setProject' in Control) {
                                self.getAttribute('projectName'),
                                self.getAttribute('projectLang')
        },

        /**
         * event: on category enter
         *
         * @return Promise
         */
        $onCategoryEnter: function (Panel, Category) {
            if (this.$loaded === false) {
                return Promise.resolve();
            }

            switch (Category.getAttribute('name')) {
                case 'information':
                case 'extra':
                case 'settings':
                case 'content':
                    return Promise.resolve();
            }

            var self = this;

            this.Loader.show();

            return this.$hideCategory().then(function () {
                return new Promise(function (resolve, reject) {
                    QUIAjax.get('package_quiqqer_bricks_ajax_getPanelCategory', function (result) {
                        self.$Container.set('html', '<form>' + result + '</form>');
                        self.$load();
                        resolve();
                    }, {
                        'package': 'quiqqer/bricks',
                        brickId  : self.getAttribute('id'),
                        category : Category.getAttribute('name'),
                        onError  : reject
                    });
                });
            }).then(function () {
                return QUI.parse();
            }).then(function () {
                return self.$showCategory();
            }).then(function () {
                self.Loader.hide();

            }).catch(function (err) {
                console.error(err);
                self.Loader.hide();
            });
        },

        /**
         * event: on category leave
         */
        $onCategoryLeave: function () {
            this.$unload();

            if (this.$Areas) {
                this.$Areas.destroy();
                this.$Areas = false;
            }

            if (this.$Editor) {
                this.$Editor.destroy();
                this.$Editor = false;
            }
        },

        /**
         * show the container
         *
         * @return Promise
         */
        $showCategory: function () {
            var self = this;

            return new Promise(function (resolve) {
                moofx(self.$Container).animate({
                    opacity: 1,
                    top    : 0
                }, {
                    duration: 250,
                    callback: resolve
                });
            });
        },

        /**
         * hide the container
         *
         * @return Promise
         */
        $hideCategory: function () {
            var self = this;

            // unload
            this.$unload();

            return new Promise(function (resolve) {
                moofx(self.$Container).animate({
                    opacity: 0,
                    top    : -20
                }, {
                    duration: 250,
                    callback: function () {
                        self.$Container.set('html', '');
                        resolve();
                    }
                });
            });
Henning Leutz's avatar
Henning Leutz committed
        }
    });
});