blob: b4ad194bd68a7378bfbed6563bd8ecb2bb4311da [file] [log] [blame]
PatrikBuhra2bc79c2019-10-29 13:39:00 +01001/*-
2 * ========================LICENSE_START=================================
3 * O-RAN-SC
4 * %%
5 * Copyright (C) 2019 Nordix Foundation
6 * %%
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ========================LICENSE_END===================================
19 */
PatrikBuhrdbb8eba2019-11-15 14:12:11 +010020import { animate, state, style, transition, trigger } from '@angular/animations';
21import { AfterViewInit, Component, Inject, OnInit, ViewChild } from '@angular/core';
22import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
PatrikBuhra2bc79c2019-10-29 13:39:00 +010023import { MatMenuTrigger } from '@angular/material/menu';
PatrikBuhra2bc79c2019-10-29 13:39:00 +010024import { JsonPointer } from 'angular6-json-schema-form';
PatrikBuhrdbb8eba2019-11-15 14:12:11 +010025import * as uuid from 'uuid';
26import { PolicyInstance, PolicyType } from '../interfaces/policy.types';
PatrikBuhra2bc79c2019-10-29 13:39:00 +010027import { PolicyService } from '../services/policy/policy.service';
28import { ErrorDialogService } from '../services/ui/error-dialog.service';
29import { NotificationService } from './../services/ui/notification.service';
PatrikBuhrdbb8eba2019-11-15 14:12:11 +010030import { UiService } from '../services/ui/ui.service';
PatrikBuhra2bc79c2019-10-29 13:39:00 +010031
PatrikBuhra2bc79c2019-10-29 13:39:00 +010032
33@Component({
34 selector: 'rd-policy-instance-dialog',
35 templateUrl: './policy-instance-dialog.component.html',
36 styleUrls: ['./policy-instance-dialog.component.scss'],
37 animations: [
38 trigger('expandSection', [
39 state('in', style({ height: '*' })),
40 transition(':enter', [
41 style({ height: 0 }), animate(100),
42 ]),
43 transition(':leave', [
44 style({ height: '*' }),
45 animate(100, style({ height: 0 })),
46 ]),
47 ]),
48 ],
49})
50export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit {
51
52 formActive = false;
53 isVisible = {
54 form: true,
55 json: false,
56 schema: false
57 };
58
59 jsonFormStatusMessage = 'Loading form...';
60 jsonSchemaObject: any = {};
61 jsonObject: any = {};
62
63
64 jsonFormOptions: any = {
65 addSubmit: false, // Add a submit button if layout does not have one
66 debug: false, // Don't show inline debugging information
67 loadExternalAssets: true, // Load external css and JavaScript for frameworks
68 returnEmptyFields: false, // Don't return values for empty input fields
69 setSchemaDefaults: true, // Always use schema defaults for empty fields
70 defautWidgetOptions: { feedback: true }, // Show inline feedback icons
71 };
72
73 liveFormData: any = {};
74 formValidationErrors: any;
75 formIsValid = false;
76
PatrikBuhra2bc79c2019-10-29 13:39:00 +010077 @ViewChild(MatMenuTrigger, { static: true }) menuTrigger: MatMenuTrigger;
78
elinuxhenrikb033eaf2020-02-03 16:02:21 +010079 policyInstanceId: string; // null if not yet created
80 policyTypeName: string;
PatrikBuhrdbb8eba2019-11-15 14:12:11 +010081 darkMode: boolean;
elinuxhenrikb033eaf2020-02-03 16:02:21 +010082 ric: string;
83 allRics: string[];
PatrikBuhra2bc79c2019-10-29 13:39:00 +010084
elinuxhenrikb033eaf2020-02-03 16:02:21 +010085 private fetchRics() {
86 console.log('fetchRics ' + this.policyTypeName);
87 const self: PolicyInstanceDialogComponent = this;
88 this.dataService.getRics(this.policyTypeName).subscribe(
89 {
90 next(value) {
91 self.allRics = value;
92 console.log(value);
93 },
94 error(error) {
95 self.errorService.displayError('Fetching of rics failed: ' + error.message);
96 },
97 complete() { }
98 });
99 }
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100100
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100101 constructor(
102 private dataService: PolicyService,
103 private errorService: ErrorDialogService,
104 private notificationService: NotificationService,
105 @Inject(MAT_DIALOG_DATA) private data,
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100106 private dialogRef: MatDialogRef<PolicyInstanceDialogComponent>,
107 private ui: UiService) {
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100108 this.formActive = false;
PatrikBuhr592589c2019-11-20 15:00:31 +0100109 this.policyInstanceId = data.instanceId;
110 this.policyTypeName = data.name;
PatrikBuhr268acb12019-11-21 16:04:59 +0100111 this.jsonSchemaObject = data.createSchema;
112 this.jsonObject = this.parseJson(data.instanceJson);
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100113 this.ric = data.ric;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100114 }
115
116 ngOnInit() {
117 this.jsonFormStatusMessage = 'Init';
118 this.formActive = true;
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100119 this.ui.darkModeState.subscribe((isDark) => {
120 this.darkMode = isDark;
121 });
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100122 if (!this.policyInstanceId) {
123 this.fetchRics();
124 }
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100125 }
126
127 ngAfterViewInit() {
128 }
129
130 onSubmit() {
131 if (this.policyInstanceId == null) {
132 this.policyInstanceId = uuid.v4();
133 }
134 const policyJson: string = this.prettyLiveFormData;
135 const self: PolicyInstanceDialogComponent = this;
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100136 this.dataService.putPolicy(this.policyTypeName, this.policyInstanceId, policyJson, this.ric).subscribe(
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100137 {
138 next(value) {
139 self.notificationService.success('Policy ' + self.policyTypeName + ':' + self.policyInstanceId + ' submitted');
140 },
141 error(error) {
142 self.errorService.displayError('updatePolicy failed: ' + error.message);
143 },
144 complete() { }
145 });
146 }
147
148 onClose() {
149 this.dialogRef.close();
150 }
151
PatrikBuhr592589c2019-11-20 15:00:31 +0100152 public onChanges(formData: any) {
153 this.liveFormData = formData;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100154 }
155
156 get prettyLiveFormData() {
157 return JSON.stringify(this.liveFormData, null, 2);
158 }
159
160 get schemaAsString() {
161 return JSON.stringify(this.jsonSchemaObject, null, 2);
162 }
163
164 get jsonAsString() {
165 return JSON.stringify(this.jsonObject, null, 2);
166 }
167
168 isValid(isValid: boolean): void {
169 this.formIsValid = isValid;
170 }
171
PatrikBuhr592589c2019-11-20 15:00:31 +0100172 validationErrors(validationErrors: any): void {
173 this.formValidationErrors = validationErrors;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100174 }
175
176 get prettyValidationErrors() {
177 if (!this.formValidationErrors) { return null; }
178 const errorArray = [];
179 for (const error of this.formValidationErrors) {
180 const message = error.message;
181 const dataPathArray = JsonPointer.parse(error.dataPath);
182 if (dataPathArray.length) {
183 let field = dataPathArray[0];
184 for (let i = 1; i < dataPathArray.length; i++) {
185 const key = dataPathArray[i];
186 field += /^\d+$/.test(key) ? `[${key}]` : `.${key}`;
187 }
188 errorArray.push(`${field}: ${message}`);
189 } else {
190 errorArray.push(message);
191 }
192 }
193 return errorArray.join('<br>');
194 }
195
PatrikBuhr268acb12019-11-21 16:04:59 +0100196 private parseJson(str: string): string {
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100197 try {
PatrikBuhr268acb12019-11-21 16:04:59 +0100198 if (str != null) {
199 return JSON.parse(str);
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100200 }
201 } catch (jsonError) {
202 this.jsonFormStatusMessage =
203 'Invalid JSON\n' +
204 'parser returned:\n\n' + jsonError;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100205 }
PatrikBuhr268acb12019-11-21 16:04:59 +0100206 return null;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100207 }
208
209 public toggleVisible(item: string) {
210 this.isVisible[item] = !this.isVisible[item];
211 }
212}
213
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100214export function getPolicyDialogProperties(policyType: PolicyType, instance: PolicyInstance, darkMode: boolean): MatDialogConfig {
PatrikBuhr268acb12019-11-21 16:04:59 +0100215 const createSchema = policyType.schemaObject;
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100216 const instanceId = instance ? instance.id : null;
217 const instanceJson = instance ? instance.json : null;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100218 const name = policyType.name;
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100219 const ric = instance ? instance.ric : null;
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100220 return {
221 maxWidth: '1200px',
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100222 maxHeight: '900px',
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100223 width: '900px',
224 role: 'dialog',
225 disableClose: false,
PatrikBuhrdbb8eba2019-11-15 14:12:11 +0100226 panelClass: darkMode ? 'dark-theme' : '',
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100227 data: {
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100228 createSchema,
229 instanceId,
230 instanceJson,
elinuxhenrikb033eaf2020-02-03 16:02:21 +0100231 name,
232 ric
PatrikBuhra2bc79c2019-10-29 13:39:00 +0100233 }
234 };
235}
236