{"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","proxy","getTypeInfo","type","selectedOption","handleNewWidgetOptionSelect","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","removeClass","noObjectsSelector","textStatus","success","update","lastWidget","destroy","$heading","find","$bod","resetItemOrder","$table","onDeleteItem","id","i","eq","getManagerRow","$tbody","HUD","onHide","$settingsForm","AdminTable","$settingsContainer","$settingsErrorList","reorderAction","deleteAction","onReorderItems","ids","parent","initSettingsFn","initBackUi","refreshSettings","$front","$settingsBtn","$title","$subtitle","$bodyContainer","$back","$btnsContainer","$settingsSpinner","getColspan","title","setColspan","window","dashboard","showingSettings","setSettingsHtml","container","requestAnimationFrame","velocity","hasClass","onShowBack","complete","onShowFront","saveSettings","preventDefault","action","colspan","refreshCols","info","displayError","html","subtitle","showSettings","height","hideSettings","remove","bodyHtml","serialize","scrollContainerToElement","initUiElements","appendHeadHtml","appendFootHtml","cp","displayNotice","removeListener","errors","ui","createErrorList","setTimeout","attr","prepend","valueLabel","addRow","getManagerRowLabel","postActionRequest","colspanPicker","typeName","escapeHtml","base","headHtml","footHtml","cancelSettings","trigger","updateContainerHeight","$row","SlidePicker","min","max","totalCols","step","num","onChange","refresh","removeItems","jQuery"],"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($.proxy(function() {\n                this.$grid = $('#dashboard-grid');\n                this.grid = this.$grid.data('grid');\n                $('#newwidgetmenubtn').data('menubtn').menu.on('optionselect', $.proxy(this, 'handleNewWidgetOptionSelect'));\n            }, this));\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: $.proxy(function() {\n                        this.$widgetManagerBtn.addClass('active');\n                    }, this),\n                    onHide: $.proxy(function() {\n                        this.$widgetManagerBtn.removeClass('active');\n                    }, this)\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: $.proxy(function(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                    }, this),\n                    onDeleteItem: $.proxy(function(id) {\n                        var widget = this.widgets[id];\n\n                        widget.destroy();\n                    }, this)\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($.proxy(function() {\n                Craft.initUiElements(this.$settingsContainer);\n                this.initSettingsFn();\n            }, this));\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: $.proxy(this, 'onShowBack')\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: $.proxy(this, 'onShowFront')\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, $.proxy(function(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            }, this));\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($.proxy(function() {\n                this.$settingsForm.find(':focusable:first').trigger('focus');\n            }, this), 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($.proxy(function() {\n                window.dashboard.grid.removeItems(this.$gridItem);\n                this.$gridItem.remove();\n            }, this), 200);\n        }\n    });\n})(jQuery);\n"]}