/* ======================================= ATUM DASHBOARD ======================================= */ import CurrentStockValueWidget from './widgets/_current-stock-value'; import { NiceScroll } from '../_nice-scroll'; import Settings from '../../config/_settings'; import SalesStatsWidget from './widgets/_sales-stats'; import StatisticsWidget from './widgets/_statistics'; import StockControlWidget from './widgets/_stock-control'; import Tooltip from '../_tooltip'; import VideosWidget from './widgets/_videos'; export default class Dashboard { $atumDashboard: JQuery; $widgetsContainer: JQuery; $addWidgetModalContent: JQuery; grid: any; swal: any = window['swal']; constructor( private settings: Settings, private tooltip: Tooltip ) { this.$atumDashboard = $('.atum-dashboard'); this.$widgetsContainer = this.$atumDashboard.find('.atum-widgets'); this.$addWidgetModalContent = this.$atumDashboard.find('#tmpl-atum-modal-add-widgets'); this.buildWidgetsGrid(); this.bindDashButtons(); this.bindWidgetControls(); this.bindConfigControls(); this.initWidgets(); this.marketingBannerConfig(); $(window).resize( () => this.onResize() ).resize(); } onResize() { let width: number = $(window).width(), $dashCards: any = $('.dash-cards'), $videoList: any = $('.video-list-wrapper'); if (width <= 480) { // Apply the caousel to dashboard cards in mobiles. $dashCards.addClass('owl-carousel owl-theme').owlCarousel({ items : 1, margin : 15, stagePadding: 30, }); const videoCarousel: JQuery = $videoList.find('.scroll-box').addClass('owl-carousel owl-theme').owlCarousel({ items : 2, margin : 1, dots : false, stagePadding: 15 }); // Video Carousel nav. const $videoNextNav: JQuery = $videoList.find('.carousel-nav-next'), $videoPrevNav: JQuery = $videoList.find('.carousel-nav-prev'); $videoNextNav.click( () => videoCarousel.trigger('next.owl.carousel') ); $videoPrevNav.click( () => videoCarousel.trigger('prev.owl.carousel') ); videoCarousel.on('changed.owl.carousel', (evt: any) => { if (evt.item.index === 0) { $videoPrevNav.addClass('disabled'); } else if (evt.item.index === evt.item.count - 2) { $videoNextNav.addClass('disabled'); } else { $videoPrevNav.add($videoNextNav).removeClass('disabled'); } }); } else { // Remove the carousel in screens wider than mobile. $('.owl-carousel').removeClass('owl-carousel owl-theme').trigger('destroy.owl.carousel'); } } buildWidgetsGrid() { const $gridStackElem: any = this.$widgetsContainer.find('.grid-stack'); this.grid = $gridStackElem.gridstack({ handle : '.widget-header', alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), verticalMargin : 30, resizable : { autoHide : true, handles : 'se, sw', containment: 'parent', }, }).data('gridstack'); // Bind events. $gridStackElem.on('change', () => { this.saveWidgetsLayout(); NiceScroll.addScrollBars(this.$widgetsContainer); }); // Dynamic min height for widgets. $gridStackElem.on('resizestart', (evt: any, ui: any) => { const minHeight = ui.element.find('.widget-body').outerHeight() + ui.element.find('.widget-header').outerHeight(); ui.element.closest('.atum-widget').css('min-height', minHeight); }); } bindDashButtons() { // "Add more widgets" popup. $('.add-dash-widget').click( () => { this.swal({ title : this.settings.get('availableWidgets'), html : this.$addWidgetModalContent.html(), showConfirmButton: false, showCloseButton : true, customClass : 'add-widget-popup', width : '620px', onOpen : (elem: any) => { // Wait until the show animation is complete setTimeout( () => NiceScroll.addScrollBars($(elem)), 300 ); }, onClose : (elem: any) => NiceScroll.removeScrollBars($(elem)) }) .catch(this.swal.noop); }); // Add widget. $('body').on('click', '.add-widget-popup .add-widget', (evt: JQueryEventObject) => { const $button: JQuery = $(evt.currentTarget), widgetId: string = $button.closest('li').data('widget'), $widgetContainer: JQuery = $('.add-widget-popup'); $.ajax({ url : window['ajaxurl'], method : 'POST', data : { token : this.$widgetsContainer.data('nonce'), action: 'atum_dashboard_add_widget', widget: widgetId }, dataType : 'json', beforeSend: () => $widgetContainer.addClass('overlay'), success : (response: any) => { if (typeof response === 'object' && response.success === true) { const layout = response.data.layout; this.grid.addWidget($(response.data.widget), null, null, layout.min, layout.height, true); this.initWidgets([widgetId]); $button.hide().siblings('.btn-info').show(); this.toggleModalTemplateButtons(widgetId); $widgetContainer.removeClass('overlay'); this.bindWidgetControls(); } } }); }); // Restore default layout and widgets const $restoreDashDefaults: JQuery = $('.restore-defaults'); $restoreDashDefaults.click( () => { this.swal({ title : this.settings.get('areYouSure'), text : this.settings.get('defaultsWillRestore'), type : 'warning', showCancelButton : true, confirmButtonText : this.settings.get('continue'), cancelButtonText : this.settings.get('cancel'), reverseButtons : true, allowOutsideClick : false, showLoaderOnConfirm: true, preConfirm: (): Promise => { return new Promise( (resolve: Function, reject: Function) => { $.ajax({ url : window['ajaxurl'], method : 'POST', data : { token : this.$widgetsContainer.data('nonce'), action: 'atum_dashboard_restore_layout' }, dataType : 'json', beforeSend: () => { this.tooltip.destroyTooltips($restoreDashDefaults); this.$atumDashboard.addClass('overlay'); }, success : () => { resolve(); }, error: () => { reject(); } }); }); } }) .then( () => location.reload() ) .catch(this.swal.noop); }); } toggleModalTemplateButtons(widgetId: string) { this.$addWidgetModalContent.find('[data-widget="' + widgetId + '"]').find('.add-widget').toggle().siblings('.btn-info').toggle(); } bindWidgetControls() { // Remove widget. $('.atum-widget').find('.widget-close').click( (evt:JQueryEventObject) => { const $widget: JQuery = $(evt.currentTarget).closest('.atum-widget'); this.grid.removeWidget($widget); this.toggleModalTemplateButtons( $widget.data('gs-id') ); }); // Widget settings. $('.atum-widget').find('.widget-settings').click( (evt: JQueryEventObject) => { $(evt.currentTarget).closest('.widget-wrapper').find('.widget-config').show().siblings().hide(); }); } bindConfigControls() { // Cancel config. $('.widget-config').find('.cancel-config').click( (evt: JQueryEventObject) => { $(evt.currentTarget).closest('.widget-wrapper').find('.widget-config').hide().siblings().show(); }); // Save config. $('.widget-config').submit( (evt: JQueryEventObject) => { evt.preventDefault(); // TODO: IMPLEMENT WIDGET CONFIG //console.log($(this).serialize()); }); } /** * If no widgets param is passed, all the widgets will be initialized */ initWidgets(widgets?: string[]) { // TODO: DO NOT INIT WIDGETS THAT ARE NOT BEING DISPLAYED const noWidgets: boolean = !widgets || !$.isArray(widgets); // Statistics widget. if (noWidgets || $.inArray('atum_statistics_widget', widgets) > -1) { new StatisticsWidget(this.settings, this.$widgetsContainer); } // Sales Data widgets. if ( noWidgets || $.inArray('atum_sales_widget', widgets) > -1 || $.inArray('atum_lost_sales_widget', widgets) > -1 || $.inArray('atum_orders_widget', widgets) > -1 || $.inArray('atum_promo_sales_widget', widgets) > -1 ) { new SalesStatsWidget(); } // Stock Control widget. if (noWidgets || $.inArray('atum_stock_control_widget', widgets) > -1) { new StockControlWidget(this.settings); } // Current Stock Value widget. if (noWidgets || $.inArray('atum_current_stock_value_widget', widgets) > -1) { new CurrentStockValueWidget(this.$widgetsContainer); } // Videos widget. if (typeof widgets === 'undefined' || $.inArray('atum_videos_widget', widgets) > -1) { new VideosWidget(this.$widgetsContainer); } // Lists' Scrollbars NiceScroll.addScrollBars(this.$widgetsContainer); // Nice Selects. this.doNiceSelects(); } marketingBannerConfig() { // Hide banner. $('.marketing-close').on('click', () => { $('.dash-marketing-banner-container').fadeOut(); }); // Redirect to button url. $('.banner-button').on('click', (evt: JQueryEventObject) => { window.open($(evt.currentTarget).data('url'), '_blank'); }); } doNiceSelects($widget?: JQuery) { const $container: any = typeof $widget !== 'undefined' ? $widget : this.$widgetsContainer; $container.find('select').niceSelect(); } saveWidgetsLayout() { $.ajax({ url : window['ajaxurl'], method : 'POST', data : { action: 'atum_dashboard_save_layout', token : this.$widgetsContainer.data('nonce'), layout: this.serializeLayout(this.grid.grid.nodes) } }); } serializeLayout(items?: any) { let serializedItems: any = {}; if (typeof items === 'undefined') { return serializedItems; } $.each(items, (index: number, data: any) => { serializedItems[data.id] = { x : data.x, y : data.y, height: data.height, width : data.width }; }); return serializedItems; } }