aimeos / ai-cms-grapesjs

GrapesJS CMS integration into Aimeos
GNU Lesser General Public License v2.1
22 stars 18 forks source link

Block creation issue in grapesjs #30

Open rabiadg opened 10 months ago

rabiadg commented 10 months ago

Created a new block in grapesjs but its componenet code is not working at all how to fix it Plz check my attached code

/*

Aimeos.CMSContent = {

GrapesJS: {

    blocks: {

        'categorylist': {
            category: 'Extra',
            label: 'Categories',
            attributes: {class: 'fa fa-cubes'},
            content: `<categorylist limit="3" type="default">
                    <div class="category" data-gjs-name="Category"></div>
                    <div class="category" data-gjs-name="Category"></div>
                    <div class="category" data-gjs-name="Category"></div>
                </categorylist>`
        },
    },

    components: {
        'categorylist': function (editor) {
            editor.DomComponents.addType('categorylist', {
                isComponent: el => el.tagName === 'categorylist' ? {type: 'categorylist'} : false,
                model: {
                    defaults: {
                        tagName: 'categorylist',
                        draggable: true,
                        droppable: true,
                        attributes: {
                            class: 'categorylist',
                        },
                        styles: `
                            .categorylist {
                                display: block; max-height: 350px; overflow: hidden; white-space: nowrap;
                            }

                        `,
                        components: model => {
                            const limit = model.props().limit || 3;
                            let result = '';

                            for (let i = 0; i < limit; i++) {
                                result += '<div class="category" data-gjs-name="Category"></div>';
                            }
                            return result;
                        },
                        traits: [{
                            type: 'select',
                            label: 'Category',
                            name: 'catid'
                        }, {
                            type: 'number',
                            label: 'Limit',
                            name: 'limit',
                            min: 1,
                            max: 100,
                            step: 1
                        }]
                    },
                    init() {
                        this.on('change:attributes:limit', this.onLimitChange);
                        this.fetch();
                    },
                    fetch() {
                        Aimeos.options.done(options => {
                            if (options.meta && options.meta.resources && options.meta.resources['catalog']) {
                                const args = {
                                    fields: {catalog: 'catalog.id,catalog.label,catalog.level'},
                                    page: {limit: 100}
                                };

                                const config = {
                                    'paramsSerializer': function (params) {
                                        return jQuery.param(params); // workaround, Axios and QS fail on [==]
                                    },
                                    'params': {}
                                };

                                if (options.meta.prefix && options.meta.prefix) {
                                    config['params'][options.meta.prefix] = args;
                                } else {
                                    config['params'] = args;
                                }

                                axios.get(options.meta.resources['catalog'], config).then(response => {
                                    const items = [{id: '', name: ''}];

                                    (response.data.data || []).forEach(entry => {
                                        if (entry['id'] && entry['attributes']) {
                                            items.push({
                                                id: entry['id'],
                                                name: '-'.repeat(entry['attributes']['catalog.level'] || 0) + ' ' + (entry['attributes']['catalog.label'] || '')
                                            });
                                        }
                                    });

                                    const catid = this.get('traits').where({name: 'catid'})[0];
                                    catid.set('options', items);
                                });
                            }
                        });
                    },
                    onLimitChange() {
                        let items = '';
                        const view = this.getView();
                        const limit = this.getAttributes().limit;

                        for (let i = 0; i < limit; i++) {
                            items += '<div class="category" data-gjs-name="Category">';
                        }

                        this.empty().append(items);
                        view && view.render();
                    },
                    updated(property, value) {
                        if (property === 'components' && this.getAttributes().limit !== value.length) {
                            this.getTrait('limit').set('value', value.length);
                        }
                    }
                }
            });
        },

    },

    initialize: function (editor, setup, media) {

        editor.Components.addType('image', {
            view: {
                onActive(ev) {
                    ev && ev.stopPropagation();
                    const {model} = this;
                    editor.runCommand('core:open-assets', {
                        target: model,
                        types: ['image'],
                        onClick(asset) {
                            const srcset = asset.get('srcset');
                            srcset && model.addAttributes({srcset})
                        },
                        onSelect(asset) {
                            const srcset = asset.get('srcset');
                            srcset && model.addAttributes({srcset})
                        }
                    });
                },
                onError() {
                    const fallback = this.model.getSrcResult({fallback: 1});
                    if (fallback) this.el.src = fallback;
                    if (fallback) this.el.removeAttribute('srcset');
                }
            }
        });

        editor.Canvas.getFrames().forEach(frame => {
            const body = frame.view.getBody();
            body.setAttribute('dir', editor.getConfig('langDir'));
            body.classList.add('aimeos', 'cms-page', 'gjs-dashed');
        });
        editor.I18n.setLocale(document.querySelector('.aimeos').attributes.lang.nodeValue);
        editor.AssetManager.add(media);

        for (const cmp in setup.components) {
            console.log(cmp);
            setup.components[cmp](editor);
        }

        // only add own panels
        editor.Panels.getPanels().reset(setup.panels);

        // add custom blocks
        for (const block in setup.blocks) {
            editor.BlockManager.add(block, setup.blocks[block]);
        }

        // load plugins after blocks to enforce order
        const opts = setup.config.pluginsOpts;
        grapesjs.plugins.add('grapesjs-table', window['grapesjs-table'].default(editor, opts['grapesjs-table']));

        // add custom styles
        editor.DomComponents.getWrapper().set('attributes', {'class': 'container-fluid'});

        // Show Blocks Manager by default
        const blocks = editor.Panels.getButton('views', 'open-blocks');
        editor.on('load', () => blocks && blocks.set('active', 1));

        // On component delete show the Blocks Manager
        editor.on('component:deselected', () => {
            const btn = editor.Panels.getButton('views', 'open-blocks');
            btn && btn.set('active', 1);
        });

        // On component change show the Traits Manager
        editor.on('component:selected', () => {
            if (editor.getSelected()) {
                const btn = editor.Panels.getButton('views', 'open-tm');
                btn && btn.set('active', 1);
            }
        });
    }
},

init: function () {
    Aimeos.components['cms-content'] = new Vue({
        el: document.querySelector('#item-content-group'),
        data: {
            items: [],
            media: [],
            siteid: null,
            domain: null,
            version: 0
        },
        beforeMount() {
            this.Aimeos = Aimeos;
        },
        mounted: function () {
            this.items = JSON.parse(this.$el.dataset.items || '{}');
            this.media = JSON.parse(this.$el.dataset.media || '{}');
            this.siteid = this.$el.dataset.siteid;
            this.domain = this.$el.dataset.domain;

            if (this.items[0]) {
                this.$set(this.items[0], '_show', true);
            }
        },
        mixins: [this.mixins]
    });

    document.querySelectorAll('.btn').forEach(function (el) {
        el.addEventListener('mousedown', function () {
            Aimeos.components['cms-content'].change();
        })
    });
},

mixins: {
    methods: {
        active: function (idx) {
            return this.items[idx] && this.items[idx]['text.status'] > 0;
        },

        add: function (data) {
            let entry = {};

            entry[this.domain + '.lists.id'] = null;
            entry[this.domain + '.lists.type'] = 'default';
            entry[this.domain + '.lists.siteid'] = this.siteid;
            entry[this.domain + '.lists.datestart'] = null;
            entry[this.domain + '.lists.dateend'] = null;

            entry['text.id'] = null;
            entry['text.type'] = 'content';
            entry['text.languageid'] = '';
            entry['text.siteid'] = this.siteid;
            entry['text.content'] = '';
            entry['text.label'] = '';
            entry['text.status'] = 1;

            entry['property'] = [];
            entry['config'] = [];
            entry['_show'] = true;
            entry['_nosort'] = true;

            this.items.push(Object.assign(entry, data));
        },

        change: function () {
            this.version++;
        },

        duplicate: function (idx) {
            if (idx < this.items.length) {
                let entry = JSON.parse(JSON.stringify(this.items[idx]));
                entry['text.id'] = null;
                this.$set(this.items, this.items.length, entry);
            }
        },

        label: function (idx) {
            return (this.items[idx]['text.languageid'] ? this.items[idx]['text.languageid'].toUpperCase() : '***');
        },

        remove: function (idx) {
            this.items.splice(idx, 1);
        },

        toggle: function (what, idx) {
            this.$set(this.items[idx], what, (!this.items[idx][what] ? true : false));
        },
    }
}

};

aimeos commented 10 months ago

Seems like a copy&paste of the existing code. What's you own code?

rabiadg commented 10 months ago

i am just cloned cataloglist for creating same entry for only categories but it doesn't work

aimeos commented 10 months ago

In Javascript, that doesn't work because it will only overwrite the already existing code for the "cataloglist" block. Instead, you have to reset the blocks object first: Aimeos.CMSContent.GrapesJS.blocks = {}