Frontend CHANGE move yang changes from session to configuration service
diff --git a/frontend/projects/netconf-lib/src/lib/classes/Modification.ts b/frontend/projects/netconf-lib/src/lib/classes/Modification.ts
new file mode 100644
index 0000000..d7954f1
--- /dev/null
+++ b/frontend/projects/netconf-lib/src/lib/classes/Modification.ts
@@ -0,0 +1,14 @@
+/**
+ * Author: Jakub Man <xmanja00@stud.fit.vutbr.cz>
+ * A single modification
+ */
+import {ModificationType} from './ModificationType';
+
+export class Modification {
+ [path: string]: {
+ type: ModificationType;
+ original: any; // Original value before modification
+ value: any; // A new value
+ data: object; // The node data
+ }
+}
diff --git a/frontend/projects/netconf-lib/src/lib/classes/ModificationType.ts b/frontend/projects/netconf-lib/src/lib/classes/ModificationType.ts
index ee3ef16..84d1289 100644
--- a/frontend/projects/netconf-lib/src/lib/classes/ModificationType.ts
+++ b/frontend/projects/netconf-lib/src/lib/classes/ModificationType.ts
@@ -4,14 +4,14 @@
*/
export const enum ModificationType {
/** Creating a new node */
- Create = "create",
+ Create = 'create',
/** Changing value of a current leaf node */
- Change = "change",
+ Change = 'change',
/** Delete a current node */
- Delete = "delete",
+ Delete = 'delete',
/** Replacing a current node */
- Replace = "replace",
+ Replace = 'replace',
/** Reordering user-ordered lists or leaf-lists */
- Reorder = "reorder"
+ Reorder = 'reorder'
}
diff --git a/frontend/projects/netconf-lib/src/lib/classes/session.ts b/frontend/projects/netconf-lib/src/lib/classes/session.ts
index 9600224..09e490b 100644
--- a/frontend/projects/netconf-lib/src/lib/classes/session.ts
+++ b/frontend/projects/netconf-lib/src/lib/classes/session.ts
@@ -8,5 +8,5 @@
public key: string;
public device: Device;
public data?: object[];
- public modifications: object;
+ public modifications?: object;
}
diff --git a/frontend/projects/netconf-lib/src/lib/services/configuration.service.ts b/frontend/projects/netconf-lib/src/lib/services/configuration.service.ts
index 29b33f3..dbb2578 100644
--- a/frontend/projects/netconf-lib/src/lib/services/configuration.service.ts
+++ b/frontend/projects/netconf-lib/src/lib/services/configuration.service.ts
@@ -2,23 +2,57 @@
* Author: Jakub Man <xmanja00@stud.fit.vutbr.cz>
* Service for configuration changes
*/
-import {Injectable} from '@angular/core';
+import {EventEmitter, Injectable} from '@angular/core';
import {Session} from '../classes/session';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
+import {Modification} from '../classes/Modification';
+import {ModificationType} from '../classes/ModificationType';
+
+interface Modifications {
+ [key: string]: Modification;
+}
@Injectable({
providedIn: 'root'
})
export class ConfigurationService {
+
+
+ modifications: Modifications = {};
+
+ public modificationsChanged = new EventEmitter<string>();
+
+
constructor(public http: HttpClient) {
}
- public commitChanges(session: Session): Observable<any> {
- console.log('Modifications: ');
- console.log(session.modifications);
- return this.http.post<any>('/netconf/session/commit', {'key': session.key, 'modifications': session.modifications});
+ public commitChanges(sessionKey: string): Observable<any> {
+ return this.http.post<any>('/netconf/session/commit', {'key': sessionKey, 'modifications': this.modifications[sessionKey]});
+ }
+
+ createChangeModification(sessionKey: string, path: string, node: object, newValue: any) {
+ // tslint:disable-next-line:triple-equals
+ if (node['value'] == newValue) {
+ console.log('Value did not change');
+ return;
+ }
+ if (!this.modifications[sessionKey]) {
+ this.modifications[sessionKey] = {};
+ }
+ this.modifications[sessionKey][path] = {
+ 'type': ModificationType.Change,
+ 'original': node['value'],
+ 'value': newValue,
+ 'data': node
+ };
+ console.log(this.modifications);
+ this.modificationsChanged.emit(sessionKey);
+ }
+
+ discardModifications(sessionKey: string) {
+ this.modifications[sessionKey] = {};
}
}
diff --git a/frontend/projects/netconf-lib/src/lib/services/session.service.ts b/frontend/projects/netconf-lib/src/lib/services/session.service.ts
index d39377c..1ec826f 100644
--- a/frontend/projects/netconf-lib/src/lib/services/session.service.ts
+++ b/frontend/projects/netconf-lib/src/lib/services/session.service.ts
@@ -35,7 +35,6 @@
private _sessions: Session[] = [];
public sessionsChanged: EventEmitter<Session[]> = new EventEmitter<Session[]>();
- public modificationAdded: EventEmitter<Session> = new EventEmitter<Session>();
addSession(key: string, device: Device) {
if (!this.doesSessionExists(key)) {
@@ -57,7 +56,7 @@
return this.http.delete('/netconf/session/' + key)
.pipe(
tap(
- next => {
+ _ => {
this._sessions.splice(idx, 1);
this.sessionsChanged.emit(this.sessions);
}
@@ -65,11 +64,17 @@
);
}
- loadOpenSessions(): Observable<Session[]> {
- return this.http.get<Session[]>('/netconf/sessions');
+ loadOpenSessions(forceReload = false): Observable<Session[]> {
+ if (!forceReload && this.sessions.length !== 0) {
+ return of(this.sessions);
+ }
+ return this.http.get<Session[]>('/netconf/sessions').pipe(
+ tap(data => this.sessions = data)
+ );
}
destroyAllSessions() {
+ this.sessions = [];
return this.http.delete('/netconf/sessions');
}
@@ -101,11 +106,7 @@
* For more information see https://netopeer.liberouter.org/doc/libyang/devel/howtoxpath.html
*/
public getCompatibleDeviceSessions(path: any): Observable<Session[]> {
- if (this.sessions.length === 0) {
- return this.loadOpenSessions();
- } else {
- return of(this.sessions);
- }
+ return this.loadOpenSessions(); // TODO: Path filtering
}
@@ -134,35 +135,4 @@
}
- createChangeModification(sessionKey: string, path: string, node: object, newValue: string) {
- if (node['value'] == newValue) {
- // No change
- console.log('Value did not change');
- return;
- }
- const idx = this.findSessionIndex(sessionKey);
- if (idx < 0) {
- console.warn('Session "' + sessionKey + '" not found');
- return;
- }
- if (!this.sessions[idx].modifications) {
- this.sessions[idx].modifications = {};
- }
- this.sessions[idx].modifications[path] = {
- 'type': ModificationType.Change,
- 'original': node['value'],
- 'value': newValue,
- 'data': node
- };
- this.modificationAdded.emit(this.sessions[idx]);
- }
-
- discardModifications(sessionKey: string) {
- const idx = this.findSessionIndex(sessionKey);
- if (idx > 0) {
- this.sessions[idx].modifications = {};
- }
-
- }
-
}
diff --git a/frontend/projects/tools/src/yang-configure/components/confirm-commit.component.ts b/frontend/projects/tools/src/yang-configure/components/confirm-commit.component.ts
index 1e5596c..8cdc38e 100644
--- a/frontend/projects/tools/src/yang-configure/components/confirm-commit.component.ts
+++ b/frontend/projects/tools/src/yang-configure/components/confirm-commit.component.ts
@@ -4,7 +4,7 @@
*/
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {ConfigurationService, SessionService} from 'netconf-lib';
+import {ConfigurationService, Session} from 'netconf-lib';
import {NodeControlService} from '../services/node-control.service';
@Component({
@@ -14,25 +14,25 @@
})
export class ConfirmCommitComponent implements OnInit {
- @Input() session;
+ @Input() session: Session;
@Output() shouldClose: EventEmitter<boolean> = new EventEmitter<boolean>();
error = '';
constructor(public configurationService: ConfigurationService,
- public sessionService: SessionService,
public nodeControlService: NodeControlService) { }
ngOnInit() {
}
commitChanges() {
- this.configurationService.commitChanges(this.session).subscribe(
+ this.configurationService.commitChanges(this.session.key).subscribe(
success => {
if (!success.success) {
this.error = success.message;
} else {
this.error = '';
+ this.nodeControlService.confirmNewValue();
this.shouldClose.emit(true);
}
},
@@ -44,7 +44,7 @@
discardChanges() {
this.nodeControlService.restoreOriginalValuesOnAll();
- this.sessionService.discardModifications(this.session.key);
+ this.configurationService.discardModifications(this.session.key);
this.shouldClose.emit(true);
}
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-configure.component.ts b/frontend/projects/tools/src/yang-configure/components/yang-configure.component.ts
index 9fda740..8bd08de 100644
--- a/frontend/projects/tools/src/yang-configure/components/yang-configure.component.ts
+++ b/frontend/projects/tools/src/yang-configure/components/yang-configure.component.ts
@@ -19,6 +19,7 @@
constructor(
public sessionService: SessionService,
public nodeControlService: NodeControlService,
+ public configurationService: ConfigurationService,
private deviceService: DeviceService,
public schemaService: SchemasService
) {
@@ -38,13 +39,12 @@
this.sessionService.loadOpenSessions().subscribe(
sessions => {
console.log(sessions);
- this.sessionService.sessions = sessions;
+ // this.sessionService.sessions = sessions;
}
);
- this.sessionService.modificationAdded.subscribe(
- session => {
- if (session.key === this.selectedSession.key) {
- this.selectedSession.modifications = session.modifications; // Update selected session value
+ this.configurationService.modificationsChanged.subscribe(
+ sessionKey => {
+ if (sessionKey === this.selectedSession.key) {
this.commitChangesShown = true;
}
}
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.html b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.html
index 57a2789..4b601c0 100644
--- a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.html
+++ b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.html
@@ -17,29 +17,16 @@
<!-- Node has a value -->
<span *ngIf="node['value']">:</span>
- <span class="value" *ngIf="node['value'] && !editing">{{node['value']}}</span>
- <ng-container *ngIf="node['info']['type'] == 4 || (node['new'] && node['info']['type'] == 8)">
-
- <ng-container
- *ngIf="node['info']['config'] &&
- !node['deleted'] &&
- (!node['info']['key'] || node['new'])
- && node['info']['datatypebase'] != 'empty'">
- <input [class.hidden]="!editing" type="text" autofocus class="editing-input" [(ngModel)]="editingValue">
- <span class="old-value" *ngIf="node['value'] !== originalValue">{{originalValue}}</span>
- <i class="fa fa-pencil action-icon" aria-hidden="true" [class.hidden]="editing"
- (click)="toggleEdit()"
- title="Edit value"></i>
-
-
- <i class="fa fa-times action-icon text-danger" aria-hidden="true" [class.hidden]="!editing"
- (click)="toggleEdit()"></i>
- <i class="fa fa-check action-icon text-success" aria-hidden="true" [class.hidden]="!editing"
- (click)="confirmEdit()"></i>
- <span title="Current value" class="disabled" [class.hidden]="!editing || editingValue == originalValue"></span>
-
- </ng-container>
- </ng-container>
+ <nct-yang-node-editable-value
+ *ngIf="node['value']"
+ [editable]="(node['info']['type'] == 4 || (node['new'] && node['info']['type'] == 8)) &&
+ (node['info']['config'] &&
+ !node['deleted']) &&
+ (!node['info']['key'] || node['new'])"
+ [value]="node['value']"
+ (changeSaved)="confirmEdit($event)"
+ (changeDiscarded)="discardChanges($event)"
+ ></nct-yang-node-editable-value>
<!-- Menu -->
<nct-yang-node-menu *ngIf="node['info']['config']"
@@ -47,6 +34,8 @@
[nodeType]="node['info']['type']"
(addChildClicked)="addChildNode()"></nct-yang-node-menu>
+ <span class="type" *ngIf="node['info']['datatype']">{{node['info']['datatype']}}</span>
+
<!-- Node description -->
<nct-yang-node-description [description]="node['info']['dsc']"></nct-yang-node-description>
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.scss b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.scss
index ae8f922..f450f2e 100644
--- a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.scss
+++ b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.scss
@@ -10,12 +10,6 @@
display: none;
}
-.value {
- font-family: "JetBrains Mono", "Source Code Pro", Consolas, monospace;
- margin-left: 10px;
- /* cursor: pointer; */
-}
-
.disabled {
color: transparentize($colorText, 0.3);
}
@@ -41,13 +35,6 @@
border-left: 1px solid transparentize($colorText, 0.5);
}
-.old-value {
- text-decoration: line-through;
- font-weight: lighter;
- color: $colorError;
- margin-left: 7px;
-}
-
.modified {
color: $colorSuccess;
}
@@ -56,8 +43,10 @@
color: $colorError;
}
-.editing-input {
- border: none;
- border-bottom: 1px solid $colorText;
+.type {
+ color: transparentize($colorText, 0.2);
font-family: "JetBrains Mono", "Source Code Pro", Consolas, monospace;
+ margin-left: 15px;
}
+
+
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.ts b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.ts
index 66ba899..74dc7ac 100644
--- a/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.ts
+++ b/frontend/projects/tools/src/yang-configure/components/yang-schema-node.component.ts
@@ -40,22 +40,18 @@
@Input() showChildren = false;
@Input() activeSession;
showAllChildrenOnOpen = false;
- editing = false;
- originalValue;
- editingValue = '';
newNode: { key: string, module: string, path: string };
ngOnInit() {
this.showAllChildrenOnOpen = this.showChildren;
this.nodeControlService.performNodeAction.subscribe(
action => {
- this.performGlobalAction(action);
+ if (action === 'close') {
+ this.showChildren = false;
+ this.showAllChildrenOnOpen = false;
+ }
}
);
- if (this.node['value']) {
- this.originalValue = this.node['value'];
- this.editingValue = this.node['value'];
- }
}
toggleChildren() {
@@ -68,32 +64,13 @@
this.showChildren = !this.showChildren;
}
- toggleEdit() {
- this.editing = !this.editing;
+ confirmEdit(value) {
+ this.configurationService.createChangeModification(this.activeSession.key, this.node['info']['path'], this.node, value);
+ this.node['value'] = value;
}
- performGlobalAction(action: string) {
- switch (action) {
- case 'close':
- this.showChildren = false;
- this.showAllChildrenOnOpen = false;
- break;
- case 'discardChanges':
- this.restoreOriginal();
- break;
- }
- }
-
- confirmEdit() {
- this.editing = false;
- this.sessionService.createChangeModification(this.activeSession.key, this.node['info']['path'], this.node, this.editingValue);
- this.sessionService.modificationAdded.emit(this.activeSession);
- this.node['value'] = this.editingValue;
- }
-
- restoreOriginal() {
- this.editingValue = this.originalValue;
- this.node['value'] = this.originalValue;
+ discardChanges(value) {
+ this.node['value'] = value;
}
addChildNode() {
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-new-node/yang-new-node.component.ts b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-new-node/yang-new-node.component.ts
index 94b12bc..38cba63 100644
--- a/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-new-node/yang-new-node.component.ts
+++ b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-new-node/yang-new-node.component.ts
@@ -8,7 +8,11 @@
styleUrls: ['./yang-new-node.component.scss']
})
export class YangNewNodeComponent implements OnInit {
-
+ /*
+ * Move child generation to the session service
+ * Mark them with node['new']
+ * This component will only be the dropdown menu, node will be handleded by the schema-node component
+ */
@Input() sessionKey: string;
@Input() schema: string;
@Input() path: string;
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.html b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.html
new file mode 100644
index 0000000..5a2258d
--- /dev/null
+++ b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.html
@@ -0,0 +1,18 @@
+<span class="value" *ngIf="value && !editing">{{value}}</span>
+
+<ng-container *ngIf="editable">
+ <input [class.hidden]="!editing" type="text" autofocus class="editing-input" [(ngModel)]="editingValue">
+ <span class="old-value" *ngIf="value !== originalValue">{{originalValue}}</span>
+ <i class="fa fa-pencil action-icon" aria-hidden="true" [class.hidden]="editing"
+ (click)="editing = !editing"
+ title="Edit value"></i>
+
+
+ <i class="fa fa-times action-icon text-danger" aria-hidden="true" [class.hidden]="!editing"
+ (click)="editing = !editing"></i>
+ <i class="fa fa-check action-icon text-success" aria-hidden="true" [class.hidden]="!editing"
+ (click)="confirmEdit()"></i>
+ <span title="Current value" class="disabled" [class.hidden]="!editing || editingValue == originalValue"></span>
+
+</ng-container>
+<span class="type" *ngIf="datatype">{{datatype}}</span>
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.scss b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.scss
new file mode 100644
index 0000000..bdab355
--- /dev/null
+++ b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.scss
@@ -0,0 +1,40 @@
+@import "../../../../../../shared-styles/colors";
+
+.editing-input {
+ border: none;
+ border-bottom: 1px solid $colorText;
+ font-family: "JetBrains Mono", "Source Code Pro", Consolas, monospace;
+}
+
+.disabled {
+ color: transparentize($colorText, 0.3);
+}
+
+.hidden {
+ display: none;
+}
+
+.value {
+ font-family: "JetBrains Mono", "Source Code Pro", Consolas, monospace;
+ margin-left: 10px;
+ /* cursor: pointer; */
+}
+
+.action-icon {
+ padding-left: 5px;
+ padding-right: 5px;
+ cursor: pointer;
+ &:first-child {
+ padding-left: 10px;
+ }
+ &:hover {
+ color: $colorMain;
+ }
+}
+
+.old-value {
+ text-decoration: line-through;
+ font-weight: lighter;
+ color: $colorError;
+ margin-left: 7px;
+}
diff --git a/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.ts b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.ts
new file mode 100644
index 0000000..b402cc9
--- /dev/null
+++ b/frontend/projects/tools/src/yang-configure/components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component.ts
@@ -0,0 +1,47 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {NodeControlService} from '../../../services/node-control.service';
+
+@Component({
+ selector: 'nct-yang-node-editable-value',
+ templateUrl: './yang-node-editable-value.component.html',
+ styleUrls: ['./yang-node-editable-value.component.scss']
+})
+export class YangNodeEditableValueComponent implements OnInit {
+
+ @Input() editable: boolean;
+ @Input() value: any;
+ @Input() datatype?: string;
+
+
+ @Output() changeSaved = new EventEmitter<any>();
+ @Output() changeDiscarded = new EventEmitter<any>();
+
+ editing = false;
+ originalValue: any;
+ editingValue: any;
+
+ constructor(public nodeControlService: NodeControlService) {
+ }
+
+ ngOnInit() {
+ this.originalValue = this.value;
+ this.editingValue = this.value;
+ this.nodeControlService.performNodeAction.subscribe(
+ action => {
+ if (action === 'discardChanges') {
+ this.value = this.originalValue;
+ this.editingValue = this.originalValue;
+ this.changeDiscarded.emit(this.originalValue);
+ } else if (action === 'confirmNewValue') {
+ this.originalValue = this.value;
+ }
+ }
+ );
+ }
+
+ confirmEdit() {
+ this.editing = false;
+ this.changeSaved.emit(this.editingValue);
+ }
+
+}
diff --git a/frontend/projects/tools/src/yang-configure/services/node-control.service.ts b/frontend/projects/tools/src/yang-configure/services/node-control.service.ts
index 9cd7f14..f669980 100644
--- a/frontend/projects/tools/src/yang-configure/services/node-control.service.ts
+++ b/frontend/projects/tools/src/yang-configure/services/node-control.service.ts
@@ -37,6 +37,7 @@
this.performNodeAction.emit('discardChanges');
}
-
-
+ confirmNewValue() {
+ this.performNodeAction.emit('confirmNewValue');
+ }
}
diff --git a/frontend/projects/tools/src/yang-configure/yang-configure.module.ts b/frontend/projects/tools/src/yang-configure/yang-configure.module.ts
index 5e29048..2885912 100644
--- a/frontend/projects/tools/src/yang-configure/yang-configure.module.ts
+++ b/frontend/projects/tools/src/yang-configure/yang-configure.module.ts
@@ -15,7 +15,8 @@
import { YangNewNodeComponent } from './components/yang-tree-components/yang-new-node/yang-new-node.component';
import { YangNodeDescriptionComponent } from './components/yang-tree-components/yang-node-description/yang-node-description.component';
import { YangSchemaLinkComponent } from './components/yang-tree-components/yang-schema-link/yang-schema-link.component';
-import { YangNodeMenuComponent } from './components/yang-tree-components/yang-node-menu/yang-node-menu.component';
+import { YangNodeMenuComponent } from './components/yang-tree-components/yang-node-menu/yang-node-menu.component';
+import { YangNodeEditableValueComponent } from './components/yang-tree-components/yang-node-editable-value/yang-node-editable-value.component';
@NgModule({
@@ -26,7 +27,7 @@
RouterModule,
FormsModule
],
- declarations: [YangConfigureComponent, YangSchemaNodeComponent, ConfirmCommitComponent, YangNewNodeComponent, YangNodeDescriptionComponent, YangSchemaLinkComponent, YangNodeMenuComponent],
+ declarations: [YangConfigureComponent, YangSchemaNodeComponent, ConfirmCommitComponent, YangNewNodeComponent, YangNodeDescriptionComponent, YangSchemaLinkComponent, YangNodeMenuComponent, YangNodeEditableValueComponent],
entryComponents: [YangConfigureComponent]
})
export class YangConfigureModule {