1 import { Component, OnInit } from '@angular/core';
2 import { ValidatorFn, Validators } from '@angular/forms';
3 import { Router } from '@angular/router';
5 import _ from 'lodash';
6 import { forkJoin as observableForkJoin } from 'rxjs';
8 import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
9 import { TelemetryService } from '~/app/shared/api/telemetry.service';
10 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
11 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
12 import { CdForm } from '~/app/shared/forms/cd-form';
13 import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
14 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
15 import { NotificationService } from '~/app/shared/services/notification.service';
16 import { TelemetryNotificationService } from '~/app/shared/services/telemetry-notification.service';
19 selector: 'cd-telemetry',
20 templateUrl: './telemetry.component.html',
21 styleUrls: ['./telemetry.component.scss']
23 export class TelemetryComponent extends CdForm implements OnInit {
24 configForm: CdFormGroup;
26 moduleEnabled: boolean;
28 newConfig: Object = {};
29 configResp: object = {};
30 previewForm: CdFormGroup;
43 contactInfofields = ['contact', 'description', 'organization'];
44 report: object = undefined;
45 reportId: number = undefined;
49 showContactInfo: boolean;
52 public actionLabels: ActionLabelsI18n,
53 private formBuilder: CdFormBuilder,
54 private mgrModuleService: MgrModuleService,
55 private notificationService: NotificationService,
56 private router: Router,
57 private telemetryService: TelemetryService,
58 private telemetryNotificationService: TelemetryNotificationService
65 this.mgrModuleService.getOptions('telemetry'),
66 this.mgrModuleService.getConfig('telemetry')
68 observableForkJoin(observables).subscribe(
70 const configResp = resp[1];
71 this.moduleEnabled = configResp['enabled'];
72 this.sendToUrl = configResp['url'];
73 this.sendToDeviceUrl = configResp['device_url'];
74 this.showContactInfo = configResp['channel_ident'];
75 this.options = _.pick(resp[0], this.requiredFields);
76 this.configResp = _.pick(configResp, this.requiredFields);
77 this.createConfigForm();
78 this.configForm.setValue(this.configResp);
87 private createConfigForm() {
88 const controlsConfig = {};
89 _.forEach(Object.values(this.options), (option) => {
90 controlsConfig[option.name] = [option.default_value, this.getValidators(option)];
92 this.configForm = this.formBuilder.group(controlsConfig);
95 private replacer(key: string, value: any) {
96 // Display the arrays of keys 'ranges' and 'values' horizontally as they take up too much space
97 // and Stringify displays it in vertical by default.
98 if ((key === 'ranges' || key === 'values') && Array.isArray(value)) {
100 for (let i = 0; i < value.length; i++) {
101 elements.push(JSON.stringify(value[i]));
105 // Else, just return the value as is, without any formatting.
109 replacerTest(report: object) {
110 return JSON.stringify(report, this.replacer, 2);
113 private formatReport() {
115 copy = JSON.parse(JSON.stringify(this.report));
121 'osd_perf_histograms',
126 for (let i = 0; i < perf_keys.length; i++) {
127 const key = perf_keys[i];
128 if (key in copy['report']) {
129 delete copy['report'][key];
132 return JSON.stringify(copy, null, 2);
135 formatReportTest(report: object) {
137 copy = JSON.parse(JSON.stringify(report));
143 'osd_perf_histograms',
148 for (let i = 0; i < perf_keys.length; i++) {
149 const key = perf_keys[i];
154 return JSON.stringify(copy, null, 2);
157 private createPreviewForm() {
159 report: this.formatReport(),
160 reportId: this.reportId,
161 licenseAgrmt: [this.licenseAgrmt, Validators.requiredTrue]
163 this.previewForm = this.formBuilder.group(controls);
166 private getValidators(option: any): ValidatorFn[] {
168 switch (option.type) {
170 result.push(Validators.required);
173 if (_.isNumber(option.min)) {
174 result.push(Validators.minLength(option.min));
176 if (_.isNumber(option.max)) {
177 result.push(Validators.maxLength(option.max));
184 private updateReportFromConfig(updatedConfig: Object = {}) {
186 const availableChannels: string[] = this.report['report']['channels_available'];
187 const updatedChannels = [];
188 for (const channel of availableChannels) {
189 const key = `channel_${channel}`;
190 if (updatedConfig[key]) {
191 updatedChannels.push(channel);
194 this.report['report']['channels'] = updatedChannels;
195 // update contactInfo
196 for (const contactInfofield of this.contactInfofields) {
197 this.report['report'][contactInfofield] = updatedConfig[contactInfofield];
201 private getReport() {
204 this.telemetryService.getReport().subscribe(
207 this.reportId = resp['report']['report_id'];
208 this.updateReportFromConfig(this.newConfig);
209 this.createPreviewForm();
220 this.showContactInfo = !this.showContactInfo;
225 for (const option of Object.values(this.options)) {
226 const control = this.configForm.get(option.name);
227 // Append the option only if they are valid
229 this.newConfig[option.name] = control.value;
231 this.configForm.setErrors({ cdSubmitButton: true });
235 // reset contact info field if ident channel is off
236 if (!this.newConfig['channel_ident']) {
237 for (const contactInfofield of this.contactInfofields) {
238 this.newConfig[contactInfofield] = '';
244 disableModule(message: string = null, followUpFunc: Function = null) {
245 this.telemetryService.enable(false).subscribe(() => {
246 this.telemetryNotificationService.setVisibility(true);
248 this.notificationService.show(NotificationType.success, message);
253 this.router.navigate(['']);
267 const updatedConfig = {};
268 _.forEach(this.requiredFields, (configField) => {
269 if (!_.isEqual(this.configResp[configField], this.newConfig[configField])) {
270 updatedConfig[configField] = this.newConfig[configField];
273 return updatedConfig;
277 const updatedConfig = this.getChangedConfig();
278 const observables = [
279 this.telemetryService.enable(),
280 this.mgrModuleService.updateConfig('telemetry', updatedConfig)
283 observableForkJoin(observables).subscribe(
285 this.telemetryNotificationService.setVisibility(false);
286 this.notificationService.show(
287 NotificationType.success,
288 $localize`The Telemetry module has been configured and activated successfully.`
292 this.telemetryNotificationService.setVisibility(false);
293 this.notificationService.show(
294 NotificationType.error,
295 $localize`An Error occurred while updating the Telemetry module configuration.\
298 // Reset the 'Update' button.
299 this.previewForm.setErrors({ cdSubmitButton: true });
303 this.router.navigate(['']);