From c8ad4458c9f147ef83c7ff884e2178be9c2ff8c6 Mon Sep 17 00:00:00 2001 From: mdelez <60604010+mdelez@users.noreply.github.com> Date: Mon, 15 Jun 2020 09:47:40 +0200 Subject: [PATCH] FIX: display-edit dev build errors (#106) * refactor (display-edit): first not-so-elegant way of fixing dev build errors * fix (display-edit): fixed a bug I introduced while fixing another bug * tests (operations): add assertions to display edit comp. * formatting * Revert "refactor (display-edit): first not-so-elegant way of fixing dev build errors" This reverts commit 2ea88b6469baa5f5d4f3c4b61d478fa1c7454da5. # Conflicts: # projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.ts * revert (display-edit): revert to original logic * fix (display-edit): fixed incorrect member name * fix (tests): display-edit unit tests now check for an instance of the appropriate readvalue. Also added some missing values * reworded a comment Co-authored-by: Tobias Schweizer --- .../display-edit/display-edit.component.html | 31 +-- .../display-edit.component.spec.ts | 54 +++- .../display-edit/display-edit.component.ts | 248 +++++++++--------- 3 files changed, 183 insertions(+), 150 deletions(-) diff --git a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.html b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.html index 18fe57358..0b7818586 100644 --- a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.html +++ b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.html @@ -1,7 +1,7 @@

- {{displayValue.propertyLabel}} + {{displayValue.propertyLabel}}

- - - - - - - - - - - + + + + + + + + + + + - - + - {{displayValue.strval}} + {{displayValue.strval}}
diff --git a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.spec.ts b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.spec.ts index 3440fd21e..4dcb559f2 100644 --- a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.spec.ts +++ b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.spec.ts @@ -15,7 +15,16 @@ import { UpdateResource, UpdateValue, ValuesEndpointV2, - WriteValueResponse + WriteValueResponse, + ReadBooleanValue, + ReadUriValue, + ReadDecimalValue, + ReadColorValue, + ReadIntervalValue, + ReadTimeValue, + ReadLinkValue, + ReadListValue, + ReadGeonameValue } from '@knora/api'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -294,7 +303,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestTextValueAsStringComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadTextValueAsString).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -314,7 +323,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestTextValueAsHtmlComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadTextValueAsHtml).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -325,7 +334,7 @@ describe('DisplayEditComponent', () => { expect(testHostComponent.displayEditValueComponent).toBeTruthy(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestIntValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadIntValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -336,7 +345,7 @@ describe('DisplayEditComponent', () => { expect(testHostComponent.displayEditValueComponent).toBeTruthy(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestBooleanValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadBooleanValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -347,7 +356,7 @@ describe('DisplayEditComponent', () => { expect(testHostComponent.displayEditValueComponent).toBeTruthy(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestUriValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadUriValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -357,7 +366,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestDecimalValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadDecimalValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -367,7 +376,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestColorValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadColorValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -377,7 +386,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestIntervalValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadIntervalValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -387,7 +396,7 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestTimeValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadTimeValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); }); @@ -397,13 +406,35 @@ describe('DisplayEditComponent', () => { testHostFixture.detectChanges(); expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestLinkValueComponent).toBe(true); - expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue).not.toBeUndefined(); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadLinkValue).toBe(true); expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); expect((testHostComponent.displayEditValueComponent.displayValueComponent as unknown as TestLinkValueComponent).parentResource instanceof ReadResource).toBe(true); expect((testHostComponent.displayEditValueComponent.displayValueComponent as unknown as TestLinkValueComponent).propIri).toEqual('http://0.0.0.0:3333/ontology/0001/anything/v2#hasOtherThingValue'); }); + it('should choose the apt component for a list value in the template', () => { + testHostComponent.assignValue('http://0.0.0.0:3333/ontology/0001/anything/v2#hasListItem'); + testHostFixture.detectChanges(); + + expect(testHostComponent.displayEditValueComponent).toBeTruthy(); + + expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestListValueComponent).toBe(true); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadListValue).toBe(true); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); + }); + + it('should choose the apt component for a geoname value in the template', () => { + testHostComponent.assignValue('http://0.0.0.0:3333/ontology/0001/anything/v2#hasGeoname'); + testHostFixture.detectChanges(); + + expect(testHostComponent.displayEditValueComponent).toBeTruthy(); + + expect(testHostComponent.displayEditValueComponent.displayValueComponent instanceof TestGeonameValueComponent).toBe(true); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue instanceof ReadGeonameValue).toBe(true); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.mode).toEqual('read'); + }); + }); describe('methods getValueType and isReadOnly', () => { @@ -580,6 +611,7 @@ describe('DisplayEditComponent', () => { 'uuid'); expect(testHostComponent.displayEditValueComponent.displayValue.id).toEqual('newID'); + expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue.id).toEqual('newID'); expect(testHostComponent.displayEditValueComponent.mode).toEqual('read'); }); diff --git a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.ts b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.ts index f3c464b69..2471d94b6 100644 --- a/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.ts +++ b/projects/dsp-ui/src/lib/viewer/operations/display-edit/display-edit.component.ts @@ -23,160 +23,160 @@ import { BaseValueComponent } from '../../values/base-value.component'; }) export class DisplayEditComponent implements OnInit { - @ViewChild('displayVal') displayValueComponent: BaseValueComponent; + @ViewChild('displayVal') displayValueComponent: BaseValueComponent; - @Input() displayValue: ReadValue; + @Input() displayValue: ReadValue; - @Input() parentResource: ReadResource; + @Input() parentResource: ReadResource; - @Input() configuration?: object; + @Input() configuration?: object; - constants = Constants; + constants = Constants; - mode: 'read' | 'update' | 'create' | 'search'; + mode: 'read' | 'update' | 'create' | 'search'; - canModify: boolean; + canModify: boolean; - editModeActive = false; + editModeActive = false; - shouldShowCommentToggle: boolean; + shouldShowCommentToggle: boolean; - // type of given displayValue - // or knora-api-js-lib class representing the value - valueTypeOrClass: string; + // type of given displayValue + // or knora-api-js-lib class representing the value + valueTypeOrClass: string; - // indicates if value can be edited - readOnlyValue: boolean; + // indicates if value can be edited + readOnlyValue: boolean; - private readonly readTextValueAsString = 'ReadTextValueAsString'; + private readonly readTextValueAsString = 'ReadTextValueAsString'; - private readonly readTextValueAsXml = 'ReadTextValueAsXml'; + private readonly readTextValueAsXml = 'ReadTextValueAsXml'; - private readonly readTextValueAsHtml = 'ReadTextValueAsHtml'; + private readonly readTextValueAsHtml = 'ReadTextValueAsHtml'; - constructor(@Inject(DspApiConnectionToken) private knoraApiConnection: KnoraApiConnection) { - } + constructor(@Inject(DspApiConnectionToken) private knoraApiConnection: KnoraApiConnection) { + } + + ngOnInit() { + + this.mode = 'read'; - ngOnInit() { + // determine if user has modify permissions + const allPermissions = PermissionUtil.allUserPermissions(this.displayValue.userHasPermission as 'RV' | 'V' | 'M' | 'D' | 'CR'); - this.mode = 'read'; + this.canModify = allPermissions.indexOf(PermissionUtil.Permissions.M) !== -1; - // determine if user has modify permissions - const allPermissions = PermissionUtil.allUserPermissions(this.displayValue.userHasPermission as 'RV' | 'V' | 'M' | 'D' | 'CR'); + // check if comment toggle button should be shown + this.checkCommentToggleVisibility(); - this.canModify = allPermissions.indexOf(PermissionUtil.Permissions.M) !== -1; + this.valueTypeOrClass = this.getValueTypeOrClass(this.displayValue); - // check if comment toggle button should be shown - this.checkCommentToggleVisibility(); + this.readOnlyValue = this.isReadOnly(this.valueTypeOrClass); + } - this.valueTypeOrClass = this.getValueTypeOrClass(this.displayValue); + activateEditMode() { + this.editModeActive = true; + this.mode = 'update'; - this.readOnlyValue = this.isReadOnly(this.valueTypeOrClass); - } + // hide comment toggle button while in edit mode + this.checkCommentToggleVisibility(); - activateEditMode() { - this.editModeActive = true; - this.mode = 'update'; + // hide read mode comment when switching to edit mode + this.displayValueComponent.shouldShowComment = false; + } - // hide comment toggle button while in edit mode - this.checkCommentToggleVisibility(); + saveEditValue() { + this.editModeActive = false; + const updatedVal = this.displayValueComponent.getUpdatedValue(); + + if (updatedVal instanceof UpdateValue) { + + const updateRes = new UpdateResource(); + updateRes.id = this.parentResource.id; + updateRes.type = this.parentResource.type; + updateRes.property = this.displayValue.property; + updateRes.value = updatedVal; + this.knoraApiConnection.v2.values.updateValue(updateRes as UpdateResource).pipe( + mergeMap((res: WriteValueResponse) => { + return this.knoraApiConnection.v2.values.getValue(this.parentResource.id, res.uuid); + }) + ).subscribe( + (res2: ReadResource) => { + this.displayValue = res2.getValues(this.displayValue.property)[0]; + this.mode = 'read'; + + // hide comment once back in read mode + this.displayValueComponent.updateCommentVisibility(); + + // check if comment toggle button should be shown + this.checkCommentToggleVisibility(); + } + ); + + } else { + console.error('invalid value'); + } + } - // hide read mode comment when switching to edit mode - this.displayValueComponent.shouldShowComment = false; - } + cancelEditValue() { + this.editModeActive = false; + this.mode = 'read'; - saveEditValue() { - this.editModeActive = false; - const updatedVal = this.displayValueComponent.getUpdatedValue(); + // hide comment once back in read mode + this.displayValueComponent.updateCommentVisibility(); - if (updatedVal instanceof UpdateValue) { + // check if comment toggle button should be shown + this.checkCommentToggleVisibility(); + } - const updateRes = new UpdateResource(); - updateRes.id = this.parentResource.id; - updateRes.type = this.parentResource.type; - updateRes.property = this.displayValue.property; - updateRes.value = updatedVal; - this.knoraApiConnection.v2.values.updateValue(updateRes as UpdateResource).pipe( - mergeMap((res: WriteValueResponse) => { - return this.knoraApiConnection.v2.values.getValue(this.parentResource.id, res.uuid); - }) - ).subscribe( - (res2: ReadResource) => { - this.displayValue = res2.getValues(this.displayValue.property)[0]; - this.mode = 'read'; + // shows or hides the comment + toggleComment() { + this.displayValueComponent.toggleCommentVisibility(); + } - // hide comment once back in read mode - this.displayValueComponent.updateCommentVisibility(); + // only show the comment toggle button if user is in READ mode and a comment exists for the value + checkCommentToggleVisibility() { + this.shouldShowCommentToggle = (this.mode === 'read' && this.displayValue.valueHasComment !== '' && this.displayValue.valueHasComment !== undefined); + } - // check if comment toggle button should be shown - this.checkCommentToggleVisibility(); + /** + * Given a value, determines the type or class representing it. + * + * For text values, this method determines the specific class in use. + * For all other types, the given type is returned. + * + * @param value the given value. + */ + getValueTypeOrClass(value: ReadValue): string { + + if (value.type === this.constants.TextValue) { + if (value instanceof ReadTextValueAsString) { + return this.readTextValueAsString; + } else if (value instanceof ReadTextValueAsXml) { + return this.readTextValueAsXml; + } else if (value instanceof ReadTextValueAsHtml) { + return this.readTextValueAsHtml; + } else { + throw new Error(`unknown TextValue class ${value}`); + } + } else { + return value.type; } - ); - - } else { - console.error('invalid value'); } - } - - cancelEditValue() { - this.editModeActive = false; - this.mode = 'read'; - - // hide comment once back in read mode - this.displayValueComponent.updateCommentVisibility(); - - // check if comment toggle button should be shown - this.checkCommentToggleVisibility(); - } - - // shows or hides the comment - toggleComment() { - this.displayValueComponent.toggleCommentVisibility(); - } - - // only show the comment toggle button if user is in READ mode and a comment exists for the value - checkCommentToggleVisibility() { - this.shouldShowCommentToggle = (this.mode === 'read' && this.displayValue.valueHasComment !== '' && this.displayValue.valueHasComment !== undefined); - } - - /** - * Given a value, determines the type or class representing it. - * - * For text values, this method determines the specific class in use. - * For all other types, the given type is returned. - * - * @param value the given value. - */ - getValueTypeOrClass(value: ReadValue): string { - - if (value.type === this.constants.TextValue) { - if (value instanceof ReadTextValueAsString) { - return this.readTextValueAsString; - } else if (value instanceof ReadTextValueAsXml) { - return this.readTextValueAsXml; - } else if (value instanceof ReadTextValueAsHtml) { - return this.readTextValueAsHtml; - } else { - throw new Error(`unknown TextValue class ${value}`); - } - } else { - return value.type; + + /** + * Equality checks with constants below are TEMPORARY until component is implemented. + * Used so that the CRUD buttons do not show if a property doesn't have a value component. + */ + + /** + * Determines if the given value is readonly. + * + * @param valueTypeOrClass the type or class of the given value. + */ + isReadOnly(valueTypeOrClass: string): boolean { + return valueTypeOrClass === this.readTextValueAsHtml || + valueTypeOrClass === this.readTextValueAsXml || + valueTypeOrClass === this.constants.GeomValue; } - } - - /** - * Equality checks with constants below are TEMPORARY until component is implemented. - * Used so that the CRUD buttons do not show if a property doesn't have a value component. - */ - - /** - * Determines if the given value is readonly. - * - * @param valueTypeOrClass the type or class of the given value. - */ - isReadOnly(valueTypeOrClass: string): boolean { - return valueTypeOrClass === this.readTextValueAsHtml || - valueTypeOrClass === this.readTextValueAsXml || - valueTypeOrClass === this.constants.GeomValue; - } }