<commit_before>$(function () {
    //TODO: cleanup this

    var COMPONENTS_PAGE_SIZE = 3;

    var dashboardsApi = ues.utils.tenantPrefix() + 'apis/dashboards';

    var dashboardsUrl = ues.utils.tenantPrefix() + 'dashboards';

    var resolveURI = ues.dashboards.resolveURI;

    var findPage = ues.dashboards.findPage;

    var dashboard;

    var page;

    var activeComponent;

    var freshDashboard = true;

    var storeCache = {
        gadget: [],
        widget: [],
        layout: []
    };

    /**
     * Handlebars helpers
     */
    Handlebars.registerHelper('has', function () {
        var has = function (o) {
            if (!o) {
                return false;
            }
            if (o instanceof Array && !o.length) {
                return false;
            }
            var key;
            for (key in o) {
                if (o.hasOwnProperty(key)) {
                    return true;
                }
            }
            return false;
        };
        var args = Array.prototype.slice.call(arguments);
        var options = args.pop();
        var length = args.length;
        if (!length) {
            return new Handlebars.SafeString(options.inverse(this));
        }
        var i;
        for (i = 0; i < length; i++) {
            if (has(args[i])) {
                return new Handlebars.SafeString(options.fn(this));
            }
        }
        return new Handlebars.SafeString(options.inverse(this));
    });

    Handlebars.registerHelper('equals', function (left, right, options) {
        if (left === right) {
            return options.fn(this);
        }
        return options.inverse(this);
    });

    Handlebars.registerHelper('dump', function (o) {
        return JSON.stringify(o);
    });

    Handlebars.registerHelper('resolveURI', function (path) {
        return ues.dashboards.resolveURI(path);
    });

    /**
     * Precompiling Handlebar templates
     */
    var layoutsListHbs = Handlebars.compile($("#ues-layouts-list-hbs").html() || '');

    var layoutHbs = Handlebars.compile($("#ues-layout-hbs").html());

    var componentsListHbs = Handlebars.compile($("#ues-components-list-hbs").html());

    var noComponentsHbs = Handlebars.compile($("#ues-no-components-hbs").html());

    var componentToolbarHbs = Handlebars.compile($("#ues-component-toolbar-hbs").html());

    var pageOptionsHbs = Handlebars.compile($("#ues-page-properties-hbs").html());

    var componentPropertiesHbs = Handlebars.compile($("#ues-component-properties-hbs").html() || '');

    var pagesListHbs = Handlebars.compile($("#ues-pages-list-hbs").html());

    /**
     * generates a random id
     * @returns {string}
     */
    var randomId = function () {
        return Math.random().toString(36).slice(2);
    };

    /**
     * switches workspaces in the designer
     * @param name
     */
    var showWorkspace = function (name) {
        $('.ues-workspace').hide();
        $('#ues-workspace-' + name).show();
    };

    /**
     * show the store of a given type
     * @param type
     */
    var showStore = function (type) {
        var store = $('#ues-store').removeClass('ues-hidden');
        store.find('.ues-store-assets').addClass('ues-hidden');
        store.find('#ues-store-' + type).removeClass('ues-hidden');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible') || designer.hasClass('ues-store-visible')) {
            return;
        }
        if (designer.hasClass('ues-properties-visible')) {
            designer.removeClass('ues-properties-visible').addClass('ues-storeprop-visible');
            return;
        }
        designer.addClass('ues-store-visible');
    };

    /**
     * hide the store
     */
    var hideStore = function () {
        $('#ues-store').addClass('ues-hidden');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible')) {
            designer.removeClass('ues-storeprop-visible').addClass('ues-properties-visible');
            return;
        }
        designer.removeClass('ues-store-visible');

    };

    /**
     * check whether store is visible
     * @returns {boolean}
     */
    var storeVisible = function () {
        return !$('#ues-store').hasClass('ues-hidden');
    };

    /**
     * shows properties panel
     */
    var showProperties = function () {
        $('#ues-properties').removeClass('ues-hidden');
        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible') || designer.hasClass('ues-properties-visible')) {
            return;
        }
        if (designer.hasClass('ues-store-visible')) {
            designer.removeClass('ues-store-visible').addClass('ues-storeprop-visible');
            return;
        }
        designer.addClass('ues-properties-visible');
    };

    /**
     * hides properties panel
     */
    var hideProperties = function () {
        $('#ues-properties').addClass('ues-hidden');

        var menu = $('.ues-context-menu');
        menu.find('.ues-component-properties-toggle').parent().removeClass('active');
        menu.find('.ues-page-properties-toggle').parent().removeClass('active');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible')) {
            designer.removeClass('ues-storeprop-visible').addClass('ues-store-visible');
            return;
        }
        designer.removeClass('ues-properties-visible');
    };

    /**
     * removes properties panel
     */
    var removeProperties = function () {
        $('#ues-properties').empty();
    };

    /**
     * checks whether properties panel is visible
     * @returns {boolean}
     */
    var propertiesVisible = function () {
        return !$('#ues-properties').hasClass('ues-hidden');
    };

    /**
     * update component properties panel and save
     * @param sandbox
     */
    var updateComponentProperties = function (sandbox) {
        var notifiers = {};
        var options = {};
        var settings = {};
        var styles = {};
        var id = sandbox.data('component');

        saveOptions(sandbox, options);
        saveSettings(sandbox, settings);
        saveStyles(sandbox, styles);
        saveNotifiers(sandbox, notifiers);

        saveComponentProperties(id, {
            options: options,
            settings: settings,
            styles: styles,
            notifiers: notifiers
        });
    };

    /**
     * renders the component properties panel
     * @param component
     */
    var renderComponentProperties = function (component) {
        activeComponent = component;
        var ctx = buildPropertiesContext(component, page);
        var el = $('#ues-properties').find('.ues-content').html(componentPropertiesHbs(ctx))
            .find('.ues-sandbox').on('change', 'input, select, textarea', function () {
                updateComponentProperties($(this).closest('.ues-sandbox'));
            });
        $('[data-toggle="tooltip"]', el).tooltip();
        var toggle = $('#ues-workspace-designer').find('.ues-context-menu')
            .find('.ues-context-menu-actions')
            .find('.ues-component-properties-toggle');
        var parent = toggle.parent();
        parent.siblings().removeClass('active');
        parent.addClass('active').show();
        showProperties();
    };

    /**
     * find an asset of the given type from the store cache
     * @param type
     * @param id
     * @returns {*}
     */
    var findStoreCache = function (type, id) {
        var i;
        var item;
        var items = storeCache[type];
        var length = items.length;
        for (i = 0; i < length; i++) {
            item = items[i];
            if (item.id === id) {
                return item;
            }
        }
    };

    /**
     * find a given component in the current page
     * @param id
     * @returns {*}
     */
    var findComponent = function (id) {
        var i;
        var length;
        var area;
        var component;
        var components;
        var content = page.content;
        for (area in content) {
            if (content.hasOwnProperty(area)) {
                components = content[area];
                length = components.length;
                for (i = 0; i < length; i++) {
                    component = components[i];
                    if (component.id === id) {
                        return component;
                    }
                }
            }
        }
    };

    /**
     * save component properties
     * @param id
     * @param data
     */
    var saveComponentProperties = function (id, data) {
        var o;
        var opt;
        var block = findComponent(id);
        var content = block.content;

        //save options
        var options = content.options;
        var opts = data.options;
        for (opt in opts) {
            if (opts.hasOwnProperty(opt)) {
                o = options[opt] || (options[opt] = {});
                o.value = opts[opt];
            }
        }

        //save settings
        content.settings = data.settings;

        //save styles
        content.styles = data.styles;

        //save wiring
        var event;
        var listener;
        var notifiers = data.notifiers;
        var listen = content.listen;
        for (event in notifiers) {
            if (notifiers.hasOwnProperty(event)) {
                listener = listen[event];
                listener.on = notifiers[event];
            }
        }

        ues.dashboards.rewire(page);
        updateComponent(id);
        saveDashboard();
    };

    /**
     * removes and destroys the given component from the page
     * @param component
     * @param done
     */
    var removeComponent = function (component, done) {
        destroyComponent(component, function (err) {
            if (err) {
                return done(err);
            }
            var container = $('#' + component.id);
            var area = container.closest('.ues-component-box').attr('id');
            var content = page.content;
            area = content[area];
            var index = area.indexOf(component);
            area.splice(index, 1);
            container.remove();

            var properties = $('#ues-properties');
            var compId = properties.find('.ues-sandbox').data('component');
            if (compId !== component.id) {
                return done();
            }
            properties.empty();
            hideProperties();
            done();
        });
    };

    /**
     * destroys the given component
     * @param component
     * @param done
     */
    var destroyComponent = function (component, done) {
        ues.components.destroy(component, function (err) {
            if (err) {
                return err;
            }
            done(err);
        });
    };

    /**
     * destroys a given list of components of an area
     * @param components
     * @param done<commit_msg>fixing property panel deletion issue when a component is removed<commit_after>$(function () {
    //TODO: cleanup this

    var COMPONENTS_PAGE_SIZE = 3;

    var dashboardsApi = ues.utils.tenantPrefix() + 'apis/dashboards';

    var dashboardsUrl = ues.utils.tenantPrefix() + 'dashboards';

    var resolveURI = ues.dashboards.resolveURI;

    var findPage = ues.dashboards.findPage;

    var dashboard;

    var page;

    var activeComponent;

    var freshDashboard = true;

    var storeCache = {
        gadget: [],
        widget: [],
        layout: []
    };

    /**
     * Handlebars helpers
     */
    Handlebars.registerHelper('has', function () {
        var has = function (o) {
            if (!o) {
                return false;
            }
            if (o instanceof Array && !o.length) {
                return false;
            }
            var key;
            for (key in o) {
                if (o.hasOwnProperty(key)) {
                    return true;
                }
            }
            return false;
        };
        var args = Array.prototype.slice.call(arguments);
        var options = args.pop();
        var length = args.length;
        if (!length) {
            return new Handlebars.SafeString(options.inverse(this));
        }
        var i;
        for (i = 0; i < length; i++) {
            if (has(args[i])) {
                return new Handlebars.SafeString(options.fn(this));
            }
        }
        return new Handlebars.SafeString(options.inverse(this));
    });

    Handlebars.registerHelper('equals', function (left, right, options) {
        if (left === right) {
            return options.fn(this);
        }
        return options.inverse(this);
    });

    Handlebars.registerHelper('dump', function (o) {
        return JSON.stringify(o);
    });

    Handlebars.registerHelper('resolveURI', function (path) {
        return ues.dashboards.resolveURI(path);
    });

    /**
     * Precompiling Handlebar templates
     */
    var layoutsListHbs = Handlebars.compile($("#ues-layouts-list-hbs").html() || '');

    var layoutHbs = Handlebars.compile($("#ues-layout-hbs").html());

    var componentsListHbs = Handlebars.compile($("#ues-components-list-hbs").html());

    var noComponentsHbs = Handlebars.compile($("#ues-no-components-hbs").html());

    var componentToolbarHbs = Handlebars.compile($("#ues-component-toolbar-hbs").html());

    var pageOptionsHbs = Handlebars.compile($("#ues-page-properties-hbs").html());

    var componentPropertiesHbs = Handlebars.compile($("#ues-component-properties-hbs").html() || '');

    var pagesListHbs = Handlebars.compile($("#ues-pages-list-hbs").html());

    /**
     * generates a random id
     * @returns {string}
     */
    var randomId = function () {
        return Math.random().toString(36).slice(2);
    };

    /**
     * switches workspaces in the designer
     * @param name
     */
    var showWorkspace = function (name) {
        $('.ues-workspace').hide();
        $('#ues-workspace-' + name).show();
    };

    /**
     * show the store of a given type
     * @param type
     */
    var showStore = function (type) {
        var store = $('#ues-store').removeClass('ues-hidden');
        store.find('.ues-store-assets').addClass('ues-hidden');
        store.find('#ues-store-' + type).removeClass('ues-hidden');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible') || designer.hasClass('ues-store-visible')) {
            return;
        }
        if (designer.hasClass('ues-properties-visible')) {
            designer.removeClass('ues-properties-visible').addClass('ues-storeprop-visible');
            return;
        }
        designer.addClass('ues-store-visible');
    };

    /**
     * hide the store
     */
    var hideStore = function () {
        $('#ues-store').addClass('ues-hidden');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible')) {
            designer.removeClass('ues-storeprop-visible').addClass('ues-properties-visible');
            return;
        }
        designer.removeClass('ues-store-visible');

    };

    /**
     * check whether store is visible
     * @returns {boolean}
     */
    var storeVisible = function () {
        return !$('#ues-store').hasClass('ues-hidden');
    };

    /**
     * shows properties panel
     */
    var showProperties = function () {
        $('#ues-properties').removeClass('ues-hidden');
        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible') || designer.hasClass('ues-properties-visible')) {
            return;
        }
        if (designer.hasClass('ues-store-visible')) {
            designer.removeClass('ues-store-visible').addClass('ues-storeprop-visible');
            return;
        }
        designer.addClass('ues-properties-visible');
    };

    /**
     * hides properties panel
     */
    var hideProperties = function () {
        $('#ues-properties').addClass('ues-hidden');

        var menu = $('.ues-context-menu');
        menu.find('.ues-component-properties-toggle').parent().removeClass('active');
        menu.find('.ues-page-properties-toggle').parent().removeClass('active');

        var designer = $('#ues-designer');
        if (designer.hasClass('ues-storeprop-visible')) {
            designer.removeClass('ues-storeprop-visible').addClass('ues-store-visible');
            return;
        }
        designer.removeClass('ues-properties-visible');
    };

    /**
     * removes properties panel
     */
    var removeProperties = function () {
        $('#ues-properties').empty();
    };

    /**
     * checks whether properties panel is visible
     * @returns {boolean}
     */
    var propertiesVisible = function () {
        return !$('#ues-properties').hasClass('ues-hidden');
    };

    /**
     * update component properties panel and save
     * @param sandbox
     */
    var updateComponentProperties = function (sandbox) {
        var notifiers = {};
        var options = {};
        var settings = {};
        var styles = {};
        var id = sandbox.data('component');

        saveOptions(sandbox, options);
        saveSettings(sandbox, settings);
        saveStyles(sandbox, styles);
        saveNotifiers(sandbox, notifiers);

        saveComponentProperties(id, {
            options: options,
            settings: settings,
            styles: styles,
            notifiers: notifiers
        });
    };

    /**
     * renders the component properties panel
     * @param component
     */
    var renderComponentProperties = function (component) {
        activeComponent = component;
        var ctx = buildPropertiesContext(component, page);
        var el = $('#ues-properties').find('.ues-content').html(componentPropertiesHbs(ctx))
            .find('.ues-sandbox').on('change', 'input, select, textarea', function () {
                updateComponentProperties($(this).closest('.ues-sandbox'));
            });
        $('[data-toggle="tooltip"]', el).tooltip();
        var toggle = $('#ues-workspace-designer').find('.ues-context-menu')
            .find('.ues-context-menu-actions')
            .find('.ues-component-properties-toggle');
        var parent = toggle.parent();
        parent.siblings().removeClass('active');
        parent.addClass('active').show();
        showProperties();
    };

    /**
     * find an asset of the given type from the store cache
     * @param type
     * @param id
     * @returns {*}
     */
    var findStoreCache = function (type, id) {
        var i;
        var item;
        var items = storeCache[type];
        var length = items.length;
        for (i = 0; i < length; i++) {
            item = items[i];
            if (item.id === id) {
                return item;
            }
        }
    };

    /**
     * find a given component in the current page
     * @param id
     * @returns {*}
     */
    var findComponent = function (id) {
        var i;
        var length;
        var area;
        var component;
        var components;
        var content = page.content;
        for (area in content) {
            if (content.hasOwnProperty(area)) {
                components = content[area];
                length = components.length;
                for (i = 0; i < length; i++) {
                    component = components[i];
                    if (component.id === id) {
                        return component;
                    }
                }
            }
        }
    };

    /**
     * save component properties
     * @param id
     * @param data
     */
    var saveComponentProperties = function (id, data) {
        var o;
        var opt;
        var block = findComponent(id);
        var content = block.content;

        //save options
        var options = content.options;
        var opts = data.options;
        for (opt in opts) {
            if (opts.hasOwnProperty(opt)) {
                o = options[opt] || (options[opt] = {});
                o.value = opts[opt];
            }
        }

        //save settings
        content.settings = data.settings;

        //save styles
        content.styles = data.styles;

        //save wiring
        var event;
        var listener;
        var notifiers = data.notifiers;
        var listen = content.listen;
        for (event in notifiers) {
            if (notifiers.hasOwnProperty(event)) {
                listener = listen[event];
                listener.on = notifiers[event];
            }
        }

        ues.dashboards.rewire(page);
        updateComponent(id);
        saveDashboard();
    };

    /**
     * removes and destroys the given component from the page
     * @param component
     * @param done
     */
    var removeComponent = function (component, done) {
        destroyComponent(component, function (err) {
            if (err) {
                return done(err);
            }
            var container = $('#' + component.id);
            var area = container.closest('.ues-component-box').attr('id');
            var content = page.content;
            area = content[area];
            var index = area.indexOf(component);
            area.splice(index, 1);
            container.remove();

            var properties = $('#ues-properties').find('.ues-content');
            var compId = properties.find('.ues-sandbox').data('component');
            if (compId !== component.id) {
                return done();
            }
            properties.empty();
            hideProperties();
            done();
        });
    };

    /**
     * destroys the given component
     * @param component
     * @param done
     */
    var destroyComponent = function (component, done) {
        ues.components.destroy(component, function (err) {
            if (err) {
                return err;
            }
            done(err);
        });
    };

    /**
     * destroys a given list of components of an area
     * @param components
     * @param done
{'fraction_non_alphanumeric': 0.14133490523261086, 'fraction_numerical': 0.0007254919742450349, 'mean_word_length': 1.819971870604782, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4480843', 'n_tokens_mistral': 5964, 'n_tokens_neox': 5820, 'n_words': 1258}