From 0c2a43d7b9420a7c9327d0975eef2b100fc97d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Kilchenmann?= Date: Fri, 29 Apr 2022 16:09:39 +0200 Subject: [PATCH] fix(ontology-editor): bring back the gui-attr for pulldown (DEV-856) (#719) * fix(ontology-editor): bring back the gui-attr for pulldown (DEV-856) * fix(ontology-editor): bring back the gui-attr for pulldown (DEV-856) * test(ontology-editor): bring back the gui-attr for pulldown (DEV-856) * style(ontology-editor): display whole id of prop or class * test(ontology-editor): test the list property edit function * refactor(ontology-editor): fix typos --- .../property-form.component.html | 4 +- .../property-form.component.spec.ts | 143 +++++++++++++++++- .../property-form/property-form.component.ts | 50 +++--- .../property-info.component.html | 2 +- .../resource-class-info.component.html | 2 +- src/assets/style/_elements.scss | 4 + 6 files changed, 173 insertions(+), 32 deletions(-) diff --git a/src/app/project/ontology/property-form/property-form.component.html b/src/app/project/ontology/property-form/property-form.component.html index 2a4d121a21..df55906f8e 100644 --- a/src/app/project/ontology/property-form/property-form.component.html +++ b/src/app/project/ontology/property-form/property-form.component.html @@ -79,7 +79,7 @@ {{guiAttrIcon}}  - Select list * + Select list {{item.labels[0].value}} @@ -94,7 +94,7 @@ {{guiAttrIcon}}  - Select resource class * + Select resource class {{item.label}} diff --git a/src/app/project/ontology/property-form/property-form.component.spec.ts b/src/app/project/ontology/property-form/property-form.component.spec.ts index 0da25649c4..f2aea01501 100644 --- a/src/app/project/ontology/property-form/property-form.component.spec.ts +++ b/src/app/project/ontology/property-form/property-form.component.spec.ts @@ -14,7 +14,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar'; import { By } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { MockOntology, ReadOntology } from '@dasch-swiss/dsp-js'; +import { ListNodeInfo, MockOntology, ReadOntology } from '@dasch-swiss/dsp-js'; import { TranslateModule } from '@ngx-translate/core'; import { of } from 'rxjs'; import { CacheService } from 'src/app/main/cache/cache.service'; @@ -124,6 +124,70 @@ class LinkHostComponent { } +/** + * test host component to simulate parent component + * Property is of type resource link + */ +@Component({ + template: '' +}) +class ListHostComponent { + + @ViewChild('propertyForm') propertyFormComponent: PropertyFormComponent; + + propertyInfo: PropertyInfoObject = { + 'propDef': { + 'id': 'http://0.0.0.0:3333/ontology/0001/anything/v2#hasOtherListItem', + 'subPropertyOf': ['http://api.knora.org/ontology/knora-api/v2#hasValue'], + 'comment': 'Andere listenelement', + 'label': 'Andere listenelement', + 'guiElement': 'http://api.knora.org/ontology/salsah-gui/v2#Pulldown', + 'subjectType': 'http://0.0.0.0:3333/ontology/0001/anything/v2#Thing', + 'objectType': 'http://api.knora.org/ontology/knora-api/v2#ListValue', + 'isLinkProperty': false, + 'isLinkValueProperty': false, + 'isEditable': true, + 'guiAttributes': ['hlist='], + 'comments': [{ + 'language': 'de', + 'value': 'Andere listenelement' + }, { + 'language': 'en', + 'value': 'Other list element' + }, { + 'language': 'fr', + 'value': 'Autre elément de liste' + }, { + 'language': 'it', + 'value': 'Altra elemento di lista' + }], + 'labels': [{ + 'language': 'de', + 'value': 'Andere listenelement' + }, { + 'language': 'en', + 'value': 'Other list element' + }, { + 'language': 'fr', + 'value': 'Autre elément de liste' + }, { + 'language': 'it', + 'value': 'Altra elemento di lista' + }] + }, + 'propType': { + 'icon': 'arrow_drop_down_circle', + 'label': 'Dropdown', + 'description': 'Dropdown menu with values from predefined list', + 'subPropOf': 'http://api.knora.org/ontology/knora-api/v2#hasValue', + 'objectType': 'http://api.knora.org/ontology/knora-api/v2#ListValue', + 'guiEle': 'http://api.knora.org/ontology/salsah-gui/v2#Pulldown', + 'group': 'List' + } + }; + +} + describe('PropertyFormComponent', () => { let simpleTextHostComponent: SimpleTextHostComponent; let simpleTextHostFixture: ComponentFixture; @@ -131,6 +195,9 @@ describe('PropertyFormComponent', () => { let linkHostComponent: LinkHostComponent; let linkHostFixture: ComponentFixture; + let listHostComponent: ListHostComponent; + let listHostFixture: ComponentFixture; + beforeEach(waitForAsync(() => { const cacheServiceSpyOnto = jasmine.createSpyObj('CacheServiceOnto', ['get']); @@ -145,6 +212,7 @@ describe('PropertyFormComponent', () => { TestBed.configureTestingModule({ declarations: [ LinkHostComponent, + ListHostComponent, SimpleTextHostComponent, PropertyFormComponent ], @@ -183,16 +251,66 @@ describe('PropertyFormComponent', () => { })); beforeEach(() => { - const cacheSpyOnto = TestBed.inject(CacheService); // mock cache service for currentOntology - (cacheSpyOnto as jasmine.SpyObj).get.and.callFake( + const cacheSpyOnto = TestBed.inject(CacheService); + (cacheSpyOnto as jasmine.SpyObj).get.withArgs('currentOntology').and.callFake ( () => { const response: ReadOntology = MockOntology.mockReadOntology('http://0.0.0.0:3333/ontology/0001/anything/v2'); return of(response); } ); + // mock cache service for currentOntologyLists + const cacheSpyLists = TestBed.inject(CacheService); + (cacheSpyLists as jasmine.SpyObj).get.withArgs('currentOntologyLists').and.callFake( + () => { + const response: ListNodeInfo[] = [{ + 'comments': [], + 'id': 'http://rdfh.ch/lists/0001/otherTreeList', + 'isRootNode': true, + 'labels': [{ + 'language': 'en', + 'value': 'Tree list root' + }], + 'projectIri': 'http://rdfh.ch/projects/0001' + }, { + 'comments': [{ + 'language': 'en', + 'value': 'a list that is not in used in ontology or data' + }], + 'id': 'http://rdfh.ch/lists/0001/notUsedList', + 'isRootNode': true, + 'labels': [{ + 'language': 'de', + 'value': 'unbenutzte Liste' + }, { + 'language': 'en', + 'value': 'a list that is not used' + }], + 'name': 'notUsedList', + 'projectIri': 'http://rdfh.ch/projects/0001' + }, { + 'comments': [{ + 'language': 'en', + 'value': 'Anything Tree List' + }], + 'id': 'http://rdfh.ch/lists/0001/treeList', + 'isRootNode': true, + 'labels': [{ + 'language': 'de', + 'value': 'Listenwurzel' + }, { + 'language': 'en', + 'value': 'Tree list root' + }], + 'name': 'treelistroot', + 'projectIri': 'http://rdfh.ch/projects/0001' + }]; + return of(response); + } + ); + // simple text simpleTextHostFixture = TestBed.createComponent(SimpleTextHostComponent); simpleTextHostComponent = simpleTextHostFixture.componentInstance; @@ -207,6 +325,12 @@ describe('PropertyFormComponent', () => { expect(linkHostComponent).toBeTruthy(); + // list + listHostFixture = TestBed.createComponent(ListHostComponent); + listHostComponent = listHostFixture.componentInstance; + listHostFixture.detectChanges(); + + expect(listHostComponent).toBeTruthy(); }); it('should create an instance', () => { @@ -257,17 +381,26 @@ describe('PropertyFormComponent', () => { }); - it('expect link to other resource called "Thing"', () => { + it('expect link to other resource called "Thing" ( = guiAttribute)', () => { expect(linkHostComponent.propertyFormComponent).toBeTruthy(); expect(linkHostComponent.propertyFormComponent.propertyInfo.propDef).toBeDefined(); expect(linkHostComponent.propertyFormComponent.propertyInfo.propType).toBeDefined(); const form = linkHostComponent.propertyFormComponent.propertyForm; - expect(form.controls['guiAttr'].value).toEqual('http://0.0.0.0:3333/ontology/0001/anything/v2#Thing'); }); + it('expect link to List called "Tree list root" ( = guiAttribute)', () => { + expect(listHostComponent.propertyFormComponent).toBeTruthy(); + expect(listHostComponent.propertyFormComponent.propertyInfo.propDef).toBeDefined(); + expect(listHostComponent.propertyFormComponent.propertyInfo.propType).toBeDefined(); + + const form = listHostComponent.propertyFormComponent.propertyForm; + expect(form.controls['guiAttr'].value).toEqual('http://rdfh.ch/lists/0001/otherTreeList'); + + }); + it('expect "required" toggle switch (cardinality) to be disabled', () => { expect(simpleTextHostComponent.propertyFormComponent).toBeTruthy(); expect(simpleTextHostComponent.propertyFormComponent.propertyInfo.propDef).toBeDefined(); diff --git a/src/app/project/ontology/property-form/property-form.component.ts b/src/app/project/ontology/property-form/property-form.component.ts index f77ce01b66..6296a9f04a 100644 --- a/src/app/project/ontology/property-form/property-form.component.ts +++ b/src/app/project/ontology/property-form/property-form.component.ts @@ -337,31 +337,35 @@ export class PropertyFormComponent implements OnInit { // disable the input and set the validator as not required this.propertyForm.controls['guiAttr'].disable(); - switch (type.guiEle) { - // prop type is a list - case Constants.GuiList: - case Constants.GuiRadio: - this.showGuiAttr = true; - // gui attribute value for lists looks as follow: hlist= - // get index from guiAttr array where value starts with hlist= - const i = this.guiAttributes.findIndex(element => element.includes('hlist')); - // find content beteween pointy brackets to get list iri - const re = /\<([^)]+)\>/; - const listIri = this.guiAttributes[i].match(re)[1]; - - this.propertyForm.controls['guiAttr'].setValue(listIri); - break; - - // prop type is resource pointer: link to or part of - case Constants.GuiSearchbox: - this.showGuiAttr = true; - this.propertyForm.controls['guiAttr'].setValue(this.propertyInfo.propDef.objectType); - break; - - default: - this.showGuiAttr = false; + if (type.objectType) { + switch (type.objectType) { + // prop type is a list + case Constants.ListValue: + this.showGuiAttr = true; + // gui attribute value for lists looks as follows: hlist= + // get index from guiAttr array where value starts with hlist= + const i = this.guiAttributes.findIndex(element => element.includes('hlist')); + // find content between pointy brackets to get list iri + const re = /\<([^)]+)\>/; + const listIri = this.guiAttributes[i].match(re)[1]; + + this.propertyForm.controls['guiAttr'].setValue(listIri); + break; + + // prop type is resource pointer: link to or part of + case Constants.LinkValue: + this.showGuiAttr = true; + this.propertyForm.controls['guiAttr'].setValue(this.propertyInfo.propDef.objectType); + break; + + default: + this.showGuiAttr = false; + } + } else { + this.showGuiAttr = false; } + } else { // depending on the selected property type, // we have to define gui element attributes diff --git a/src/app/project/ontology/property-info/property-info.component.html b/src/app/project/ontology/property-info/property-info.component.html index 45cec8d31f..2d7265bfe7 100644 --- a/src/app/project/ontology/property-info/property-info.component.html +++ b/src/app/project/ontology/property-info/property-info.component.html @@ -20,7 +20,7 @@
- + {{propDef.id | split: '#':1}}  ·  diff --git a/src/app/project/ontology/resource-class-info/resource-class-info.component.html b/src/app/project/ontology/resource-class-info/resource-class-info.component.html index c5490ed313..39dc1827cd 100644 --- a/src/app/project/ontology/resource-class-info/resource-class-info.component.html +++ b/src/app/project/ontology/resource-class-info/resource-class-info.component.html @@ -7,7 +7,7 @@ {{resourceClass.label | appTruncate: 24}} - + {{resourceClass.id | split: '#':1}}  ·  diff --git a/src/assets/style/_elements.scss b/src/assets/style/_elements.scss index 7dcc6cc61a..1d2e58c35f 100644 --- a/src/assets/style/_elements.scss +++ b/src/assets/style/_elements.scss @@ -769,6 +769,10 @@ $gc-small: $form-width - $gc-large - 4; font-size: 11px; } +.wide-tooltip { + max-width: unset !important; +} + .annotation-tooltip { p {