1717 * limitations under the License.
1818 * #L%
1919 */
20- import { Component , OnInit , OnDestroy , AfterViewInit , AfterViewChecked , Input } from '@angular/core' ;
20+ import { Component , OnInit , OnDestroy , AfterViewInit , AfterViewChecked , Input , ViewChildren , QueryList } from '@angular/core' ;
2121import { ActivatedRoute } from '@angular/router' ;
2222import { Subscription , Observable } from 'rxjs/Rx' ;
2323import { JhiEventManager } from 'ng-jhipster' ;
@@ -32,9 +32,10 @@ import { DragulaService } from 'ng2-dragula';
3232import * as $ from 'jquery' ;
3333import { NotificationService } from '../../shared/services/notification.service' ;
3434import { Principal } from '../../shared/auth/principal.service' ;
35- import { Widget , MessageType , EmbedResourceModalComponent , ShareableResourceType } from '../widget' ;
35+ import { Widget , MessageType , EmbedResourceModalComponent , ShareableResourceType , WidgetType , QueryWidgetComponent } from '../widget' ;
3636import { HttpResponse , HttpErrorResponse } from '@angular/common/http' ;
3737import { BsModalRef , BsModalService } from 'ngx-bootstrap' ;
38+ import { forwardRef } from '@angular/core' ;
3839
3940declare var CKEDITOR : any ;
4041
@@ -70,6 +71,12 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
7071
7172 alreadySavingDashboardMessage : boolean = false ;
7273
74+ // query widgets options
75+ queryWidgetId2executionOptions : Object ;
76+ @ViewChildren ( forwardRef ( ( ) => QueryWidgetComponent ) )
77+ queryWidgets : QueryList < QueryWidgetComponent > ;
78+ minimumTimeoutWindow : number ;
79+
7380 // styles and widgets sizing
7481 panelHeadingHeight : string = '40px' ;
7582 widgetContainerPadding : string = '5px' ;
@@ -133,6 +140,8 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
133140 direction : 'vertical'
134141 } ) ;
135142
143+ this . minimumTimeoutWindow = this . principal [ 'userIdentity' ] [ 'contract' ] [ 'pollingInterval' ] ;
144+
136145 this . dragendSubscription = this . dragulaService . dragend ( 'bag-items' ) . subscribe ( ( element ) => {
137146 this . saveDashboardWithCurrentLayout ( ) ;
138147
@@ -237,10 +246,19 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
237246 this . gridStepValue = Math . round ( ( 1 / 12 ) * this . widgetsContainerWidth ) ;
238247
239248 this . gridStep2size = {
249+ '1' : ( this . gridStepValue ) - this . doublePadding ,
240250 '2' : ( 2 * this . gridStepValue ) - this . doublePadding ,
241251 '3' : ( 3 * this . gridStepValue ) - this . doublePadding ,
242252 '4' : ( 4 * this . gridStepValue ) - this . doublePadding ,
243- '5' : ( 5 * this . gridStepValue ) - this . doublePadding
253+ '5' : ( 5 * this . gridStepValue ) - this . doublePadding ,
254+ '6' : ( 6 * this . gridStepValue ) - this . doublePadding ,
255+ '7' : ( 7 * this . gridStepValue ) - this . doublePadding ,
256+ '8' : ( 8 * this . gridStepValue ) - this . doublePadding ,
257+ '9' : ( 9 * this . gridStepValue ) - this . doublePadding ,
258+ '10' : ( 10 * this . gridStepValue ) - this . doublePadding ,
259+ '11' : ( 11 * this . gridStepValue ) - this . doublePadding ,
260+ '12' : ( 12 * this . gridStepValue ) - this . doublePadding
261+
244262 } ;
245263 this . heightsForCloseness = [ ] ;
246264 for ( const key of Object . keys ( this . gridStep2size ) ) {
@@ -261,7 +279,7 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
261279 enableResizingForAllWidgets ( ) {
262280 for ( const widget of this . dashboard [ 'widgets' ] ) {
263281 const currentLayoutWidgetInfo = this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] . get ( widget [ 'id' ] ) ;
264- this . widgetActivateResizing ( currentLayoutWidgetInfo [ 'widgetId' ] , currentLayoutWidgetInfo [ 'width' ] ) ;
282+ this . widgetActivateResizing ( currentLayoutWidgetInfo [ 'widgetId' ] , ( < Widget > widget ) . type , currentLayoutWidgetInfo [ 'width' ] ) ;
265283 }
266284 }
267285
@@ -359,6 +377,11 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
359377 // through the dashboard select in the top navbar
360378 this . initWidgetsWithDeafultLayout ( ) ;
361379 }
380+ if ( this . widgetsLayoutsLoaded ) {
381+ // case: we init the default layouts for all the widgets in a dashboard loaded
382+ // through the dashboard select in the top navbar
383+ this . initWidgetsWithDeafultLayout ( ) ;
384+ }
362385 } else {
363386 // adding widgets following the layout order
364387 this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] . forEach ( ( value , widgetInfoKey ) => {
@@ -381,6 +404,9 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
381404 for ( const widget of this . dashboard [ 'widgets' ] ) {
382405 const height : string = this . defaultWidgetHeight + 'px' ;
383406 const layout = this . buildDeaultLayoutInfo ( widget . id , height ) ;
407+ if ( widget [ 'type' ] === WidgetType . QUERY ) {
408+ layout [ 'width' ] = 12 ;
409+ }
384410 this . dashboard . addWidgetLayoutInfo ( layout ) ;
385411 }
386412 this . widgetsLayoutsLoaded = true ;
@@ -405,17 +431,28 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
405431
406432 if ( response . eventOccurred === 'new-widget' ) {
407433 const height : string = this . defaultWidgetHeight + 'px' ;
408- const defaultLayoutOptions = this . buildDeaultLayoutInfo ( response . content . id , height ) ;
409434 const widget = response . content ;
435+ const defaultLayoutOptions = this . buildDeaultLayoutInfo ( response . content . id , height ) ;
436+ if ( widget [ 'type' ] === WidgetType . QUERY ) {
437+ defaultLayoutOptions [ 'width' ] = 12 ;
438+ }
410439 this . dashboard . addWidget ( widget ) ;
411440 if ( ! this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] ) {
412441 this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] = new Map ( ) ;
413442 }
414443 this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] . set ( defaultLayoutOptions [ 'widgetId' ] , defaultLayoutOptions ) ;
415444 setTimeout ( ( ) => { // waiting for the panel is rendered
416- this . widgetActivateResizing ( defaultLayoutOptions [ 'widgetId' ] , defaultLayoutOptions [ 'width' ] ) ;
445+ this . widgetActivateResizing ( defaultLayoutOptions [ 'widgetId' ] , widget . type , defaultLayoutOptions [ 'width' ] ) ;
417446 } , 50 ) ;
418447
448+ // if the new widget is a query-widget we have to update the handle the external options (auto-update flag and auto-update interval)
449+ if ( widget . type === WidgetType . QUERY ) {
450+ this . queryWidgetId2executionOptions [ widget [ 'id' ] ] = {
451+ autoUpdate : false ,
452+ autoUpdateIntervalWindow : this . principal [ 'userIdentity' ] [ 'contract' ] [ 'pollingInterval' ]
453+ } ;
454+ }
455+
419456 // if the dashboard is shared, the new widget will be shared too
420457 if ( this . dashboard [ 'shared' ] ) {
421458 widget [ 'shared' ] = true ;
@@ -431,7 +468,7 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
431468 this . dashboard . updateWidget ( editedWidget ) ;
432469 setTimeout ( ( ) => { // waiting for the panel is rendered
433470 const widgetLayout = this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] . get ( editedWidgetId ) ;
434- this . widgetActivateResizing ( editedWidgetId , widgetLayout [ 'width' ] ) ;
471+ this . widgetActivateResizing ( editedWidgetId , editedWidget . type , widgetLayout [ 'width' ] ) ;
435472 } , 50 ) ;
436473 } else if ( response . eventOccurred === 'widget-removed' ) {
437474 const currentRemovingWidgetId : number = response . content ;
@@ -523,7 +560,6 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
523560
524561 if ( saveAllowed ) {
525562
526- const infoNotification = this . notificationService . push ( 'info' , 'Save' , 'Saving the Dashboard layout...' , 3000 , 'fa fa-spinner fa-spin' ) ;
527563 const delay : number = 10 ;
528564
529565 setTimeout ( ( ) => {
@@ -545,11 +581,12 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
545581 delete dashboardCopy [ 'widgets' ] ;
546582
547583 this . dashboardService . update ( dashboardCopy ) . subscribe ( ( res ) => {
548- const message : string = 'Dashboard correctly saved.' ;
549- this . notificationService . updateNotification ( infoNotification , 'success' , 'Save' , message , undefined , true ) ;
584+ console . log ( 'Dashboard correctly saved.' ) ;
550585 this . alreadySavingDashboardMessage = false ;
551586 } , ( err : HttpErrorResponse ) => {
552- this . notificationService . updateNotification ( infoNotification , 'error' , 'Save' , 'Saving attempt failed.' , undefined , true ) ;
587+ const message = `Implicit dashboard saving failed. Current dashboard status will not be available at the next application loading.\n
588+ Try to check the server connection.` ;
589+ this . notificationService . push ( 'error' , 'Dashboard Save' , message , undefined , true ) ;
553590 console . log ( err . message ) ;
554591 this . alreadySavingDashboardMessage = false ;
555592 } ) ;
@@ -585,15 +622,52 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
585622 } ) ;
586623 }
587624
588- widgetActivateResizing ( widgetId , originalColumnWidth ) {
625+ updateQueryWidget ( queryWidgetId : number ) {
626+ ( < QueryWidgetComponent > this . getQueryWidgetById ( queryWidgetId ) ) . performLastDataFetching ( ) ;
627+ }
628+
629+ updateQueryWidgetAutoUpdateFlag ( queryWidgetId : number ) {
630+ const queryWidget = ( < QueryWidgetComponent > this . getQueryWidgetById ( queryWidgetId ) ) ;
631+ queryWidget . handleAutoUpdateFlagChange ( ) ;
632+ queryWidget . saveAll ( true ) ;
633+ }
634+
635+ updateQueryWidgetAutoUpdateInterval ( queryWidgetId : number , autoUpdateInterval : number ) {
636+ const queryWidget = ( < QueryWidgetComponent > this . getQueryWidgetById ( queryWidgetId ) ) ;
637+ queryWidget . handleAutoUpdateIntervalChange ( ) ;
638+ queryWidget . saveAll ( true ) ;
639+ }
640+
641+ getQueryWidgetById ( queryWidgetId : number ) {
642+ return this . queryWidgets . find ( ( queryWidget ) => queryWidget [ 'widget' ] [ 'id' ] === queryWidgetId ) ;
643+ }
644+
645+ /**
646+ * Activates the resizable function on all the widgets' panels.
647+ * @param widgetId
648+ * @param originalColumnWidth number of bootstrap columns, e.g. 1,2,3...6
649+ */
650+ widgetActivateResizing ( widgetId : number , widgetType : WidgetType , originalColumnWidth : number ) {
589651
590652 const originalPxWidth = ( < any > $ ( '#panel_' + widgetId ) ) . width ( ) ;
591653
654+ let minimumWidth ;
655+ let minimumHeight ;
656+ if ( widgetType === WidgetType . QUERY ) {
657+ // overriding minimum width grid step to 12 and minimun height to 1 for Query Widgets
658+ minimumWidth = this . gridStep2size [ '12' ] - 10 ; // 10 is just a little threshold, as the minimum width is not included in the available range
659+ minimumHeight = this . gridStep2size [ '1' ] ;
660+ } else {
661+ minimumWidth = this . minimumWidth ;
662+ minimumHeight = this . minimumHeight ;
663+ }
664+
592665 ( < any > $ ( '#panel_' + widgetId ) ) . resizable ( {
666+
593667 grid : this . gridStepValue ,
594- minWidth : this . minimumWidth ,
668+ minWidth : minimumWidth ,
595669 maxWidth : this . maximumWidth ,
596- minHeight : this . minimumHeight , // minimum height chosen according to the minimum width
670+ minHeight : minimumHeight ,
597671 maxHeight : this . maximumHeight ,
598672 handleSelector : '.panel' ,
599673 resizeWidth : true ,
@@ -611,6 +685,7 @@ export class DashboardDetailComponent implements OnInit, AfterViewInit, AfterVie
611685 const newPxWidth = newUiWidth ;
612686 let newColumnWidth = ( newPxWidth * originalColumnWidth ) / originalPxWidth ; // originalPxWidth/originalColumnWidth = newPxWidth/newColumnWidth
613687 newColumnWidth = Math . round ( newColumnWidth ) ;
688+
614689 this . dashboard [ 'layout' ] [ 'widgetsLayoutInfo' ] . get ( widgetId ) [ 'width' ] = newColumnWidth ;
615690
616691 // height resizing
0 commit comments