From 5107200dc769d5690f5356bb467f05143a05abd1 Mon Sep 17 00:00:00 2001
From: mdelez <60604010+mdelez@users.noreply.github.com>
Date: Fri, 26 Feb 2021 15:08:09 +0100
Subject: [PATCH] feat(list-editor): insert a child node at a specific position
(DSP-1301) (#395)
* feat(list-editor): adds functionality for inserting a child node at a specific position
* feat(list-editor): adds support for inserting a node within a list of child nodes
* chore(package.json): update DSP-JS version
* test(edit-list-item): adds unit test for insertChildNode method
* test(list-item): adds test for insert node switch case
* chore: align long list of imports into a list
---
package-lock.json | 12 +-
package.json | 2 +-
src/app/main/dialog/dialog.component.html | 9 +-
.../edit-list-item.component.html | 4 +-
.../edit-list-item.component.spec.ts | 244 ++++++++++++------
.../edit-list-item.component.ts | 78 +++++-
.../list-item-form.component.html | 10 +-
.../list-item-form.component.ts | 35 ++-
.../list/list-item/list-item.component.html | 6 +-
.../list-item/list-item.component.spec.ts | 64 +++++
.../list/list-item/list-item.component.ts | 21 ++
11 files changed, 368 insertions(+), 117 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index dbef9443ab..45d0ee84e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
"packages": {
"": {
"name": "dsp-app",
- "version": "4.1.0",
+ "version": "4.2.1",
"dependencies": {
"@angular/animations": "^9.1.12",
"@angular/cdk": "^9.2.4",
@@ -19,7 +19,7 @@
"@angular/platform-browser-dynamic": "~9.1.12",
"@angular/router": "~9.1.12",
"@ckeditor/ckeditor5-angular": "^1.2.3",
- "@dasch-swiss/dsp-js": "^2.0.2",
+ "@dasch-swiss/dsp-js": "^2.1.0",
"@dasch-swiss/dsp-ui": "^1.2.2",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
@@ -2109,7 +2109,9 @@
}
},
"node_modules/@dasch-swiss/dsp-js": {
- "version": "2.0.2",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@dasch-swiss/dsp-js/-/dsp-js-2.1.0.tgz",
+ "integrity": "sha512-jz4Umltxz5WK9CL9gUYyy9dntuFP6hYIBXODDcoD4Jr9iqBKQTS584XxFg3ZZmktiYt0Iu9j2BeKFlxUk2uAkQ==",
"license": "AGPL-3.0",
"dependencies": {
"@types/jsonld": "^1.5.0",
@@ -20863,7 +20865,9 @@
}
},
"@dasch-swiss/dsp-js": {
- "version": "2.0.2",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@dasch-swiss/dsp-js/-/dsp-js-2.1.0.tgz",
+ "integrity": "sha512-jz4Umltxz5WK9CL9gUYyy9dntuFP6hYIBXODDcoD4Jr9iqBKQTS584XxFg3ZZmktiYt0Iu9j2BeKFlxUk2uAkQ==",
"requires": {
"@types/jsonld": "^1.5.0",
"json2typescript": "1.4.1",
diff --git a/package.json b/package.json
index c543533294..da7cbf615b 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
"@angular/platform-browser-dynamic": "~9.1.12",
"@angular/router": "~9.1.12",
"@ckeditor/ckeditor5-angular": "^1.2.3",
- "@dasch-swiss/dsp-js": "^2.0.2",
+ "@dasch-swiss/dsp-js": "^2.1.0",
"@dasch-swiss/dsp-ui": "^1.2.2",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
diff --git a/src/app/main/dialog/dialog.component.html b/src/app/main/dialog/dialog.component.html
index 6e45243c48..3ab7821379 100644
--- a/src/app/main/dialog/dialog.component.html
+++ b/src/app/main/dialog/dialog.component.html
@@ -145,6 +145,13 @@
(updateParent)="replaceTitle($event)">
+
+
+
@@ -157,7 +164,7 @@
diff --git a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.html b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.html
index 84fd1bd958..88deb051b1 100644
--- a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.html
+++ b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.html
@@ -37,8 +37,8 @@
type="submit"
color="primary"
[disabled]="saveButtonDisabled"
- (click)="updateChildNode()">
- {{ 'appLabels.form.action.update' | translate }}
+ (click)=" mode === 'editListNode' ? updateChildNode() : insertChildNode()">
+ {{ mode === 'editListNode' ? 'appLabels.form.action.update' : 'appLabels.form.action.submit' | translate }}
diff --git a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.spec.ts b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.spec.ts
index 6f0da3155f..7996a3a0b4 100644
--- a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.spec.ts
+++ b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.spec.ts
@@ -2,7 +2,7 @@ import { Component, DebugElement, OnInit, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { ApiResponseData, ListNodeInfoResponse, ListsEndpointAdmin, UpdateChildNodeRequest } from '@dasch-swiss/dsp-js';
+import { ApiResponseData, CreateChildNodeRequest, ListNodeInfoResponse, ListsEndpointAdmin, UpdateChildNodeRequest } from '@dasch-swiss/dsp-js';
import { DspActionModule, DspApiConnectionToken, ProgressIndicatorComponent } from '@dasch-swiss/dsp-ui';
import { TranslateModule } from '@ngx-translate/core';
import { of } from 'rxjs';
@@ -10,29 +10,52 @@ import { AjaxResponse } from 'rxjs/ajax';
import { EditListItemComponent } from './edit-list-item.component';
/**
- * Test host component to simulate parent component.
+ * Test host component to simulate parent component for updating an existing child node.
*/
@Component({
- template: ``
+ template: ``
})
-class TestHostComponent implements OnInit {
+class TestHostUpdateChildNodeComponent {
@ViewChild('editListItem') editListItem: EditListItemComponent;
iri = 'http://rdfh.ch/lists/0001/otherTreeList01';
+ mode = 'update';
+
projectIri = 'http://rdfh.ch/projects/0001';
constructor() {}
+}
+
+/**
+ * Test host component to simulate parent component for inserting a new child node.
+ */
+@Component({
+ template: ``
+})
+class TestHostInsertChildNodeComponent {
+
+ @ViewChild('editListItem') editListItem: EditListItemComponent;
+
+ iri = 'http://rdfh.ch/lists/0001/otherTreeList01';
+
+ mode = 'insert';
- ngOnInit() {
- }
+ parentIri = 'http://rdfh.ch/lists/0001/otherTreeList';
+
+ position = 0;
+
+ projectCode = '0001';
+
+ projectIri = 'http://rdfh.ch/projects/0001';
+ constructor() {}
}
describe('EditListItemComponent', () => {
- let testHostComponent: TestHostComponent;
- let testHostFixture: ComponentFixture;
+ let testHostComponent: TestHostUpdateChildNodeComponent;
+ let testHostFixture: ComponentFixture;
let editListItemComponentDe: DebugElement;
let formInvalidMessageDe: DebugElement;
@@ -40,14 +63,15 @@ describe('EditListItemComponent', () => {
const listsEndpointSpyObj = {
admin: {
- listsEndpoint: jasmine.createSpyObj('listsEndpoint', ['getListNodeInfo', 'updateChildNode'])
+ listsEndpoint: jasmine.createSpyObj('listsEndpoint', ['getListNodeInfo', 'updateChildNode', 'createChildNode'])
}
};
TestBed.configureTestingModule({
declarations: [
EditListItemComponent,
- TestHostComponent,
+ TestHostUpdateChildNodeComponent,
+ TestHostInsertChildNodeComponent,
ProgressIndicatorComponent,
],
imports: [
@@ -65,88 +89,142 @@ describe('EditListItemComponent', () => {
.compileComponents();
}));
- beforeEach(() => {
- const dspConnSpy = TestBed.inject(DspApiConnectionToken);
-
- (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj).getListNodeInfo.and.callFake(
- () => {
- const response = new ListNodeInfoResponse();
- response.nodeinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList01';
- response.nodeinfo.labels = [{'value': 'Tree list node 01', 'language': 'en'}];
- response.nodeinfo.comments = [{'value': 'My comment', 'language': 'en'}];
- return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
- }
- );
-
- testHostFixture = TestBed.createComponent(TestHostComponent);
- testHostComponent = testHostFixture.componentInstance;
- testHostFixture.detectChanges();
-
- expect(testHostComponent).toBeTruthy();
-
- const hostCompDe = testHostFixture.debugElement;
- editListItemComponentDe = hostCompDe.query(By.directive(EditListItemComponent));
- expect(editListItemComponentDe).toBeTruthy();
- });
-
- it('should assign labels and comments', () => {
- const dspConnSpy = TestBed.inject(DspApiConnectionToken);
- expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}]);
- expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}]);
- expect(dspConnSpy.admin.listsEndpoint.getListNodeInfo).toHaveBeenCalledTimes(1);
- expect(dspConnSpy.admin.listsEndpoint.getListNodeInfo).toHaveBeenCalledWith('http://rdfh.ch/lists/0001/otherTreeList01');
-
+ describe('update list child node', () => {
+ beforeEach(() => {
+ const dspConnSpy = TestBed.inject(DspApiConnectionToken);
+
+ (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj).getListNodeInfo.and.callFake(
+ () => {
+ const response = new ListNodeInfoResponse();
+ response.nodeinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList01';
+ response.nodeinfo.labels = [{'value': 'Tree list node 01', 'language': 'en'}];
+ response.nodeinfo.comments = [{'value': 'My comment', 'language': 'en'}];
+ return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
+ }
+ );
+
+ testHostFixture = TestBed.createComponent(TestHostUpdateChildNodeComponent);
+ testHostComponent = testHostFixture.componentInstance;
+ testHostFixture.detectChanges();
+
+ expect(testHostComponent).toBeTruthy();
+
+ const hostCompDe = testHostFixture.debugElement;
+ editListItemComponentDe = hostCompDe.query(By.directive(EditListItemComponent));
+ expect(editListItemComponentDe).toBeTruthy();
+ });
+
+ it('should assign labels and comments', () => {
+ const dspConnSpy = TestBed.inject(DspApiConnectionToken);
+ expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}]);
+ expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}]);
+ expect(dspConnSpy.admin.listsEndpoint.getListNodeInfo).toHaveBeenCalledTimes(1);
+ expect(dspConnSpy.admin.listsEndpoint.getListNodeInfo).toHaveBeenCalledWith('http://rdfh.ch/lists/0001/otherTreeList01');
+ });
+
+ it('should update labels when the value changes', () => {
+ expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}]);
+ testHostComponent.editListItem.handleData([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}], 'labels');
+ expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}]);
+ expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
+ testHostComponent.editListItem.handleData([], 'labels');
+ expect(testHostComponent.editListItem.saveButtonDisabled).toBeTruthy();
+ testHostFixture.detectChanges();
+ formInvalidMessageDe = editListItemComponentDe.query(By.css('span.invalid-form'));
+ expect(formInvalidMessageDe.nativeElement.innerText).toEqual('A label is required.');
+ });
+
+ it('should update comments when the value changes', () => {
+ expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}]);
+ testHostComponent.editListItem.handleData([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}], 'comments');
+ expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}]);
+ expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
+ testHostComponent.editListItem.handleData([], 'comments');
+ expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
+ });
+
+ it('should update the child node info', () => {
+ const dspConnSpy = TestBed.inject(DspApiConnectionToken);
+
+ testHostComponent.editListItem.handleData([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}], 'labels');
+ testHostComponent.editListItem.handleData([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}], 'comments');
+
+ (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj).updateChildNode.and.callFake(
+ () => {
+ const response = new ListNodeInfoResponse();
+ response.nodeinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList01';
+ response.nodeinfo.labels = [{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}];
+ response.nodeinfo.comments = [{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}];
+
+ expect(testHostComponent.editListItem.labels).toEqual(response.nodeinfo.labels);
+ expect(testHostComponent.editListItem.comments).toEqual(response.nodeinfo.comments);
+
+ return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
+ }
+ );
+
+ const updateChildNodeRequest: UpdateChildNodeRequest = new UpdateChildNodeRequest();
+ updateChildNodeRequest.projectIri = testHostComponent.editListItem.projectIri;
+ updateChildNodeRequest.listIri = testHostComponent.editListItem.iri;
+ updateChildNodeRequest.labels = testHostComponent.editListItem.labels;
+ updateChildNodeRequest.comments = testHostComponent.editListItem.comments;
+
+ testHostComponent.editListItem.updateChildNode();
+ expect(dspConnSpy.admin.listsEndpoint.updateChildNode).toHaveBeenCalledTimes(1);
+ expect(dspConnSpy.admin.listsEndpoint.updateChildNode).toHaveBeenCalledWith(updateChildNodeRequest);
+ });
});
- it('should update labels when the value changes', () => {
- expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}]);
- testHostComponent.editListItem.handleData([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}], 'labels');
- expect(testHostComponent.editListItem.labels).toEqual([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}]);
- expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
- testHostComponent.editListItem.handleData([], 'labels');
- expect(testHostComponent.editListItem.saveButtonDisabled).toBeTruthy();
- testHostFixture.detectChanges();
- formInvalidMessageDe = editListItemComponentDe.query(By.css('span.invalid-form'));
- expect(formInvalidMessageDe.nativeElement.innerText).toEqual('A label is required.');
- });
+ describe('insert list child node', () => {
+ beforeEach(() => {
+ testHostFixture = TestBed.createComponent(TestHostInsertChildNodeComponent);
+ testHostComponent = testHostFixture.componentInstance;
+ testHostFixture.detectChanges();
- it('should update comments when the value changes', () => {
- expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}]);
- testHostComponent.editListItem.handleData([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}], 'comments');
- expect(testHostComponent.editListItem.comments).toEqual([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}]);
- expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
- testHostComponent.editListItem.handleData([], 'comments');
- expect(testHostComponent.editListItem.saveButtonDisabled).toBeFalsy();
- });
+ expect(testHostComponent).toBeTruthy();
- it('should update the child node info', () => {
- const dspConnSpy = TestBed.inject(DspApiConnectionToken);
+ const hostCompDe = testHostFixture.debugElement;
+ editListItemComponentDe = hostCompDe.query(By.directive(EditListItemComponent));
+ expect(editListItemComponentDe).toBeTruthy();
+ });
- testHostComponent.editListItem.handleData([{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}], 'labels');
- testHostComponent.editListItem.handleData([{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}], 'comments');
+ it('should instantiate empty arrays for labels and comments', () => {
+ expect(testHostComponent.editListItem.labels).toEqual([]);
+ expect(testHostComponent.editListItem.comments).toEqual([]);
+ });
- (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj).updateChildNode.and.callFake(
- () => {
- const response = new ListNodeInfoResponse();
- response.nodeinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList01';
- response.nodeinfo.labels = [{'value': 'Tree list node 01', 'language': 'en'}, {'value': 'Baumlistenknoten 01', 'language': 'de'}];
- response.nodeinfo.comments = [{'value': 'My comment', 'language': 'en'}, {'value': 'Mein Kommentar', 'language': 'de'}];
+ it('should create (insert) a new child node', () => {
+ const dspConnSpy = TestBed.inject(DspApiConnectionToken);
- expect(testHostComponent.editListItem.labels).toEqual(response.nodeinfo.labels);
- expect(testHostComponent.editListItem.comments).toEqual(response.nodeinfo.comments);
+ testHostComponent.editListItem.handleData([{'value': 'My new child node value', 'language': 'en'}], 'labels');
+ testHostComponent.editListItem.handleData([{'value': 'My new child node comment', 'language': 'en'}], 'comments');
- return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
- }
- );
+ (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj).createChildNode.and.callFake(
+ () => {
+ const response = new ListNodeInfoResponse();
+ response.nodeinfo.name = 'My new child node';
+ response.nodeinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList0123';
+ response.nodeinfo.labels = [{'value': 'My new child node value', 'language': 'en'}];
+ response.nodeinfo.comments = [{'value': 'My new child node comment', 'language': 'en'}];
+ response.nodeinfo.position = 0;
- const childNodeUpdateData: UpdateChildNodeRequest = new UpdateChildNodeRequest();
- childNodeUpdateData.projectIri = testHostComponent.editListItem.projectIri;
- childNodeUpdateData.listIri = testHostComponent.editListItem.iri;
- childNodeUpdateData.labels = testHostComponent.editListItem.labels;
- childNodeUpdateData.comments = testHostComponent.editListItem.comments;
+ expect(testHostComponent.editListItem.labels).toEqual(response.nodeinfo.labels);
+ expect(testHostComponent.editListItem.comments).toEqual(response.nodeinfo.comments);
+ expect(testHostComponent.editListItem.position).toEqual(response.nodeinfo.position);
- testHostComponent.editListItem.updateChildNode();
- expect(dspConnSpy.admin.listsEndpoint.updateChildNode).toHaveBeenCalledTimes(1);
- expect(dspConnSpy.admin.listsEndpoint.updateChildNode).toHaveBeenCalledWith(childNodeUpdateData);
+ return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
+ }
+ );
+
+ const createChildNodeRequest: CreateChildNodeRequest = new CreateChildNodeRequest();
+ createChildNodeRequest.projectIri = testHostComponent.editListItem.projectIri;
+ createChildNodeRequest.labels = testHostComponent.editListItem.labels;
+ createChildNodeRequest.comments = testHostComponent.editListItem.comments;
+ createChildNodeRequest.position = testHostComponent.editListItem.position;
+ createChildNodeRequest.parentNodeIri = testHostComponent.editListItem.parentIri;
+
+ testHostComponent.editListItem.insertChildNode();
+ expect(dspConnSpy.admin.listsEndpoint.createChildNode).toHaveBeenCalledTimes(1);
+ });
});
});
diff --git a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.ts b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.ts
index 31abe3ab52..541fc9405c 100644
--- a/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.ts
+++ b/src/app/project/list/list-item-form/edit-list-item/edit-list-item.component.ts
@@ -1,5 +1,16 @@
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
-import { ApiResponseData, ApiResponseError, ChildNodeInfoResponse, KnoraApiConnection, List, ListNodeInfo, ListNodeInfoResponse, StringLiteral, UpdateChildNodeRequest } from '@dasch-swiss/dsp-js';
+import {
+ ApiResponseData,
+ ApiResponseError,
+ ChildNodeInfoResponse,
+ CreateChildNodeRequest,
+ KnoraApiConnection,
+ List,
+ ListNodeInfo,
+ ListNodeInfoResponse,
+ StringLiteral,
+ UpdateChildNodeRequest
+} from '@dasch-swiss/dsp-js';
import { DspApiConnectionToken } from '@dasch-swiss/dsp-ui';
@Component({
@@ -12,6 +23,14 @@ export class EditListItemComponent implements OnInit {
@Input() iri: string;
+ @Input() mode: 'insert' | 'update';
+
+ @Input() parentIri?: string;
+
+ @Input() position?: number;
+
+ @Input() projectCode?: string;
+
@Input() projectIri: string;
@Output() closeDialog: EventEmitter = new EventEmitter();
@@ -46,16 +65,23 @@ export class EditListItemComponent implements OnInit {
ngOnInit(): void {
this.loading = true;
- // get list
- this._dspApiConnection.admin.listsEndpoint.getListNodeInfo(this.iri).subscribe(
- (response: ApiResponseData) => {
- this.listNode = response.body.nodeinfo;
- this.buildForm(response.body.nodeinfo);
- },
- (error: ApiResponseError) => {
- console.error(error);
- }
- );
+ // if updating a node, get the existing node info
+ if (this.mode === 'update') {
+ this._dspApiConnection.admin.listsEndpoint.getListNodeInfo(this.iri).subscribe(
+ (response: ApiResponseData) => {
+ this.listNode = response.body.nodeinfo;
+ this.buildForm(response.body.nodeinfo);
+ },
+ (error: ApiResponseError) => {
+ console.error(error);
+ }
+ );
+ } else {
+ this.labels = [];
+ this.comments = [];
+
+ this.loading = false;
+ }
}
/**
@@ -105,8 +131,8 @@ export class EditListItemComponent implements OnInit {
}
/**
- * Called from the template when the 'update' button is clicked.
- * Sends a request to DSP-API to update the list node with the data inside the two local arrays.
+ * Called from the template when the 'submit' button is clicked in update mode.
+ * Sends a request to DSP-API to update the list child node with the data inside the two local arrays.
*/
updateChildNode() {
const childNodeUpdateData: UpdateChildNodeRequest = new UpdateChildNodeRequest();
@@ -127,4 +153,30 @@ export class EditListItemComponent implements OnInit {
);
}
+ /**
+ * Called from the template when the 'submit' button is clicked in insert mode.
+ * Sends a request to DSP-API to insert a new list child node in the provided position.
+ */
+ insertChildNode() {
+ const createChildNodeRequest: CreateChildNodeRequest = new CreateChildNodeRequest();
+
+ createChildNodeRequest.name = this.projectCode + '-' + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
+ createChildNodeRequest.parentNodeIri = this.parentIri;
+ createChildNodeRequest.labels = this.labels;
+ createChildNodeRequest.comments = this.comments.length > 0 ? this.comments : [];
+ createChildNodeRequest.projectIri = this.projectIri;
+ createChildNodeRequest.position = this.position;
+
+ this._dspApiConnection.admin.listsEndpoint.createChildNode(createChildNodeRequest).subscribe(
+ (response: ApiResponseData) => {
+ this.loading = false;
+ this.closeDialog.emit(response.body.nodeinfo);
+ },
+ (error: ApiResponseError) => {
+ this.errorMessage = error;
+ this.loading = false;
+ }
+ );
+ }
+
}
diff --git a/src/app/project/list/list-item-form/list-item-form.component.html b/src/app/project/list/list-item-form/list-item-form.component.html
index 67e7b030a2..04f6bdaa95 100644
--- a/src/app/project/list/list-item-form/list-item-form.component.html
+++ b/src/app/project/list/list-item-form/list-item-form.component.html
@@ -1,5 +1,5 @@
-
+
@@ -14,7 +14,7 @@
arrow_downward
+
diff --git a/src/app/project/list/list-item/list-item.component.spec.ts b/src/app/project/list/list-item/list-item.component.spec.ts
index e625843e8a..f25538defe 100644
--- a/src/app/project/list/list-item/list-item.component.spec.ts
+++ b/src/app/project/list/list-item/list-item.component.spec.ts
@@ -172,6 +172,70 @@ describe('ListItemComponent', () => {
expect(testHostComponent.listItem.list[0].labels).toEqual([{value: 'Tree List Node 0123', language: 'en'}]);
});
+ it('should update the view to show an inserted node', () => {
+ const dspConnSpy = TestBed.inject(DspApiConnectionToken);
+
+ (dspConnSpy.admin.listsEndpoint as jasmine.SpyObj
).getList.and.callFake(
+ () => {
+ const response = new ListResponse();
+ response.list.listinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList';
+ response.list.listinfo.isRootNode = true;
+ response.list.listinfo.labels = [{value: 'Tree List Node Root', language: 'en'}];
+ response.list.children = [
+ {
+ comments: [],
+ labels: [{value: 'Tree List Node 01', language: 'en'}],
+ id: 'http://rdfh.ch/lists/0001/otherTreeList01',
+ children: [
+ {
+ comments: [],
+ labels: [{value: 'Tree List Node 03', language: 'en'}],
+ id: 'http://rdfh.ch/lists/0001/otherTreeList03',
+ children: []
+ }
+ ]
+ },
+ {
+ comments: [],
+ labels: [{value: 'Tree List Node 04 between node 01 and node 02', language: 'en'}],
+ id: 'http://rdfh.ch/lists/0001/otherTreeList04',
+ children: []
+ },
+ {
+ comments: [],
+ labels: [{value: 'Tree List Node 02', language: 'en'}],
+ id: 'http://rdfh.ch/lists/0001/otherTreeList02',
+ children: []
+ }
+ ];
+ return of(ApiResponseData.fromAjaxResponse({response} as AjaxResponse));
+ }
+ );
+
+ const listNodeOperation: ListNodeOperation = new ListNodeOperation();
+ listNodeOperation.listNode = {
+ children: undefined,
+ comments: [],
+ hasRootNode: 'http://rdfh.ch/lists/0001/otherTreeList',
+ id: 'http://rdfh.ch/lists/0001/otherTreeList04',
+ labels: [{value: 'Tree List Node 04 between node 01 and node 02', language: 'en'}],
+ position: 1
+ };
+
+ listNodeOperation.operation = 'insert';
+
+ testHostComponent.listItem.updateView(listNodeOperation);
+
+ expect(testHostComponent.listItem.list.length).toEqual(3);
+
+ expect(testHostComponent.listItem.list[1].labels).toEqual([{value: 'Tree List Node 04 between node 01 and node 02', language: 'en'}]);
+
+ expect(dspConnSpy.admin.listsEndpoint.getList).toHaveBeenCalledWith(testHostComponent.parentIri);
+
+ // getList is called twice because it is also called in ngOnInit
+ expect(dspConnSpy.admin.listsEndpoint.getList).toHaveBeenCalledTimes(2);
+ });
+
it('should update the view to remove a deleted node', () => {
const listNodeOperation: ListNodeOperation = new ListNodeOperation();
listNodeOperation.listNode = {
diff --git a/src/app/project/list/list-item/list-item.component.ts b/src/app/project/list/list-item/list-item.component.ts
index 2f8b0dc56f..e3a82d3812 100644
--- a/src/app/project/list/list-item/list-item.component.ts
+++ b/src/app/project/list/list-item/list-item.component.ts
@@ -3,6 +3,7 @@ import {
ApiResponseData,
ApiResponseError,
KnoraApiConnection,
+ ListChildNodeResponse,
ListNode,
ListResponse,
RepositionChildNodeRequest,
@@ -97,6 +98,25 @@ export class ListItemComponent implements OnInit {
}
break;
}
+ case 'insert': {
+ // get the corresponding list from the API again and reassign the local list with its response
+ this._dspApiConnection.admin.listsEndpoint.getList(this.parentIri).subscribe(
+ (result: ApiResponseData) => {
+ if (result.body instanceof ListResponse) {
+ this.list = result.body.list.children; // root node
+ } else {
+ this.list = result.body.node.children; // child node
+ }
+
+ // emit the updated list of children to the parent node
+ this.refreshChildren.emit(this.list);
+ },
+ (error: ApiResponseError) => {
+ this._errorHandler.showMessage(error);
+ }
+ );
+ break;
+ }
case 'update': {
// use the position from the response from DSP-API to find the correct node to update
this.list[data.listNode.position].labels = data.listNode.labels;
@@ -118,6 +138,7 @@ export class ListItemComponent implements OnInit {
repositionRequest.position = data.listNode.position;
// since we don't have any way to know the parent IRI from the ListItemForm component, we need to do the API call here
+ // --> TODO now we have the parent IRI within the ListItemForm component so we can move this logic there
this._dspApiConnection.admin.listsEndpoint.repositionChildNode(data.listNode.id, repositionRequest).subscribe(
(res: ApiResponseData) => {
this.list = res.body.node.children;