Project

General

Profile

« Previous | Next » 

Revision 57708

[Monitor-Dashboard]: Rename home -> stakeholder. Add custom classes to chart Icons

View differences:

modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/home/home-routing.module.ts
1
import {NgModule} from '@angular/core';
2
import {RouterModule} from '@angular/router';
3
import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard';
4
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
5
import {HomeComponent} from "./home.component";
6

  
7
@NgModule({
8
  imports: [
9
    RouterModule.forChild([
10
      {
11
        path: '',
12
        component: HomeComponent,
13
        canActivate: [FreeGuard],
14
        canDeactivate: [PreviousRouteRecorder]
15
      }
16
    ])
17
  ]
18
})
19
export class HomeRoutingModule {
20
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/home/home.component.html
1
<aside id="sidebar_main">
2
  <div *ngIf="stakeholder" class="sidebar_main_header">
3
    <div class="uk-padding-small">
4
      <img class="uk-margin-bottom" *ngIf="stakeholder.logoUrl" [src]="stakeholder.logoUrl">
5
      <h4 class="uk-text-bold uk-margin-remove">{{stakeholder.index_name}}</h4>
6
      <span class="uk-text-large">Admin Dashboard</span>
7
    </div>
8
  </div>
9
  <div *ngIf="stakeholder" class="menu_section">
10
    <ul>
11
      <li [class.current_section]="analysisOpen"
12
          [class.act_section]="analysisOpen"
13
          class="submenu_trigger">
14
        <a href="#" (click)="analysisOpen = !analysisOpen; $event.preventDefault()">
15
          <span class="menu_icon"><i class="material-icons">donut_large</i></span>
16
          <span class="menu_title">Analysis Indicators</span>
17
        </a>
18
        <ul [style.display]="(analysisOpen?'block':'none')">
19
          <ng-template ngFor [ngForOf]="stakeholder.topics" let-topic let-i="index">
20
            <li>
21
              <a [routerLink]="topic.alias">
22
                <span *ngIf="topic.icon" class="menu_icon uk-margin-small-right"><i
23
                  class="material-icons">{{topic.icon}}</i></span>
24
                <div class="menu_title uk-inline">
25
                  {{topic.name}}
26
                  <button class="uk-position-center-right-out uk-margin-right uk-button uk-button-link onHover"
27
                          (click)="$event.stopPropagation();saveTopicOpen(editTopic, i); $event.preventDefault()">
28
                    <i class="material-icons">more_horiz</i>
29
                  </button>
30
                </div>
31
              </a>
32
              <div uk-drop="mode: none; offset: -2; delay-hide: 0;" #editTopic
33
                   class="uk-padding-large uk-padding-remove-vertical uk-padding-remove-right uk-drop">
34
                <div *ngIf="topicFb">
35
                  <div class="md-card">
36
                    <div class="md-card-content uk-position-relative">
37
                      <a class="uk-position-top-right">
38
                        <i (click)="hide(editTopic)" class="material-icons">close</i>
39
                      </a>
40
                      <div class="uk-grid-small" uk-grid [formGroup]="topicFb">
41
                        <div class="uk-width-1-1">
42
                          <label class="uk-text-bold">Topic Settings</label>
43
                          <input class="uk-input uk-form-small" formControlName="name"
44
                                 [class.uk-form-danger]="topicFb.get('name').dirty && topicFb.get('name').invalid"
45
                                 type="text">
46
                        </div>
47
                        <div class="uk-width-1-1">
48
                          <label>Description</label>
49
                          <textarea class="uk-textarea" formControlName="description"
50
                                    rows="3" type="text"></textarea>
51
                        </div>
52
                        <div class="uk-width-1-2">
53
                          <select class="uk-select uk-form-small" formControlName="isPublic">
54
                            <option [value]="true">Public</option>
55
                            <option [value]="false">Private</option>
56
                          </select>
57
                        </div>
58
                        <div class="uk-width-1-2">
59
                          <select class="uk-select uk-form-small" formControlName="isActive">
60
                            <option [value]="true">Active</option>
61
                            <option [value]="false">Inactive</option>
62
                          </select>
63
                        </div>
64
                      </div>
65
                      <hr>
66
                      <div class="uk-grid-small uk-child-width-1-2" uk-grid>
67
                        <div>
68
                          <button class="md-btn md-btn-small"
69
                                  (click)="deleteTopicOpen(this.topicFb.value.name, editTopic, i)">Delete</button>
70
                        </div>
71
                        <div>
72
                          <button class="md-btn md-btn-small md-btn-primary uk-float-right"
73
                                  [class.md-btn-primary]="topicFb.valid && topicFb.dirty"
74
                                  [class.disabled]="topicFb.invalid || !topicFb.dirty"
75
                                  (click)="saveTopic(editTopic, i)">Save
76
                          </button>
77
                        </div>
78
                      </div>
79
                    </div>
80
                  </div>
81
                </div>
82
              </div>
83
            </li>
84
          </ng-template>
85
          <li>
86
            <a href="#" (click)="saveTopicOpen(newTopic); $event.preventDefault()">
87
              <span class="menu_icon"><i class="material-icons">add</i></span>
88
              <span class="menu_title">Create new Topic</span>
89
            </a>
90
            <div uk-drop="mode: none; offset: -2; delay-hide: 0" #newTopic
91
                 class="uk-padding-large uk-padding-remove-vertical uk-padding-remove-right uk-drop">
92
              <div *ngIf="topicFb">
93
                <div class="md-card">
94
                  <div class="md-card-content uk-position-relative">
95
                    <a class="uk-position-top-right">
96
                      <i (click)="hide(newTopic)" class="material-icons">close</i>
97
                    </a>
98
                    <div class="uk-grid-small" uk-grid [formGroup]="topicFb">
99
                      <div class="uk-width-1-1">
100
                        <label class="uk-text-bold">New Topic</label>
101
                        <input class="uk-input uk-form-small" formControlName="name"
102
                               [class.uk-form-danger]="topicFb.get('name').dirty && topicFb.get('name').invalid"
103
                               type="text">
104
                      </div>
105
                      <div class="uk-width-1-1">
106
                        <label>Description</label>
107
                        <textarea class="uk-textarea" formControlName="description"
108
                                  rows="3" type="text"></textarea>
109
                      </div>
110
                      <div class="uk-width-1-2">
111
                        <select class="uk-select uk-form-small" formControlName="isPublic">
112
                          <option [value]="true">Public</option>
113
                          <option [value]="false">Private</option>
114
                        </select>
115
                      </div>
116
                      <div class="uk-width-1-2">
117
                        <select class="uk-select uk-form-small" formControlName="isActive">
118
                          <option [value]="true">Active</option>
119
                          <option [value]="false">Inactive</option>
120
                        </select>
121
                      </div>
122
                    </div>
123
                    <hr>
124
                    <div class="uk-grid-small uk-child-width-1-2" uk-grid>
125
                      <div>
126
                        <button class="md-btn md-btn-small" (click)="hide(newTopic)">Cancel</button>
127
                      </div>
128
                      <div>
129
                        <button class="md-btn md-btn-small uk-float-right"
130
                                [class.md-btn-primary]="topicFb.valid && topicFb.dirty"
131
                                [class.disabled]="topicFb.invalid || !topicFb.dirty"
132
                                (click)="saveTopic(newTopic)">
133
                          Create
134
                        </button>
135
                      </div>
136
                    </div>
137
                  </div>
138
                </div>
139
              </div>
140
            </div>
141
          </li>
142
        </ul>
143
      </li>
144
    </ul>
145
  </div>
146
</aside>
147
<div id="page_content" click-outside-or-esc targetId="page_content" [escClose]="false" (clickOutside)="toggleOpen($event)">
148
  <div id="page_content_inner">
149
    <h4 class="uk-text-bold">
150
      Customise your Monitor Dashboard!
151
    </h4>
152
    <div class="uk-text-large uk-margin-bottom">
153
      <div>
154
        Modify or add new topics, categories and content.<br><br>
155
        Start your navigation through the <span class="md-color-blue-900">left side menu!</span>
156
      </div>
157
      <div class="uk-margin-small-top uk-margin-small-bottom uk-margin-large-left">
158
        <svg xmlns="http://www.w3.org/2000/svg" width="30" height="88" viewBox="0 0 30 88">
159
          <g id="Group_749" data-name="Group 749" transform="translate(-872.168 -490.5)">
160
            <text class="fill_text" id="OR" transform="translate(872.168 540.271)" font-size="18"
161
                  font-family="OpenSans-Bold, Open Sans" font-weight="900" opacity="0.8">
162
              <tspan x="0" y="0">OR</tspan>
163
            </text>
164
            <line class="stroke_line" id="Line_225" data-name="Line 225" y2="30" transform="translate(885.5 490.5)"
165
                  fill="none" stroke="#000" stroke-width="1" opacity="0.2"/>
166
            <line class="stroke_line" id="Line_226" data-name="Line 226" y2="30" transform="translate(885.5 548.5)"
167
                  fill="none" stroke="#000" stroke-width="1" opacity="0.2"/>
168
          </g>
169
        </svg>
170
      </div>
171
      <div class="uk-width-1-1">
172
        Select one of the <span class="md-color-blue-900">topics below</span>!
173
      </div>
174
    </div>
175
    <div *ngIf="stakeholder" class="uk-child-width-1-3@m uk-child-width-1-1@s uk-grid-match uk-grid-medium" uk-grid>
176
      <ng-template ngFor [ngForOf]="stakeholder.topics" let-topic>
177
        <div>
178
          <a [routerLink]="topic.alias" class="md-card">
179
            <div class="md-card-content">
180
              <h6 class="uk-text-bold">{{topic.name}}</h6>
181
              <div class="uk-text-secondary">
182
                {{topic.description}}
183
              </div>
184
            </div>
185
          </a>
186
        </div>
187
      </ng-template>
188
    </div>
189
  </div>
190
</div>
191
<modal-alert #deleteTopicModal (alertOutput)="deleteTopic()"></modal-alert>
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/home/home.component.ts
1
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
2
import {ActivatedRoute, Router} from '@angular/router';
3
import {Title} from '@angular/platform-browser';
4
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
5

  
6
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
7
import {ErrorMessagesComponent} from '../openaireLibrary/utils/errorMessages.component';
8
import {Stakeholder, Topic} from "../utils/entities/stakeholder";
9
import {StakeholderService} from "../services/stakeholder.service";
10
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
11
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
12
import {Subscriber} from "rxjs";
13
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
14
import {LayoutService} from "../library/sharedComponents/sidebar/layout.service";
15

  
16
declare var UIkit;
17

  
18
@Component({
19
  selector: 'home',
20
  templateUrl: './home.component.html',
21
})
22
export class HomeComponent implements OnInit, OnDestroy {
23
  public subscriptions: any[] = [];
24
  public loading: boolean = true;
25
  public errorCodes: ErrorCodes;
26
  public stakeholder: Stakeholder;
27
  public analysisOpen: boolean = true;
28
  private errorMessages: ErrorMessagesComponent;
29
  public topicFb: FormGroup;
30
  public element: any;
31
  public index: number;
32
  properties: EnvProperties;
33

  
34
  @ViewChild('deleteTopicModal') deleteTopicModal: AlertModal;
35

  
36
  constructor(
37
    private route: ActivatedRoute,
38
    private router: Router,
39
    private title: Title,
40
    private layoutService: LayoutService,
41
    private fb: FormBuilder,
42
    private stakeholderService: StakeholderService) {
43
    this.errorCodes = new ErrorCodes();
44
    this.errorMessages = new ErrorMessagesComponent();
45
  }
46

  
47
  public ngOnInit() {
48
    this.route.data
49
      .subscribe((data: { envSpecific: EnvProperties }) => {
50
        this.properties = data.envSpecific;
51
        this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
52
          if (stakeholder) {
53
            this.stakeholder = HelperFunctions.copy(stakeholder);
54
            this.topicFb = null;
55
            this.title.setTitle(stakeholder.index_name);
56
          }
57
        }));
58
      });
