diff --git a/src/app/main/dialog/dialog.component.html b/src/app/main/dialog/dialog.component.html
index 3ab7821379..b179b65630 100644
--- a/src/app/main/dialog/dialog.component.html
+++ b/src/app/main/dialog/dialog.component.html
@@ -140,14 +140,14 @@
@@ -156,7 +156,7 @@
diff --git a/src/app/project/list/list-info-form/list-info-form.component.html b/src/app/project/list/list-info-form/list-info-form.component.html
index b723232e89..9146368562 100644
--- a/src/app/project/list/list-info-form/list-info-form.component.html
+++ b/src/app/project/list/list-info-form/list-info-form.component.html
@@ -1,19 +1,13 @@
-
-
-
-
-
+
-
+ {{ labelInvalidMessage }}
@@ -31,17 +25,10 @@
-
-
-
diff --git a/src/app/project/list/list-info-form/list-info-form.component.spec.ts b/src/app/project/list/list-info-form/list-info-form.component.spec.ts
index bafcdf8b18..d716dd9464 100644
--- a/src/app/project/list/list-info-form/list-info-form.component.spec.ts
+++ b/src/app/project/list/list-info-form/list-info-form.component.spec.ts
@@ -1,37 +1,88 @@
+import { HarnessLoader } from '@angular/cdk/testing';
+import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { HttpClientModule } from '@angular/common/http';
+import { Component, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
+import { MatButtonHarness } from '@angular/material/button/testing';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
-import { KnoraApiConnection } from '@dasch-swiss/dsp-js';
+import { ApiResponseData, CreateListRequest, ListInfoResponse, ListResponse, ListsEndpointAdmin, UpdateListInfoRequest } from '@dasch-swiss/dsp-js';
import {
- AppInitService,
DspActionModule,
- DspApiConfigToken,
DspApiConnectionToken,
DspCoreModule
} from '@dasch-swiss/dsp-ui';
import { TranslateModule } from '@ngx-translate/core';
+import { of } from 'rxjs';
+import { AjaxResponse } from 'rxjs/ajax';
+import { DialogHeaderComponent } from 'src/app/main/dialog/dialog-header/dialog-header.component';
import { DialogComponent } from 'src/app/main/dialog/dialog.component';
import { ErrorComponent } from 'src/app/main/error/error.component';
-import { TestConfig } from 'test.config';
-import { ListItemFormComponent } from '../list-item-form/list-item-form.component';
-import { ListItemComponent } from '../list-item/list-item.component';
import { ListInfoFormComponent } from './list-info-form.component';
+/**
+ * test host component to simulate parent component for creating a new list.
+ */
+@Component({
+ template: ''
+})
+class TestHostUpdateListComponent {
+
+ @ViewChild('listInfoForm') listInfoForm: ListInfoFormComponent;
+
+ iri = 'http://rdfh.ch/lists/0001/otherTreeList';
+
+ mode = 'update';
+
+ projectIri = 'http://rdfh.ch/projects/0001';
+
+ constructor() {}
+}
+
+/**
+ * test host component to simulate parent component for creating a new list.
+ */
+@Component({
+ template: ''
+})
+class TestHostCreateListComponent {
+
+ @ViewChild('listInfoForm') listInfoForm: ListInfoFormComponent;
+
+ mode = 'create';
+
+ projectcode = '0001';
+
+ projectIri = 'http://rdfh.ch/projects/0001';
+
+ constructor() {}
+}
+
describe('ListInfoFormComponent', () => {
- let component: ListInfoFormComponent;
- let fixture: ComponentFixture;
+ let testHostUpdateListComponent: TestHostUpdateListComponent;
+ let testHostUpdateListFixture: ComponentFixture;
+ let testHostCreateListComponent: TestHostCreateListComponent;
+ let testHostCreateListFixture: ComponentFixture;
+ let rootLoader: HarnessLoader;
+
+ const listsEndpointSpyObj = {
+ admin: {
+ listsEndpoint: jasmine.createSpyObj('listsEndpoint', ['getListInfo', 'updateListInfo', 'createList'])
+ }
+ };
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
+ TestHostUpdateListComponent,
+ TestHostCreateListComponent,
ListInfoFormComponent,
- ListItemComponent,
- ListItemFormComponent,
DialogComponent,
+ DialogHeaderComponent,
ErrorComponent
],
imports: [
@@ -46,27 +97,168 @@ describe('ListInfoFormComponent', () => {
TranslateModule.forRoot()
],
providers: [
- AppInitService,
{
- provide: DspApiConfigToken,
- useValue: TestConfig.ApiConfig
+ provide: DspApiConnectionToken,
+ useValue: listsEndpointSpyObj
},
{
- provide: DspApiConnectionToken,
- useValue: new KnoraApiConnection(TestConfig.ApiConfig)
+ provide: MAT_DIALOG_DATA,
+ useValue: {}
+ },
+ {
+ provide: MatDialogRef,
+ useValue: {}
}
]
})
.compileComponents();
}));
- beforeEach(() => {
- fixture = TestBed.createComponent(ListInfoFormComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
+ describe('update existing list info', () => {
+ beforeEach(() => {
+
+ const listsEndpointSpy = TestBed.inject(DspApiConnectionToken);
+
+ (listsEndpointSpy.admin.listsEndpoint as jasmine.SpyObj).getListInfo.and.callFake(
+ () => {
+ const response = new ListInfoResponse();
+ response.listinfo.id = 'http://rdfh.ch/lists/0001/otherTreeList';
+ response.listinfo.labels = [{ 'value': 'Other Tree List', 'language': 'en' }];
+ response.listinfo.comments = [{ 'value': 'Other Tree List comment', 'language': 'en' }];
+ return of(ApiResponseData.fromAjaxResponse({ response } as AjaxResponse));
+ }
+ );
+
+ testHostUpdateListFixture = TestBed.createComponent(TestHostUpdateListComponent);
+ testHostUpdateListComponent = testHostUpdateListFixture.componentInstance;
+ testHostUpdateListFixture.detectChanges();
+ expect(testHostUpdateListComponent).toBeTruthy();
+
+ rootLoader = TestbedHarnessEnvironment.documentRootLoader(testHostUpdateListFixture);
+ });
+
+ it('should instantiate arrays for labels and comments', () => {
+ expect(testHostUpdateListComponent.listInfoForm.labels).toEqual([{ 'value': 'Other Tree List', 'language': 'en' }]);
+ expect(testHostUpdateListComponent.listInfoForm.comments).toEqual([{ 'value': 'Other Tree List comment', 'language': 'en' }]);
+ });
+
+ it('should display "Update" as the submit button text and be disabled as long as no labels are provided', async () => {
+ const submitButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.list-submit' }));
+
+ expect(await submitButton.getText()).toEqual('Update');
+
+ expect(await submitButton.isDisabled()).toBeFalsy();
+
+ testHostUpdateListComponent.listInfoForm.handleData([], 'labels');
+
+ expect(await submitButton.isDisabled()).toBeTruthy();
+
+ testHostUpdateListComponent.listInfoForm.handleData([{ 'value': 'My edited list label', 'language': 'en' }], 'labels');
+
+ expect(await submitButton.isDisabled()).toBeFalsy();
+ });
+
+ it('should update labels when the value changes', () => {
+ testHostUpdateListComponent.listInfoForm.handleData([{ 'value': 'My edited list label', 'language': 'en' }], 'labels');
+ expect(testHostUpdateListComponent.listInfoForm.labels).toEqual([{ 'value': 'My edited list label', 'language': 'en' }]);
+ });
+
+ it('should update comments when the value changes', () => {
+ testHostUpdateListComponent.listInfoForm.handleData([{ 'value': 'My edited list comment', 'language': 'en' }], 'comments');
+ expect(testHostUpdateListComponent.listInfoForm.comments).toEqual([{ 'value': 'My edited list comment', 'language': 'en' }]);
+ });
+
+ it('should update the list info', () => {
+ const listsEndpointSpy = TestBed.inject(DspApiConnectionToken);
+
+ testHostUpdateListComponent.listInfoForm.handleData([{ 'value': 'My edited list label', 'language': 'en' }], 'labels');
+ testHostUpdateListComponent.listInfoForm.handleData([{ 'value': 'My edited list comment', 'language': 'en' }], 'comments');
+
+ const updateListInfoRequest: UpdateListInfoRequest = new UpdateListInfoRequest();
+ updateListInfoRequest.listIri = testHostUpdateListComponent.listInfoForm.iri;
+ updateListInfoRequest.projectIri = testHostUpdateListComponent.listInfoForm.projectIri;
+ updateListInfoRequest.labels = testHostUpdateListComponent.listInfoForm.labels;
+ updateListInfoRequest.comments = testHostUpdateListComponent.listInfoForm.comments;
+
+ (listsEndpointSpy.admin.listsEndpoint as jasmine.SpyObj).updateListInfo.and.callFake(
+ () => {
+ const response = new ListInfoResponse();
+ response.listinfo.labels = [{ 'value': 'My edited list label', 'language': 'en' }];
+ response.listinfo.comments = [{ 'value': 'My edited list comment', 'language': 'en' }];
+
+ expect(updateListInfoRequest.labels).toEqual(response.listinfo.labels);
+ expect(updateListInfoRequest.comments).toEqual(response.listinfo.comments);
+
+ return of(ApiResponseData.fromAjaxResponse({ response } as AjaxResponse));
+ }
+ );
+
+ testHostUpdateListComponent.listInfoForm.submitData();
+ expect(listsEndpointSpy.admin.listsEndpoint.updateListInfo).toHaveBeenCalledTimes(1);
+ expect(listsEndpointSpy.admin.listsEndpoint.updateListInfo).toHaveBeenCalledWith(updateListInfoRequest);
+ });
});
- it('should create', () => {
- expect(component).toBeTruthy();
+ describe('create new list', () => {
+ beforeEach(() => {
+ testHostCreateListFixture = TestBed.createComponent(TestHostCreateListComponent);
+ testHostCreateListComponent = testHostCreateListFixture.componentInstance;
+ testHostCreateListFixture.detectChanges();
+ expect(testHostCreateListComponent).toBeTruthy();
+
+ rootLoader = TestbedHarnessEnvironment.documentRootLoader(testHostCreateListFixture);
+ });
+
+ it('should instantiate empty arrays for labels and comments', () => {
+ expect(testHostCreateListComponent.listInfoForm.labels).toEqual([]);
+ expect(testHostCreateListComponent.listInfoForm.comments).toEqual([]);
+ });
+
+ it('should display "Create" as the submit button text and be disabled as long as no labels are provided', async () => {
+ const submitButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.list-submit' }));
+
+ expect(await submitButton.getText()).toEqual('Create');
+
+ expect(await submitButton.isDisabled()).toBeTruthy();
+
+ testHostCreateListComponent.listInfoForm.handleData([{ 'value': 'My new list', 'language': 'en' }], 'labels');
+
+ expect(await submitButton.isDisabled()).toBeFalsy();
+
+ testHostCreateListComponent.listInfoForm.handleData([], 'labels');
+
+ expect(await submitButton.isDisabled()).toBeTruthy();
+ });
+
+ it('should create a new list', () => {
+ const listsEndpointSpy = TestBed.inject(DspApiConnectionToken);
+
+ testHostCreateListComponent.listInfoForm.handleData([{ 'value': 'My new list', 'language': 'en' }], 'labels');
+ testHostCreateListComponent.listInfoForm.handleData([{ 'value': 'My new list comment', 'language': 'en' }], 'comments');
+
+ const createListRequest: CreateListRequest = new CreateListRequest();
+ createListRequest.projectIri = testHostCreateListComponent.listInfoForm.projectIri;
+ createListRequest.labels = testHostCreateListComponent.listInfoForm.labels;
+ createListRequest.comments = testHostCreateListComponent.listInfoForm.comments;
+
+ (listsEndpointSpy.admin.listsEndpoint as jasmine.SpyObj).createList.and.callFake(
+ () => {
+ const response = new ListResponse();
+ response.list.children = [];
+ response.list.listinfo.labels = [{ 'value': 'My new list', 'language': 'en' }];
+ response.list.listinfo.comments = [{ 'value': 'My new list comment', 'language': 'en' }];
+
+ expect(createListRequest.labels).toEqual(response.list.listinfo.labels);
+ expect(createListRequest.comments).toEqual(response.list.listinfo.comments);
+
+ return of(ApiResponseData.fromAjaxResponse({ response } as AjaxResponse));
+ }
+ );
+
+ testHostCreateListComponent.listInfoForm.submitData();
+ expect(listsEndpointSpy.admin.listsEndpoint.createList).toHaveBeenCalledTimes(1);
+ expect(listsEndpointSpy.admin.listsEndpoint.createList).toHaveBeenCalledWith(createListRequest);
+ });
});
+
});
diff --git a/src/app/project/list/list-info-form/list-info-form.component.ts b/src/app/project/list/list-info-form/list-info-form.component.ts
index b248665d5c..b2600efc5b 100644
--- a/src/app/project/list/list-info-form/list-info-form.component.ts
+++ b/src/app/project/list/list-info-form/list-info-form.component.ts
@@ -23,9 +23,10 @@ import { ErrorHandlerService } from 'src/app/main/error/error-handler.service';
})
export class ListInfoFormComponent implements OnInit {
-
@Input() iri?: string;
+ @Input() mode: 'create' | 'update';
+
// project short code
@Input() projectcode: string;
@@ -33,8 +34,6 @@ export class ListInfoFormComponent implements OnInit {
@Output() closeDialog: EventEmitter = new EventEmitter();
- @Output() updateParent: EventEmitter<{ title: string }> = new EventEmitter<{ title: string }>();
-
loading: boolean;
project: ReadProject;
@@ -44,51 +43,16 @@ export class ListInfoFormComponent implements OnInit {
labels: StringLiteral[];
comments: StringLiteral[];
- /**
- * by adding new list, it starts with the list info and the next section is "creating the list";
- * true after adding list
- *
- */
- createList = false;
- newList: List;
-
- nameMinLength = 3;
- nameMaxLength = 16;
-
- /**
- * form group for the form controller
- */
- form: FormGroup;
-
- /**
- * error checking on the following fields
- */
- formErrors = {
- label: ''
- };
-
- /**
- * error hints
- */
- validationMessages = {
+ // possible errors for the label
+ labelErrors = {
label: {
- 'required': 'Name is required.',
- 'minlength': 'Name must be at least ' + this.nameMinLength + ' characters long.',
- 'maxlength': 'Name cannot be more than ' + this.nameMaxLength + ' characters long.'
+ 'required': 'A label is required.'
}
};
- /**
- * success of sending data
- */
- success = false;
- /**
- * message after successful post
- */
- successMessage: any = {
- status: 200,
- statusText: "You have successfully updated list's info."
- };
+ saveButtonDisabled = false;
+
+ labelInvalidMessage: string;
constructor(
@Inject(DspApiConnectionToken) private _dspApiConnection: KnoraApiConnection,
@@ -99,13 +63,13 @@ export class ListInfoFormComponent implements OnInit {
this.loading = true;
- // get list info in case of edit mode: this.iri is not undefined
- if (this.iri) {
+ // get list info in case of edit mode
+ if (this.mode === 'update') {
// edit mode, get list
this._dspApiConnection.admin.listsEndpoint.getListInfo(this.iri).subscribe(
(response: ApiResponseData) => {
this.list = response.body.listinfo;
- this.buildForm(response.body.listinfo);
+ this.buildLists(response.body.listinfo);
},
(error: ApiResponseError) => {
this._errorHandler.showMessage(error);
@@ -114,11 +78,11 @@ export class ListInfoFormComponent implements OnInit {
} else {
// build the form
- this.buildForm();
+ this.buildLists();
}
}
- buildForm(list?: ListNodeInfo): void {
+ buildLists(list?: ListNodeInfo): void {
this.loading = true;
this.labels = [];
@@ -129,47 +93,28 @@ export class ListInfoFormComponent implements OnInit {
this.comments = list.comments;
}
- setTimeout(() => {
- this.loading = false;
- });
+ this.loading = false;
}
submitData(): void {
this.loading = true;
- if (this.iri) {
+ if (this.mode === 'update') {
// edit mode: update list info
const listInfoUpdateData: UpdateListInfoRequest = new UpdateListInfoRequest();
listInfoUpdateData.projectIri = this.projectIri;
listInfoUpdateData.listIri = this.iri;
-
- // initialize labels
- let i = 0;
- for (const l of this.labels) {
- listInfoUpdateData.labels[i] = new StringLiteral();
- listInfoUpdateData.labels[i].language = l.language;
- listInfoUpdateData.labels[i].value = l.value;
- i++;
- }
- // initialize comments
- let j = 0;
- for (const c of this.comments) {
- listInfoUpdateData.comments[j] = new StringLiteral();
- listInfoUpdateData.comments[j].language = c.language;
- listInfoUpdateData.comments[j].value = c.value;
- j++;
- }
+ listInfoUpdateData.labels = this.labels;
+ listInfoUpdateData.comments = this.comments;
this._dspApiConnection.admin.listsEndpoint.updateListInfo(listInfoUpdateData).subscribe(
(response: ApiResponseData) => {
- this.success = true;
this.loading = false;
this.closeDialog.emit(response.body.listinfo);
},
(error: ApiResponseError) => {
this._errorHandler.showMessage(error);
this.loading = false;
- this.success = false;
}
);
@@ -177,36 +122,17 @@ export class ListInfoFormComponent implements OnInit {
// new: create list
const listInfoData: CreateListRequest = new CreateListRequest();
listInfoData.projectIri = this.projectIri;
-
- // initialize labels
- let i = 0;
- for (const l of this.labels) {
- listInfoData.labels[i] = new StringLiteral();
- listInfoData.labels[i].language = l.language;
- listInfoData.labels[i].value = l.value;
- i++;
- }
- // initialize comments
- let j = 0;
- for (const c of this.comments) {
- listInfoData.comments[j] = new StringLiteral();
- listInfoData.comments[j].language = c.language;
- listInfoData.comments[j].value = c.value;
- j++;
- }
+ listInfoData.labels = this.labels;
+ listInfoData.comments = this.comments;
this._dspApiConnection.admin.listsEndpoint.createList(listInfoData).subscribe(
(response: ApiResponseData) => {
- this.newList = response.body.list;
-
- this.updateParent.emit({ title: response.body.list.listinfo.labels[0].value + ' (' + response.body.list.listinfo.labels[0].language + ')' });
+ this.closeDialog.emit(response.body.list);
this.loading = false;
- this.createList = true;
},
(error: ApiResponseError) => {
this._errorHandler.showMessage(error);
this.loading = false;
- this.success = false;
}
);
}
@@ -215,13 +141,13 @@ export class ListInfoFormComponent implements OnInit {
/**
* reset the form
*/
- resetForm(ev: Event, list?: ListNodeInfo) {
+ resetLists(ev: Event, list?: ListNodeInfo) {
ev.preventDefault();
list = list ? list : new ListNodeInfo();
- this.buildForm(list);
+ this.buildLists(list);
}
handleData(data: StringLiteral[], type: string) {
@@ -235,5 +161,15 @@ export class ListInfoFormComponent implements OnInit {
this.comments = data;
break;
}
+
+ if (this.labels.length === 0) {
+ // invalid label, don't let user submit
+ this.saveButtonDisabled = true;
+ this.labelInvalidMessage = this.labelErrors.label.required;
+ } else {
+ this.saveButtonDisabled = false;
+ this.labelInvalidMessage = null;
+ }
}
+
}
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 88deb051b1..248fdbd988 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)=" mode === 'editListNode' ? updateChildNode() : insertChildNode()">
- {{ mode === 'editListNode' ? 'appLabels.form.action.update' : 'appLabels.form.action.submit' | translate }}
+ (click)=" mode === 'update' ? updateChildNode() : insertChildNode()">
+ {{ mode === 'update' ? ('appLabels.form.action.update' | translate) : ('appLabels.form.action.submit' | translate) }}
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 04f6bdaa95..c590cb40ca 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
@@ -3,7 +3,7 @@
-