{"version":3,"sources":["dashboard/src/Dashboard.js"],"names":["$","Craft","Dashboard","Garnish","Base","extend","$grid","$widgetManagerBtn","widgetTypes","widgets","widgetManager","widgetAdminTable","init","addListener","this","$doc","ready","data","grid","property","defaultValue","menu","on","handleNewWidgetOptionSelect","bind","getTypeInfo","type","selectedOption","e","$gridItem","$container","settingsNamespace","Math","floor","random","settingsHtml","addClass","toLowerCase","replace","class","data-type","append","name","value","text","t","$option","$items","response","appendTo","showWidgetManager","$form","$noWidgets","children","$widgets","widget","Widget","eval","settingsJs","length","insertAfter","last","prependTo","hudClass","addItems","onShow","scrollContainerToElement","removeClass","noObjectsSelector","textStatus","success","update","lastWidget","destroy","$settingsBtn","$front","$bod","resetItemOrder","$table","onDeleteItem","i","eq","id","getManagerRow","$tbody","HUD","onHide","$settingsContainer","AdminTable","tableSelector","$settingsErrorList","sortable","reorderAction","deleteAction","onReorderItems","ids","container","onShowFront","initBackUi","onShowBack","$title","$subtitle","$heading","$back","$settingsForm","$settingsSpinner","$btnsContainer","getColspan","title","subtitle","totalCols","window","initSettingsFn","colspanPicker","parent","refreshSettings","html","initUiElements","dashboard","find","requestAnimationFrame","height","complete","saveSettings","action","setColspan","colspan","refreshCols","displayNotice","setSettingsHtml","displayError","showSettings","velocity","hideSettings","remove","preventDefault","hasClass","$bodyContainer","info","postActionRequest","appendHeadHtml","cp","showingSettings","errors","ui","createErrorList","updateContainerHeight","attr","prepend","getManagerRowLabel","bodyHtml","typeName","escapeHtml","headHtml","base","appendFootHtml","footHtml","removeItems","jQuery","removeListener","setTimeout","trigger","$row","SlidePicker","min","max","step","valueLabel","num","onChange","refresh"],"mappings":"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","file":"Dashboard.min.js","sourcesContent":["(function($) {\n    /** global: Craft */\n    /** global: Garnish */\n    /**\n     * Dashboard class\n     */\n    Craft.Dashboard = Garnish.Base.extend({\n        $grid: null,\n        $widgetManagerBtn: null,\n\n        widgetTypes: null,\n        grid: null,\n        widgets: null,\n        widgetManager: null,\n        widgetAdminTable: null,\n        widgetSettingsModal: null,\n\n        init: function(widgetTypes) {\n            this.widgetTypes = widgetTypes;\n            this.widgets = {};\n\n            this.$widgetManagerBtn = $('#widgetManagerBtn');\n\n            this.addListener(this.$widgetManagerBtn, 'click', 'showWidgetManager');\n\n            Garnish.$doc.ready(() => {\n                this.$grid = $('#dashboard-grid');\n                this.grid = this.$grid.data('grid');\n                $('#newwidgetmenubtn').data('menubtn').menu.on('optionselect', this.handleNewWidgetOptionSelect.bind(this));\n            });\n        },\n\n        getTypeInfo: function(type, property, defaultValue) {\n            if (property) {\n                if (typeof this.widgetTypes[type][property] === 'undefined') {\n                    return defaultValue;\n                } else {\n                    return this.widgetTypes[type][property];\n                }\n            } else {\n                return this.widgetTypes[type];\n            }\n        },\n\n        handleNewWidgetOptionSelect: function(e) {\n            var $option = $(e.selectedOption),\n                type = $option.data('type'),\n                settingsNamespace = 'newwidget' + Math.floor(Math.random() * 1000000000) + '-settings',\n                settingsHtml = this.getTypeInfo(type, 'settingsHtml', '').replace(/__NAMESPACE__/g, settingsNamespace),\n                settingsJs = this.getTypeInfo(type, 'settingsJs', '').replace(/__NAMESPACE__/g, settingsNamespace),\n                $gridItem = $('<div class=\"item\" data-colspan=\"1\" style=\"display: block\">'),\n                $container = $('<div/>', {\n                    'class': 'widget new loading-new scaleout',\n                    'data-type': type,\n                })\n                    .addClass(type.toLowerCase())\n                    .append(\n                        $('<div/>', {'class': 'front'})\n                            .append(\n                                $('<div/>', {'class': 'pane'})\n                                    .append(\n                                        $('<div/>', {'class': 'spinner body-loading'})\n                                    )\n                                    .append(\n                                        $('<div/>', {'class': 'widget-heading'})\n                                            .append('<h2/>')\n                                            .append('<h5/>')\n                                    )\n                                    .append(\n                                        $('<div/>', {'class': 'body'})\n                                    )\n                                    .append(\n                                        $('<div/>', {'class': 'settings icon hidden'})\n                                    )\n                            )\n                    )\n                    .append(\n                        $('<div/>', {'class': 'back'})\n                            .append(\n                                $('<form/>', {'class': 'pane'})\n                                    .append(\n                                        $('<input/>', {\n                                            type: 'hidden',\n                                            name: 'type',\n                                            value: type,\n                                        })\n                                    )\n                                    .append(\n                                        $('<input/>', {\n                                            type: 'hidden',\n                                            name: 'settingsNamespace',\n                                            value: settingsNamespace,\n                                        })\n                                    )\n                                    .append(\n                                        $('<h2/>', {\n                                            text: Craft.t('app', '{type} Settings', {\n                                                type: $option.data('name')\n                                            }),\n                                        })\n                                    )\n                                    .append(\n                                        $('<div/>', {'class': 'settings'})\n                                    )\n                                    .append('<hr/>')\n                                    .append(\n                                        $('<div/>', {'class': 'buttons clearafter'})\n                                            .append(\n                                                $('<button/>', {\n                                                    type: 'submit',\n                                                    'class': 'btn submit',\n                                                    text: Craft.t('app', 'Save'),\n                                                })\n                                            )\n                                            .append(\n                                                $('<button/>', {\n                                                    type: 'button',\n                                                    'class': 'btn',\n                                                    text: Craft.t('app', 'Cancel')\n                                                })\n                                            )\n                                            .append(\n                                                $('<div/>', {'class': 'spinner hidden'})\n                                            )\n                                    )\n                            )\n                    )\n                    .appendTo($gridItem);\n\n            if (settingsHtml) {\n                $container.addClass('flipped');\n                $container.children('.front').addClass('hidden');\n            } else {\n                $container.addClass('loading');\n                $container.children('.back').addClass('hidden');\n            }\n\n            var widget = new Craft.Widget($container, settingsHtml.replace(/__NAMESPACE__/g, settingsNamespace), function() {\n                eval(settingsJs);\n            });\n\n            // Append the new widget after the last one\n            // (can't simply append it to the grid container, since that will place it after the resize listener object)\n\n            if (this.grid.$items.length) {\n                $gridItem.insertAfter(this.grid.$items.last());\n            } else {\n                $gridItem.prependTo(this.grid.$container);\n            }\n\n            this.grid.addItems($gridItem);\n            Garnish.scrollContainerToElement($gridItem);\n\n            $container.removeClass('scaleout');\n\n            if (!settingsHtml) {\n                var data = {\n                    type: type\n                };\n\n                Craft.postActionRequest('dashboard/create-widget', data, function(response, textStatus) {\n                    if (textStatus === 'success' && response.success) {\n                        $container.removeClass('loading');\n                        widget.update(response);\n                    } else {\n                        widget.destroy();\n                    }\n                });\n            }\n        },\n\n        showWidgetManager: function() {\n            if (!this.widgetManager) {\n                var $widgets = this.$grid.find('> .item > .widget'),\n                    $form = $(\n                        '<form method=\"post\" accept-charset=\"UTF-8\">' +\n                        '<input type=\"hidden\" name=\"action\" value=\"widgets/save-widget\"/>' +\n                        '</form>'\n                    ).appendTo(Garnish.$bod),\n                    $noWidgets = $('<p id=\"nowidgets\"' + ($widgets.length ? ' class=\"hidden\"' : '') + '>' + Craft.t('app', 'You don’t have any widgets yet.') + '</p>').appendTo($form),\n                    $table = $('<table class=\"data' + (!$widgets.length ? ' hidden' : '') + '\"/>').appendTo($form),\n                    $tbody = $('<tbody/>').appendTo($table);\n\n                for (var i = 0; i < $widgets.length; i++) {\n                    var $widget = $widgets.eq(i),\n                        widget = $widget.data('widget');\n\n                    // Make sure it's actually saved\n                    if (!widget || !widget.id) {\n                        continue;\n                    }\n\n                    widget.getManagerRow().appendTo($tbody);\n                }\n\n                this.widgetManager = new Garnish.HUD(this.$widgetManagerBtn, $form, {\n                    hudClass: 'hud widgetmanagerhud',\n                    onShow: () => {\n                        this.$widgetManagerBtn.addClass('active');\n                    },\n                    onHide: () => {\n                        this.$widgetManagerBtn.removeClass('active');\n                    },\n                });\n\n                this.widgetAdminTable = new Craft.AdminTable({\n                    tableSelector: $table,\n                    noObjectsSelector: $noWidgets,\n                    sortable: true,\n                    reorderAction: 'dashboard/reorder-user-widgets',\n                    deleteAction: 'dashboard/delete-user-widget',\n                    onReorderItems: ids => {\n                        var lastWidget = null;\n\n                        for (var i = 0; i < ids.length; i++) {\n                            var widget = this.widgets[ids[i]];\n\n                            if (!lastWidget) {\n                                widget.$gridItem.prependTo(this.$grid);\n                            } else {\n                                widget.$gridItem.insertAfter(lastWidget.$gridItem);\n                            }\n\n                            lastWidget = widget;\n                        }\n\n                        this.grid.resetItemOrder();\n                    },\n                    onDeleteItem: id => {\n                        this.widgets[id].destroy();\n                    },\n                });\n            } else {\n                this.widgetManager.show();\n            }\n        }\n    });\n\n    /**\n     * Dashboard Widget class\n     */\n    Craft.Widget = Garnish.Base.extend({\n        $container: null,\n        $gridItem: null,\n\n        $front: null,\n        $settingsBtn: null,\n        $title: null,\n        $subtitle: null,\n        $heading: null,\n        $bodyContainer: null,\n\n        $back: null,\n        $settingsForm: null,\n        $settingsContainer: null,\n        $settingsSpinner: null,\n        $settingsErrorList: null,\n\n        id: null,\n        type: null,\n        title: null,\n        subtitle: null,\n\n        totalCols: null,\n        settingsHtml: null,\n        initSettingsFn: null,\n        showingSettings: false,\n\n        colspanPicker: null,\n\n        init: function(container, settingsHtml, initSettingsFn) {\n            this.$container = $(container);\n            this.$gridItem = this.$container.parent();\n\n            // Store a reference to this object on the container element\n            this.$container.data('widget', this);\n\n            // Do a little introspection\n            this.id = this.$container.data('id');\n            this.type = this.$container.data('type');\n            this.title = this.$container.data('title');\n\n            if (this.id) {\n                // Store a reference to this object on the main Dashboard object\n                window.dashboard.widgets[this.id] = this;\n            }\n\n            this.$front = this.$container.children('.front');\n            this.$settingsBtn = this.$front.find('> .pane > .icon.settings');\n            this.$heading = this.$front.find('> .pane > .widget-heading');\n            this.$title = this.$heading.find('> h2');\n            this.$subtitle = this.$heading.find('> h5');\n            this.$bodyContainer = this.$front.find('> .pane > .body');\n\n            this.setSettingsHtml(settingsHtml, initSettingsFn);\n\n            if (!this.$container.hasClass('flipped')) {\n                this.onShowFront();\n            } else {\n                this.initBackUi();\n                this.refreshSettings();\n                this.onShowBack();\n            }\n\n            this.addListener(this.$settingsBtn, 'click', 'showSettings');\n        },\n\n        initBackUi: function() {\n            this.$back = this.$container.children('.back');\n            this.$settingsForm = this.$back.children('form');\n            this.$settingsContainer = this.$settingsForm.children('.settings');\n            var $btnsContainer = this.$settingsForm.children('.buttons');\n            this.$settingsSpinner = $btnsContainer.children('.spinner');\n\n            this.addListener($btnsContainer.children('.btn:nth-child(2)'), 'click', 'cancelSettings');\n            this.addListener(this.$settingsForm, 'submit', 'saveSettings');\n        },\n\n        getColspan: function() {\n            return this.$gridItem.data('colspan');\n        },\n\n        setColspan: function(colspan) {\n            this.$gridItem.data('colspan', colspan);\n            window.dashboard.grid.refreshCols(true);\n        },\n\n        getTypeInfo: function(property, defaultValue) {\n            return window.dashboard.getTypeInfo(this.type, property, defaultValue);\n        },\n\n        setSettingsHtml: function(settingsHtml, initSettingsFn) {\n            this.settingsHtml = settingsHtml;\n            this.initSettingsFn = initSettingsFn;\n\n            if (this.settingsHtml) {\n                this.$settingsBtn.removeClass('hidden');\n            } else {\n                this.$settingsBtn.addClass('hidden');\n            }\n        },\n\n        refreshSettings: function() {\n            this.$settingsContainer.html(this.settingsHtml);\n\n            Garnish.requestAnimationFrame(() => {\n                Craft.initUiElements(this.$settingsContainer);\n                this.initSettingsFn();\n            });\n        },\n\n        showSettings: function() {\n            if (!this.$back) {\n                this.initBackUi();\n            }\n\n            // Refresh the settings every time\n            this.refreshSettings();\n\n            this.$back.removeClass('hidden');\n            Garnish.requestAnimationFrame(() => {\n                this.$container\n                    .addClass('flipped')\n                    .velocity({height: this.$back.height()}, {\n                        complete: this.onShowBack.bind(this)\n                    });\n            });\n        },\n\n        hideSettings: function() {\n            this.$front.removeClass('hidden');\n\n            Garnish.requestAnimationFrame(() => {\n                this.$container\n                    .removeClass('flipped')\n                    .velocity({height: this.$front.height()}, {\n                        complete: this.onShowFront.bind(this)\n                    });\n            });\n        },\n\n        saveSettings: function(e) {\n            e.preventDefault();\n            this.$settingsSpinner.removeClass('hidden');\n\n            var action = this.$container.hasClass('new') ? 'dashboard/create-widget' : 'dashboard/save-widget-settings',\n                data = this.$settingsForm.serialize();\n\n            Craft.postActionRequest(action, data, (response, textStatus) => {\n                this.$settingsSpinner.addClass('hidden');\n\n                if (textStatus === 'success') {\n                    if (this.$settingsErrorList) {\n                        this.$settingsErrorList.remove();\n                        this.$settingsErrorList = null;\n                    }\n\n                    if (response.success) {\n                        Craft.cp.displayNotice(Craft.t('app', 'Widget saved.'));\n\n                        // Make sure the widget is still allowed to be shown, just in case\n                        if (!response.info) {\n                            this.destroy();\n                        } else {\n                            this.update(response);\n                            this.hideSettings();\n                        }\n                    } else {\n                        Craft.cp.displayError(Craft.t('app', 'Couldn’t save widget.'));\n\n                        if (response.errors) {\n                            this.$settingsErrorList = Craft.ui.createErrorList(response.errors)\n                                .insertAfter(this.$settingsContainer);\n                        }\n                    }\n                }\n            });\n        },\n\n        update: function(response) {\n            this.title = response.info.title;\n            this.subtitle = response.info.subtitle;\n\n            // Is this a new widget?\n            if (this.$container.hasClass('new')) {\n                // Discover ourself\n                this.id = response.info.id;\n\n                this.$container\n                    .attr('id', 'widget' + this.id)\n                    .removeClass('new loading-new');\n\n                if (this.$settingsForm) {\n                    this.$settingsForm.prepend('<input type=\"hidden\" name=\"widgetId\" value=\"' + this.id + '\"/>');\n                }\n\n                // Store a reference to this object on the main Dashboard object, now that the widget actually exists\n                window.dashboard.widgets[this.id] = this;\n\n                if (window.dashboard.widgetAdminTable) {\n                    window.dashboard.widgetAdminTable.addRow(this.getManagerRow());\n                }\n            } else {\n                if (window.dashboard.widgetAdminTable) {\n                    window.dashboard.widgetAdminTable.$tbody.children('[data-id=\"' + this.id + '\"]:first').children('td:nth-child(2)').html(this.getManagerRowLabel());\n                }\n            }\n\n            if (!this.title && !this.subtitle) {\n                this.$heading.remove();\n            } else {\n                if (this.title) {\n                    this.$title.text(this.title);\n                } else {\n                    this.$title.remove();\n                }\n\n                if (this.subtitle) {\n                    this.$subtitle.text(this.subtitle);\n                } else {\n                    this.$subtitle.remove();\n                }\n            }\n\n            this.$bodyContainer.html(response.info.bodyHtml);\n\n            // New colspan?\n            if (response.info.colspan != this.getColspan()) {\n                this.setColspan(response.info.colspan);\n                Garnish.scrollContainerToElement(this.$gridItem);\n            }\n\n            Craft.initUiElements(this.$bodyContainer);\n            Craft.appendHeadHtml(response.headHtml);\n            Craft.appendFootHtml(response.footHtml);\n\n            this.setSettingsHtml(response.info.settingsHtml, function() {\n                eval(response.info.settingsJs);\n            });\n        },\n\n        cancelSettings: function() {\n            if (this.id) {\n                this.hideSettings();\n            } else {\n                this.destroy();\n            }\n        },\n\n        onShowFront: function() {\n            this.showingSettings = false;\n            this.removeListener(this.$back, 'resize');\n            this.addListener(this.$front, 'resize', 'updateContainerHeight');\n            if (this.$back) {\n                this.$back.addClass('hidden');\n            }\n        },\n\n        onShowBack: function() {\n            this.showingSettings = true;\n            this.removeListener(this.$front, 'resize');\n            this.addListener(this.$back, 'resize', 'updateContainerHeight');\n            this.$front.addClass('hidden');\n\n            // Focus on the first input\n            setTimeout(() => {\n                this.$settingsForm.find(':focusable:first').trigger('focus');\n            }, 1);\n        },\n\n        updateContainerHeight: function() {\n            this.$container.height((this.showingSettings ? this.$back : this.$front).height());\n        },\n\n        getManagerRow: function() {\n            var $row = $(\n                '<tr data-id=\"' + this.id + '\" data-name=\"' + Craft.escapeHtml(this.title) + '\">' +\n                '<td class=\"widgetmanagerhud-icon\">' + this.getTypeInfo('iconSvg') + '</td>' +\n                '<td>' + this.getManagerRowLabel() + '</td>' +\n                '<td class=\"widgetmanagerhud-col-colspan-picker thin\"></td>' +\n                '<td class=\"widgetmanagerhud-col-move thin\"><a class=\"move icon\" title=\"' + Craft.t('app', 'Reorder') + '\" role=\"button\"></a></td>' +\n                '<td class=\"thin\"><a class=\"delete icon\" title=\"' + Craft.t('app', 'Delete') + '\" role=\"button\"></a></td>' +\n                '</tr>'\n            );\n\n            // Initialize the colspan picker\n            this.colspanPicker = new Craft.SlidePicker(this.getColspan(), {\n                min: 1,\n                max: () => {\n                    return window.dashboard.grid.totalCols;\n                },\n                step: 1,\n                valueLabel: colspan => {\n                    return Craft.t('app', '{num, number} {num, plural, =1{column} other{columns}}', {\n                        num: colspan,\n                    });\n                },\n                onChange: colspan => {\n                    // Update the widget and grid\n                    this.setColspan(colspan);\n                    window.dashboard.grid.refreshCols(true);\n\n                    // Save the change\n                    let data = {\n                        id: this.id,\n                        colspan: colspan\n                    };\n\n                    Craft.postActionRequest('dashboard/change-widget-colspan', data, (response, textStatus) => {\n                        if (textStatus === 'success' && response.success) {\n                            Craft.cp.displayNotice(Craft.t('app', 'Widget saved.'));\n                        } else {\n                            Craft.cp.displayError(Craft.t('app', 'Couldn’t save widget.'));\n                        }\n                    });\n                }\n            });\n\n            this.colspanPicker.$container.appendTo($row.find('> td.widgetmanagerhud-col-colspan-picker'));\n            window.dashboard.grid.on('refreshCols', () => {\n                this.colspanPicker.refresh();\n            });\n\n            return $row;\n        },\n\n        getManagerRowLabel: function() {\n            var typeName = this.getTypeInfo('name');\n\n            return Craft.escapeHtml(this.title) + (this.title !== typeName ? ' <span class=\"light\">(' + typeName + ')</span>' : '');\n        },\n\n        destroy: function() {\n            delete window.dashboard.widgets[this.id];\n            this.$container.addClass('scaleout');\n            this.base();\n\n            setTimeout(() => {\n                window.dashboard.grid.removeItems(this.$gridItem);\n                this.$gridItem.remove();\n            }, 200);\n        }\n    });\n})(jQuery);\n"]}