59
  }
60

  
61
  public ngOnDestroy() {
62
    this.subscriptions.forEach(value => {
63
      if (value instanceof Subscriber) {
64
        value.unsubscribe();
65
      }
66
    });
67
  }
68

  
69
  public show(element) {
70
    UIkit.drop(element).show();
71
  }
72

  
73
  public hide(element) {
74
    UIkit.drop(element).hide();
75
  }
76

  
77
  get open(): boolean {
78
    return this.layoutService.open;
79
  }
80

  
81
  public toggleOpen(event = null) {
82
    if (!event) {
83
      this.layoutService.setOpen(!this.open);
84
    } else if (event && event['value'] === true) {
85
      this.layoutService.setOpen(false);
86
    }
87
  }
88

  
89
  private buildTopic(topic: Topic) {
90
    this.topicFb = this.fb.group({
91
      _id: this.fb.control(topic._id),
92
      name: this.fb.control(topic.name, Validators.required),
93
      description: this.fb.control(topic.description),
94
      alias: this.fb.control(topic.alias),
95
      isActive: this.fb.control(topic.isActive),
96
      isPublic: this.fb.control(topic.isPublic),
97
      isDefault: this.fb.control(topic.isDefault),
98
      categories: this.fb.control(topic.categories)
99
    });
100
  }
101

  
102
  public saveTopicOpen(element, index = -1) {
103
    if (element.className.indexOf('uk-open') !== -1) {
104
      this.hide(element);
105
    } else {
106
      if (index === -1) {
107
        this.buildTopic(new Topic(null, null, null, true, true, false));
108
      } else {
109
        this.buildTopic(this.stakeholder.topics[index]);
110
      }
111
      this.show(element);
112
    }
113
  }
114

  
115
  public saveTopic(element, index = -1) {
116
    if (!this.topicFb.invalid) {
117
      if (!this.topicFb.value.alias) {
118
        this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
119
      }
120
      if (index === -1) {
121
        this.save('Topic has been successfully created', element);
122
      } else {
123
        this.save('Topic has been successfully saved', element, index);
124
      }
125
    }
126
  }
127

  
128
  public deleteTopicOpen(name: string, element, index: number) {
129
    this.element = element;
130
    this.index = index;
131
    this.deleteTopicModal.alertTitle = 'Delete ' + name;
132
    this.deleteTopicModal.cancelButtonText = 'No';
133
    this.deleteTopicModal.okButtonText = 'Yes';
134
    this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?';
135
    this.deleteTopicModal.open();
136
  }
137

  
138
  private save(message: string, element, index: number = -1) {
139
    let path = [this.stakeholder._id];
140
    this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.topicFb.value, path).subscribe(topic => {
141
      if (index === -1) {
142
        this.stakeholder.topics.push(topic);
143
      } else {
144
        this.stakeholder.topics[index] = topic;
145
      }
146
      this.stakeholderService.setStakeholder(this.stakeholder);
147
      UIkit.notification(message, {
148
        status: 'success',
149
        timeout: 3000000,
150
        pos: 'top-left'
151
      });
152
      this.hide(element);
153
    }, error => {
154
      UIkit.notification(error.error.message, {
155
        status: 'danger',
156
        timeout: 3000,
157
        pos: 'top-left'
158
      });
159
      this.hide(element);
160
    });
161
  }
162

  
163
  deleteTopic() {
164
    let path = [
165
      this.stakeholder._id,
166
      this.stakeholder.topics[this.index]._id
167
    ];
168
    this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => {
169
      this.stakeholder.topics.splice(this.index, 1);
170
      this.stakeholderService.setStakeholder(this.stakeholder);
171
      UIkit.notification('Topic has been successfully deleted', {
172
        status: 'success',
173
        timeout: 3000,
174
        pos: 'top-left'
175
      });
176
      this.hide(this.element);
177
    }, error => {
178
      UIkit.notification(error.error.message, {
179
        status: 'danger',
180
        timeout: 3000,
181
        pos: 'top-left'
182
      });
183
      this.hide(this.element);
184
    });
185
  }
186
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/home/home.module.ts
1
import {NgModule} from '@angular/core';
2
import {CommonModule} from '@angular/common';
3

  
4
import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard';
5
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
6

  
7
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
8
import {HomeComponent} from "./home.component";
9
import {HomeRoutingModule} from "./home-routing.module";
10
import {ModalModule} from "../openaireLibrary/utils/modal/modal.module";
11
import {RouterModule} from "@angular/router";
12
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
13
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
14

  
15
@NgModule({
16
  imports: [
17
    CommonModule, HomeRoutingModule, ModalModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule
18
  ],
19
  declarations: [
20
    HomeComponent
21
  ],
22
  providers: [
23
    FreeGuard, PreviousRouteRecorder,
24
    PiwikService
25
  ],
26
  exports: [
27
    HomeComponent
28
  ]
29
})
30
export class HomeModule {
31
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/utils/indicator-utils.ts
44 44
    ['other', 'perm_media']
45 45
  ]);
46 46

  
47
  chartTypesIconsClasses: Map<string, string> = new Map([
48
    ['bar', 'rotate-90']
49
  ]);
50

  
47 51
  isPublicIcon: Map<boolean, string> = new Map([
48 52
    [true, 'public'],
49 53
    [false, 'lock']
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/library/sharedComponents/input/input.component.ts
1 1
import {Component, Input, OnDestroy, OnInit} from "@angular/core";
2 2
import {Option} from "../../../utils/indicator-utils";
3
import {AbstractControl, FormControl} from "@angular/forms";
4 3

  
5 4
@Component({
6 5
  selector: '[dashboard-input]',
......
9 8
      <input *ngIf="type === 'text'" matInput [placeholder]="label"
10 9
             [formControl]="formControl" [required]="required">
11 10
      <textarea *ngIf="type === 'textarea'" [rows]="rows" matInput [placeholder]="label" [formControl]="formControl"></textarea>
12
      <mat-select *ngIf="type === 'select'" [placeholder]="label"  [formControl]="formControl" [disableOptionCentering]="true">
11
      <mat-select *ngIf="type === 'select'" [placeholder]="label" (openedChange)="stopPropagation()"
12
                  [formControl]="formControl" [disableOptionCentering]="true">
13 13
        <mat-option *ngFor="let option of options" [value]="option.value">
14 14
          {{option.label}}
15 15
        </mat-option>
......
18 18
  `
19 19
})
20 20
export class InputComponent implements OnInit, OnDestroy {
21
  @Input('formInput') formControl: FormControl;
21
  @Input('formInput') formControl: any;
22 22
  @Input('type') type: string = 'text';
23 23
  @Input('label') label: string;
24 24
  @Input('rows') rows: number = 3;
......
38 38
      && this.formControl.validator(this.formControl)
39 39
      && this.formControl.validator(this.formControl).required;
40 40
  }
41

  
42
  stopPropagation() {
43
    if(event) {
44
      event.stopPropagation();
45
    }
46
  }
41 47
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/stakeholder/stakeholder-routing.module.ts
1
import {NgModule} from '@angular/core';
2
import {RouterModule} from '@angular/router';
3
import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard';
4
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
5
import {StakeholderComponent} from "./stakeholder.component";
6

  
7
@NgModule({
8
  imports: [
9
    RouterModule.forChild([
10
      {
11
        path: '',
12
        component: StakeholderComponent,
13
        canActivate: [FreeGuard],
14
        canDeactivate: [PreviousRouteRecorder]
15
      }
16
    ])
17
  ]
18
})
19
export class StakeholderRoutingModule {
20
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/stakeholder/stakeholder.component.html
1
<aside id="sidebar_main">
2
  <div *ngIf="stakeholder" class="sidebar_main_header">
3
    <div class="uk-padding-small">
4
      <img class="uk-margin-bottom" *ngIf="stakeholder.logoUrl" [src]="stakeholder.logoUrl">
5
      <h4 class="uk-text-bold uk-margin-remove">{{stakeholder.index_name}}</h4>
6
      <span class="uk-text-large">Admin Dashboard</span>
7
    </div>
8
  </div>
9
  <div *ngIf="stakeholder" class="menu_section">
10
    <ul>
11
      <li [class.current_section]="analysisOpen"
12
          [class.act_section]="analysisOpen"
13
          class="submenu_trigger">
14
        <a href="#" (click)="analysisOpen = !analysisOpen; $event.preventDefault()">
15
          <span class="menu_icon"><i class="material-icons">donut_large</i></span>
16
          <span class="menu_title">Analysis Indicators</span>
17
        </a>
18
        <ul [style.display]="(analysisOpen?'block':'none')">
19
          <ng-template ngFor [ngForOf]="stakeholder.topics" let-topic let-i="index">
20
            <li>
21
              <a [routerLink]="topic.alias">
22
                <span *ngIf="topic.icon" class="menu_icon uk-margin-small-right"><i
23
                  class="material-icons">{{topic.icon}}</i></span>
24
                <div class="menu_title uk-inline">
25
                  {{topic.name}}
26
                  <button class="uk-position-center-right-out uk-margin-right uk-button uk-button-link onHover"
27
                          (click)="$event.stopPropagation();saveTopicOpen(editTopic, i); $event.preventDefault()">
28
                    <i class="material-icons">more_horiz</i>
29
                  </button>
30
                </div>
31
              </a>
32
              <div uk-drop="mode: none; offset: -2; delay-hide: 0; flip: false" #editTopic
33
                   class="uk-padding-large uk-padding-remove-vertical uk-padding-remove-right uk-drop">
34
                <div *ngIf="topicFb">
35
                  <div class="md-card">
36
                    <div class="md-card-content uk-position-relative">
37
                      <a class="uk-position-top-right">
38
                        <i (click)="hide(editTopic)" class="material-icons">close</i>
39
                      </a>
40
                      <div class="uk-grid-small" uk-grid [formGroup]="topicFb">
41
                        <div class="uk-width-1-1">
42
                          <label class="uk-text-bold">Topic Settings</label>
43
                          <input class="uk-input uk-form-small" formControlName="name"
44
                                 [class.uk-form-danger]="topicFb.get('name').dirty && topicFb.get('name').invalid"
45
                                 type="text">
46
                        </div>
47
                        <div class="uk-width-1-1">
48
                          <label>Description</label>
49
                          <textarea class="uk-textarea" formControlName="description"
50
                                    rows="3" type="text"></textarea>
51
                        </div>
52
                        <div dashboard-input [type]="'select'"
53
                             [formInput]="topicFb.get('isPublic')" [options]="indicatorUtils.isPublic"
54
                             label="Privacy" class="uk-width-1-2">
55
                        </div>
56
                        <div dashboard-input [type]="'select'"
57
                             [formInput]="topicFb.get('isActive')" [options]="indicatorUtils.isActive"
58
                             label="Status" class="uk-width-1-2">
59
                        </div>
60
                      </div>
61
                      <hr>
62
                      <div class="uk-grid-small uk-child-width-1-2" uk-grid>
63
                        <div>
64
                          <button class="md-btn md-btn-small"
65
                                  (click)="deleteTopicOpen(this.topicFb.value.name, editTopic, i)">Delete</button>
66
                        </div>
67
                        <div>
68
                          <button class="md-btn md-btn-small md-btn-primary uk-float-right"
69
                                  [class.md-btn-primary]="topicFb.valid && topicFb.dirty"
70
                                  [class.disabled]="topicFb.invalid || !topicFb.dirty"
71
                                  (click)="saveTopic(editTopic, i)">Save
72
                          </button>
73
                        </div>
74
                      </div>
75
                    </div>
76
                  </div>
77
                </div>
78
              </div>
79
            </li>
80
          </ng-template>
81
          <li>
82
            <a href="#" (click)="saveTopicOpen(newTopic); $event.preventDefault()">
83
              <span class="menu_icon"><i class="material-icons">add</i></span>
84
              <span class="menu_title">Create new Topic</span>
85
            </a>
86
            <div uk-drop="mode: none; offset: -2; delay-hide: 0" #newTopic
87
                 class="uk-padding-large uk-padding-remove-vertical uk-padding-remove-right uk-drop">
88
              <div *ngIf="topicFb">
89
                <div class="md-card">
90
                  <div class="md-card-content uk-position-relative">
91
                    <a class="uk-position-top-right">
92
                      <i (click)="hide(newTopic)" class="material-icons">close</i>
93
                    </a>
94
                    <div class="uk-grid-small" uk-grid [formGroup]="topicFb">
95
                      <div class="uk-width-1-1">
96
                        <label class="uk-text-bold">New Topic</label>
97
                        <input class="uk-input uk-form-small" formControlName="name"
98
                               [class.uk-form-danger]="topicFb.get('name').dirty && topicFb.get('name').invalid"
99
                               type="text">
100
                      </div>
101
                      <div class="uk-width-1-1">
102
                        <label>Description</label>
103
                        <textarea class="uk-textarea" formControlName="description"
104
                                  rows="3" type="text"></textarea>
105
                      </div>
106
                      <div dashboard-input [type]="'select'"
107
                           [formInput]="topicFb.get('isPublic')" [options]="indicatorUtils.isPublic"
108
                           label="Privacy" class="uk-width-1-2">
109
                      </div>
110
                      <div dashboard-input [type]="'select'"
111
                           [formInput]="topicFb.get('isActive')" [options]="indicatorUtils.isActive"
112
                           label="Status" class="uk-width-1-2">
113
                      </div>
114
                    </div>
115
                    <hr>
116
                    <div class="uk-grid-small uk-child-width-1-2" uk-grid>
117
                      <div>
118
                        <button class="md-btn md-btn-small" (click)="hide(newTopic)">Cancel</button>
119
                      </div>
120
                      <div>
121
                        <button class="md-btn md-btn-small uk-float-right"
122
                                [class.md-btn-primary]="topicFb.valid && topicFb.dirty"
123
                                [class.disabled]="topicFb.invalid || !topicFb.dirty"
124
                                (click)="saveTopic(newTopic)">
125
                          Create
126
                        </button>
127
                      </div>
128
                    </div>
129
                  </div>
130
                </div>
131
              </div>
132
            </div>
133
          </li>
134
        </ul>
135
      </li>
136
    </ul>
137
  </div>
138
</aside>
139
<div id="page_content" click-outside-or-esc targetId="page_content" [escClose]="false" (clickOutside)="toggleOpen($event)">
140
  <div id="page_content_inner">
141
    <h4 class="uk-text-bold">
142
      Customise your Monitor Dashboard!
143
    </h4>
144
    <div class="uk-text-large uk-margin-bottom">
145
      <div>
146
        Modify or add new topics, categories and content.<br><br>
147
        Start your navigation through the <span class="md-color-blue-900">left side menu!</span>
148
      </div>
149
      <div class="uk-margin-small-top uk-margin-small-bottom uk-margin-large-left">
150
        <svg xmlns="http://www.w3.org/2000/svg" width="30" height="88" viewBox="0 0 30 88">
151
          <g id="Group_749" data-name="Group 749" transform="translate(-872.168 -490.5)">
152
            <text class="fill_text" id="OR" transform="translate(872.168 540.271)" font-size="18"
153
                  font-family="OpenSans-Bold, Open Sans" font-weight="900" opacity="0.8">
154
              <tspan x="0" y="0">OR</tspan>
155
            </text>
156
            <line class="stroke_line" id="Line_225" data-name="Line 225" y2="30" transform="translate(885.5 490.5)"
157
                  fill="none" stroke="#000" stroke-width="1" opacity="0.2"/>
158
            <line class="stroke_line" id="Line_226" data-name="Line 226" y2="30" transform="translate(885.5 548.5)"
159
                  fill="none" stroke="#000" stroke-width="1" opacity="0.2"/>
160
          </g>
161
        </svg>
162
      </div>
163
      <div class="uk-width-1-1">
164
        Select one of the <span class="md-color-blue-900">topics below</span>!
165
      </div>
166
    </div>
167
    <div *ngIf="stakeholder" class="uk-child-width-1-3@m uk-child-width-1-1@s uk-grid-match uk-grid-medium" uk-grid>
168
      <ng-template ngFor [ngForOf]="stakeholder.topics" let-topic>
169
        <div>
170
          <a [routerLink]="topic.alias" class="md-card">
171
            <div class="md-card-content">
172
              <h6 class="uk-text-bold">{{topic.name}}</h6>
173
              <div class="uk-text-secondary">
174
                {{topic.description}}
175
              </div>
176
            </div>
177
          </a>
178
        </div>
179
      </ng-template>
180
    </div>
181
  </div>
182
</div>
183
<modal-alert #deleteTopicModal (alertOutput)="deleteTopic()"></modal-alert>
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/stakeholder/stakeholder.component.ts
1
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
2
import {ActivatedRoute, Router} from '@angular/router';
3
import {Title} from '@angular/platform-browser';
4
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
5

  
6
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
7
import {ErrorMessagesComponent} from '../openaireLibrary/utils/errorMessages.component';
8
import {Stakeholder, Topic} from "../utils/entities/stakeholder";
9
import {StakeholderService} from "../services/stakeholder.service";
10
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
11
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
12
import {Subscriber} from "rxjs";
13
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
14
import {LayoutService} from "../library/sharedComponents/sidebar/layout.service";
15
import {IndicatorUtils} from "../utils/indicator-utils";
16

  
17
declare var UIkit;
18

  
19
@Component({
20
  selector: 'stakeholder',
21
  templateUrl: './stakeholder.component.html',
22
})
23
export class StakeholderComponent implements OnInit, OnDestroy {
24
  public subscriptions: any[] = [];
25
  public loading: boolean = true;
26
  public errorCodes: ErrorCodes;
27
  public stakeholder: Stakeholder;
28
  public analysisOpen: boolean = true;
29
  private errorMessages: ErrorMessagesComponent;
30
  public topicFb: FormGroup;
31
  public indicatorUtils: IndicatorUtils = new IndicatorUtils();
32
  public element: any;
33
  public index: number;
34
  properties: EnvProperties;
35

  
36
  @ViewChild('deleteTopicModal') deleteTopicModal: AlertModal;
37

  
38
  constructor(
39
    private route: ActivatedRoute,
40
    private router: Router,
41
    private title: Title,
42
    private layoutService: LayoutService,
43
    private fb: FormBuilder,
44
    private stakeholderService: StakeholderService) {
45
    this.errorCodes = new ErrorCodes();
46
    this.errorMessages = new ErrorMessagesComponent();
47
  }
48

  
49
  public ngOnInit() {
50
    this.route.data
51
      .subscribe((data: { envSpecific: EnvProperties }) => {
52
        this.properties = data.envSpecific;
53
        this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
54
          if (stakeholder) {
55
            this.stakeholder = HelperFunctions.copy(stakeholder);
56
            this.topicFb = null;
57
            this.title.setTitle(stakeholder.index_name);
58
          }
59
        }));
60
      });
61
  }
62

  
63
  public ngOnDestroy() {
64
    this.subscriptions.forEach(value => {
65
      if (value instanceof Subscriber) {
66
        value.unsubscribe();
67
      }
68
    });
69
  }
70

  
71
  public show(element) {
72
    UIkit.drop(element).show();
73
  }
74

  
75
  public hide(element) {
76
    UIkit.drop(element).hide();
77
  }
78

  
79
  get open(): boolean {
80
    return this.layoutService.open;
81
  }
82

  
83
  public toggleOpen(event = null) {
84
    if (!event) {
85
      this.layoutService.setOpen(!this.open);
86
    } else if (event && event['value'] === true) {
87
      this.layoutService.setOpen(false);
88
    }
89
  }
90

  
91
  private buildTopic(topic: Topic) {
92
    this.topicFb = this.fb.group({
93
      _id: this.fb.control(topic._id),
94
      name: this.fb.control(topic.name, Validators.required),
95
      description: this.fb.control(topic.description),
96
      alias: this.fb.control(topic.alias),
97
      isActive: this.fb.control(topic.isActive),
98
      isPublic: this.fb.control(topic.isPublic),
99
      isDefault: this.fb.control(topic.isDefault),
100
      categories: this.fb.control(topic.categories)
101
    });
102
  }
103

  
104
  public saveTopicOpen(element, index = -1) {
105
    if (element.className.indexOf('uk-open') !== -1) {
106
      this.hide(element);
107
    } else {
108
      if (index === -1) {
109
        this.buildTopic(new Topic(null, null, null, true, true, false));
110
      } else {
111
        this.buildTopic(this.stakeholder.topics[index]);
112
      }
113
      this.show(element);
114
    }
115
  }
116

  
117
  public saveTopic(element, index = -1) {
118
    if (!this.topicFb.invalid) {
119
      if (!this.topicFb.value.alias) {
120
        this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
121
      }
122
      if (index === -1) {
123
        this.save('Topic has been successfully created', element);
124
      } else {
125
        this.save('Topic has been successfully saved', element, index);
126
      }
127
    }
128
  }
129

  
130
  public deleteTopicOpen(name: string, element, index: number) {
131
    this.element = element;
132
    this.index = index;
133
    this.deleteTopicModal.alertTitle = 'Delete ' + name;
134
    this.deleteTopicModal.cancelButtonText = 'No';
135
    this.deleteTopicModal.okButtonText = 'Yes';
136
    this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?';
137
    this.deleteTopicModal.open();
138
  }
139

  
140
  private save(message: string, element, index: number = -1) {
141
    let path = [this.stakeholder._id];
142
    this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.topicFb.value, path).subscribe(topic => {
143
      if (index === -1) {
144
        this.stakeholder.topics.push(topic);
145
      } else {
146
        this.stakeholder.topics[index] = topic;
147
      }
148
      this.stakeholderService.setStakeholder(this.stakeholder);
149
      UIkit.notification(message, {
150
        status: 'success',
151
        timeout: 3000000,
152
        pos: 'top-left'
153
      });
154
      this.hide(element);
155
    }, error => {
156
      UIkit.notification(error.error.message, {
157
        status: 'danger',
158
        timeout: 3000,
159
        pos: 'top-left'
160
      });
161
      this.hide(element);
162
    });
163
  }
164

  
165
  deleteTopic() {
166
    let path = [
167
      this.stakeholder._id,
168
      this.stakeholder.topics[this.index]._id
169
    ];
170
    this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => {
171
      this.stakeholder.topics.splice(this.index, 1);
172
      this.stakeholderService.setStakeholder(this.stakeholder);
173
      UIkit.notification('Topic has been successfully deleted', {
174
        status: 'success',
175
        timeout: 3000,
176
        pos: 'top-left'
177
      });
178
      this.hide(this.element);
179
    }, error => {
180
      UIkit.notification(error.error.message, {
181
        status: 'danger',
182
        timeout: 3000,
183
        pos: 'top-left'
184
      });
185
      this.hide(this.element);
186
    });
187
  }
188
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/stakeholder/stakeholder.module.ts
1
import {NgModule} from '@angular/core';
2
import {CommonModule} from '@angular/common';
3

  
4
import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard';
5
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
6

  
7
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
8
import {ModalModule} from "../openaireLibrary/utils/modal/modal.module";
9
import {RouterModule} from "@angular/router";
10
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
11
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
12
import {StakeholderComponent} from "./stakeholder.component";
13
import {StakeholderRoutingModule} from "./stakeholder-routing.module";
14
import {InputModule} from "../library/sharedComponents/input/input.module";
15

  
16
@NgModule({
17
  imports: [
18
    CommonModule, StakeholderRoutingModule, ModalModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, InputModule
19
  ],
20
  declarations: [
21
    StakeholderComponent
22
  ],
23
  providers: [
24
    FreeGuard, PreviousRouteRecorder,
25
    PiwikService
26
  ],
27
  exports: [
28
    StakeholderComponent
29
  ]
30
})
31
export class StakeholderModule {
32
}
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/topic/topic.component.html
39 39
                    <textarea class="uk-textarea" formControlName="description"
40 40
                              rows="3" type="text"></textarea>
41 41
                  </div>
42
                  <div class="uk-width-1-2">
43
                    <select class="uk-select uk-form-small" formControlName="isPublic">
44
                      <option [value]="true">Public</option>
45
                      <option [value]="false">Private</option>
46
                    </select>
42
                  <div dashboard-input [type]="'select'"
43
                       [formInput]="topicFb.get('isPublic')" [options]="indicatorUtils.isPublic"
44
                       label="Privacy" class="uk-width-1-2">
47 45
                  </div>
48
                  <div class="uk-width-1-2">
49
                    <select class="uk-select uk-form-small" formControlName="isActive">
50
                      <option [value]="true">Active</option>
51
                      <option [value]="false">Inactive</option>
52
                    </select>
46
                  <div dashboard-input [type]="'select'"
47
                       [formInput]="topicFb.get('isActive')" [options]="indicatorUtils.isActive"
48
                       label="Status" class="uk-width-1-2">
53 49
                  </div>
54 50
                </div>
55 51
                <hr>
......
102 98
                             [class.uk-form-danger]="categoryFb.get('name').dirty && categoryFb.get('name').invalid"
103 99
                             type="text">
104 100
                    </div>
105
                    <div class="uk-width-1-2">
106
                      <select class="uk-select uk-form-small" formControlName="isPublic">
107
                        <option [value]="true">Public</option>
108
                        <option [value]="false">Private</option>
109
                      </select>
101
                    <div dashboard-input [type]="'select'"
102
                         [formInput]="categoryFb.get('isPublic')" [options]="indicatorUtils.isPublic"
103
                         label="Privacy" class="uk-width-1-2">
110 104
                    </div>
111
                    <div class="uk-width-1-2">
112
                      <select class="uk-select uk-form-small" formControlName="isActive">
113
                        <option [value]="true">Active</option>
114
                        <option [value]="false">Inactive</option>
115
                      </select>
105
                    <div dashboard-input [type]="'select'"
106
                         [formInput]="categoryFb.get('isActive')" [options]="indicatorUtils.isActive"
107
                         label="Status" class="uk-width-1-2">
116 108
                    </div>
117 109
                  </div>
118 110
                  <hr>
......
164 156
                                   [class.uk-form-danger]="subcategoryFb.get('name').dirty && subcategoryFb.get('name').invalid"
165 157
                                   type="text">
166 158
                          </div>
167
                          <div class="uk-width-1-2">
168
                            <select class="uk-select uk-form-small" formControlName="isPublic">
169
                              <option [value]="true">Public</option>
170
                              <option [value]="false">Private</option>
171
                            </select>
159
                          <div dashboard-input [type]="'select'"
160
                               [formInput]="subcategoryFb.get('isPublic')" [options]="indicatorUtils.isPublic"
161
                               label="Privacy" class="uk-width-1-2">
172 162
                          </div>
173
                          <div class="uk-width-1-2">
174
                            <select class="uk-select uk-form-small" formControlName="isActive">
175
                              <option [value]="true">Active</option>
176
                              <option [value]="false">Inactive</option>
177
                            </select>
163
                          <div dashboard-input [type]="'select'"
164
                               [formInput]="subcategoryFb.get('isActive')" [options]="indicatorUtils.isActive"
165
                               label="Status" class="uk-width-1-2">
178 166
                          </div>
179 167
                        </div>
180 168
                        <hr>
......
218 206
                                 [class.uk-form-danger]="subcategoryFb.get('name').dirty && subcategoryFb.get('name').invalid"
219 207
                                 type="text">
220 208
                        </div>
221
                        <div class="uk-width-1-2">
222
                          <select class="uk-select uk-form-small" formControlName="isPublic">
223
                            <option [value]="true">Public</option>
224
                            <option [value]="false">Private</option>
225
                          </select>
209
                        <div dashboard-input [type]="'select'"
210
                             [formInput]="subcategoryFb.get('isPublic')" [options]="indicatorUtils.isPublic"
211
                             label="Privacy" class="uk-width-1-2">
226 212
                        </div>
227
                        <div class="uk-width-1-2">
228
                          <select class="uk-select uk-form-small" formControlName="isActive">
229
                            <option [value]="true">Active</option>
230
                            <option [value]="false">Inactive</option>
231
                          </select>
213
                        <div dashboard-input [type]="'select'"
214
                             [formInput]="subcategoryFb.get('isActive')" [options]="indicatorUtils.isActive"
215
                             label="Status" class="uk-width-1-2">
232 216
                        </div>
233 217
                      </div>
234 218
                      <hr>
......
272 256
                           [class.uk-form-danger]="categoryFb.get('name').dirty && categoryFb.get('name').invalid"
273 257
                           type="text">
274 258
                  </div>
275
                  <div class="uk-width-1-2">
276
                    <select class="uk-select uk-form-small" formControlName="isPublic">
277
                      <option [value]="true">Public</option>
278
                      <option [value]="false">Private</option>
279
                    </select>
259
                  <div dashboard-input [type]="'select'"
260
                       [formInput]="categoryFb.get('isPublic')" [options]="indicatorUtils.isPublic"
261
                       label="Privacy" class="uk-width-1-2">
280 262
                  </div>
281
                  <div class="uk-width-1-2">
282
                    <select class="uk-select uk-form-small" formControlName="isActive">
283
                      <option [value]="true">Active</option>
284
                      <option [value]="false">Inactive</option>
285
                    </select>
263
                  <div dashboard-input [type]="'select'"
264
                       [formInput]="categoryFb.get('isActive')" [options]="indicatorUtils.isActive"
265
                       label="Status" class="uk-width-1-2">
286 266
                  </div>
287 267
                </div>
288 268
                <hr>
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/topic/indicators.component.html
119 119
                <ng-template [ngIf]="!grid">
120 120
                  <span *ngFor="let indicatorPath of indicator.indicatorPaths"
121 121
                        class="uk-margin-medium-right uk-text-capitalize uk-flex uk-flex-middle">
122
                    <i class="material-icons md-24 uk-margin-small-right">
122
                    <i class="material-icons md-24 uk-margin-small-right"
123
                       [ngClass]="indicatorUtils.chartTypesIconsClasses.get(indicatorPath.type)">
123 124
                      {{indicatorUtils.chartTypesIcons.get(indicatorPath.type)}}
124 125
                    </i>
125 126
                    {{indicatorPath.type + ' Chart'}}
......
158 159
                <div class="uk-width-1-3 uk-text-center"
159 160
                     [ngClass]="'uk-child-width-1-' + indicator.indicatorPaths.length" uk-grid>
160 161
                  <div *ngFor="let indicatorPath of indicator.indicatorPaths">
161
                    <i class="material-icons md-24">
162
                    <i class="material-icons md-24"
163
                       [ngClass]="indicatorUtils.chartTypesIconsClasses.get(indicatorPath.type)">
162 164
                      {{indicatorUtils.chartTypesIcons.get(indicatorPath.type)}}
163 165
                    </i>
164 166
                    <div class="uk-text-capitalize">{{indicatorPath.type + ' Chart'}}</div>
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/topic/topic.component.ts
8 8
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
9 9
import {Subscriber} from "rxjs";
10 10
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
11
import {IndicatorUtils} from "../utils/indicator-utils";
11 12

  
12 13
declare var UIkit;
13 14

  
......
18 19
export class TopicComponent implements OnInit, OnDestroy {
19 20
  public subscriptions: any[] = [];
20 21
  public properties: EnvProperties;
22
  public indicatorUtils: IndicatorUtils = new IndicatorUtils();
21 23
  public loading: boolean = true;
22 24
  public stakeholder: Stakeholder;
23 25
  /**
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/app/app-routing.module.ts
25 25
  },
26 26
  {
27 27
    path: 'admin/:stakeholder',
28
    loadChildren: './home/home.module#HomeModule',
28
    loadChildren: './stakeholder/stakeholder.module#StakeholderModule',
29 29
    resolve: {envSpecific: EnvironmentSpecificResolver}
30 30
  },
31 31
  {
modules/uoa-monitor-portal/trunk/monitor_dashboard/src/assets/monitor-custom.css
28 28
    background-color: rgba(0, 0, 0, 0.50);
29 29
    position: absolute;
30 30
}
31

  
32
.rotate-90 {
33
    transform: rotate(90deg);
34
}

Also available in: Unified diff