diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 9cfd0e98af..1fcbd3fa85 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -21,78 +21,77 @@ import { AngularSplitModule } from 'angular-split';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { AccountComponent } from './user/account/account.component';
+import { AddGroupComponent } from './project/permission/add-group/add-group.component';
+import { AddressTemplateComponent } from './project/board/address-template/address-template.component';
+import { AddUserComponent } from './project/collaboration/add-user/add-user.component';
+import { AttributionTabViewComponent } from './project/board/attribution-tab-view/attribution-tab-view.component';
+import { BoardComponent } from './project/board/board.component';
+import { CollaborationComponent } from './project/collaboration/collaboration.component';
+import { CollectionListComponent } from './user/collection-list/collection-list.component';
+import { ContactsTabViewComponent } from './project/board/contacts-tab-view/contacts-tab-view.component';
import { CookiePolicyComponent } from './main/cookie-policy/cookie-policy.component';
-import { DialogHeaderComponent } from './main/dialog/dialog-header/dialog-header.component';
+import { DashboardComponent } from './user/dashboard/dashboard.component';
+import { DatasetTabViewComponent } from './project/board/dataset-tab-view/dataset-tab-view.component';
import { DialogComponent } from './main/dialog/dialog.component';
-import { ExternalLinksDirective } from './main/directive/external-links.directive';
-import { InvalidControlScrollDirective } from './main/directive/invalid-control-scroll.directive';
+import { DialogHeaderComponent } from './main/dialog/dialog-header/dialog-header.component';
+import { EditListItemComponent } from './project/list/list-item-form/edit-list-item/edit-list-item.component';
import { ErrorComponent } from './main/error/error.component';
+import { ExternalLinksDirective } from './main/directive/external-links.directive';
import { FooterComponent } from './main/footer/footer.component';
import { GridComponent } from './main/grid/grid.component';
+import { GroupsComponent } from './system/groups/groups.component';
+import { GroupsListComponent } from './system/groups/groups-list/groups-list.component';
import { HeaderComponent } from './main/header/header.component';
import { HelpComponent } from './main/help/help.component';
+import { InvalidControlScrollDirective } from './main/directive/invalid-control-scroll.directive';
+import { ListComponent } from './project/list/list.component';
+import { ListInfoFormComponent } from './project/list/list-info-form/list-info-form.component';
+import { ListItemComponent } from './project/list/list-item/list-item.component';
+import { ListItemFormComponent } from './project/list/list-item-form/list-item-form.component';
import { LoginComponent } from './main/login/login.component';
import { MainComponent } from './main/main.component';
-import { SelectLanguageComponent } from './main/select-language/select-language.component';
import { MaterialModule } from './material-module';
-import { AddressTemplateComponent } from './project/board/address-template/address-template.component';
-import { AttributionTabViewComponent } from './project/board/attribution-tab-view/attribution-tab-view.component';
-import { BoardComponent } from './project/board/board.component';
-import { ContactsTabViewComponent } from './project/board/contacts-tab-view/contacts-tab-view.component';
-import { DatasetTabViewComponent } from './project/board/dataset-tab-view/dataset-tab-view.component';
+import { MembershipComponent } from './user/membership/membership.component';
+import { OntologyComponent } from './project/ontology/ontology.component';
+import { OntologyFormComponent } from './project/ontology/ontology-form/ontology-form.component';
+import { OntologyVisualizerComponent } from './project/ontology/ontology-visualizer/ontology-visualizer.component';
import { OrganisationTemplateComponent } from './project/board/organisation-template/organisation-template.component';
+import { PasswordFormComponent } from './user/user-form/password-form/password-form.component';
+import { PermissionComponent } from './project/permission/permission.component';
import { PersonTemplateComponent } from './project/board/person-template/person-template.component';
+import { ProfileComponent } from './user/profile/profile.component';
+import { ProjectComponent } from './project/project.component';
+import { ProjectFormComponent } from './project/project-form/project-form.component';
+import { ProjectsComponent } from './system/projects/projects.component';
+import { ProjectsListComponent } from './system/projects/projects-list/projects-list.component';
import { ProjectTabViewComponent } from './project/board/project-tab-view/project-tab-view.component';
-import { TermsTabViewComponent } from './project/board/terms-tab-view/terms-tab-view.component';
-import { UrlTemplateComponent } from './project/board/url-template/url-template.component';
-import { AddUserComponent } from './project/collaboration/add-user/add-user.component';
-import { CollaborationComponent } from './project/collaboration/collaboration.component';
-import { SelectGroupComponent } from './project/collaboration/select-group/select-group.component';
-import { ListInfoFormComponent } from './project/list/list-info-form/list-info-form.component';
-import { EditListItemComponent } from './project/list/list-item-form/edit-list-item/edit-list-item.component';
-import { ListItemFormComponent } from './project/list/list-item-form/list-item-form.component';
-import { ListItemComponent } from './project/list/list-item/list-item.component';
-import { ListComponent } from './project/list/list.component';
-import { OntologyFormComponent } from './project/ontology/ontology-form/ontology-form.component';
-import { OntologyVisualizerComponent } from './project/ontology/ontology-visualizer/ontology-visualizer.component';
-import { VisualizerComponent } from './project/ontology/ontology-visualizer/visualizer/visualizer.component';
-import { OntologyComponent } from './project/ontology/ontology.component';
+import { PropertiesComponent } from './workspace/resource/properties/properties.component';
import { PropertyFormComponent } from './project/ontology/property-form/property-form.component';
import { PropertyInfoComponent } from './project/ontology/property-info/property-info.component';
import { ResourceClassFormComponent } from './project/ontology/resource-class-form/resource-class-form.component';
import { ResourceClassInfoComponent } from './project/ontology/resource-class-info/resource-class-info.component';
import { ResourceClassPropertyFormComponent } from './project/ontology/resource-class-property-form/resource-class-property-form.component';
-import { AddGroupComponent } from './project/permission/add-group/add-group.component';
-import { PermissionComponent } from './project/permission/permission.component';
-import { ProjectFormComponent } from './project/project-form/project-form.component';
-import { ProjectComponent } from './project/project.component';
-import { GroupsListComponent } from './system/groups/groups-list/groups-list.component';
-import { GroupsComponent } from './system/groups/groups.component';
-import { ProjectsListComponent } from './system/projects/projects-list/projects-list.component';
-import { ProjectsComponent } from './system/projects/projects.component';
-import { SystemComponent } from './system/system.component';
-import { UsersListComponent } from './system/users/users-list/users-list.component';
-import { UsersComponent } from './system/users/users.component';
-import { AccountComponent } from './user/account/account.component';
-import { CollectionListComponent } from './user/collection-list/collection-list.component';
-import { DashboardComponent } from './user/dashboard/dashboard.component';
-import { MembershipComponent } from './user/membership/membership.component';
-import { ProfileComponent } from './user/profile/profile.component';
-import { PasswordFormComponent } from './user/user-form/password-form/password-form.component';
-import { UserFormComponent } from './user/user-form/user-form.component';
-import { UserMenuComponent } from './user/user-menu/user-menu.component';
-import { UserComponent } from './user/user.component';
+import { ResourceComponent } from './workspace/resource/resource.component';
import { ResourceInstanceFormComponent } from './workspace/resource/resource-instance-form/resource-instance-form.component';
+import { ResultsComponent } from './workspace/results/results.component';
+import { SelectGroupComponent } from './project/collaboration/select-group/select-group.component';
+import { SelectLanguageComponent } from './main/select-language/select-language.component';
import { SelectOntologyComponent } from './workspace/resource/resource-instance-form/select-ontology/select-ontology.component';
import { SelectProjectComponent } from './workspace/resource/resource-instance-form/select-project/select-project.component';
import { SelectPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/select-properties.component';
-import { SwitchPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/switch-properties/switch-properties.component';
import { SelectResourceClassComponent } from './workspace/resource/resource-instance-form/select-resource-class/select-resource-class.component';
-import { ResourceComponent } from './workspace/resource/resource.component';
-import { ResultsComponent } from './workspace/results/results.component';
-import { ResourceToolbarComponent } from './workspace/resource/resource-toolbar/resource-toolbar.component';
-import { ResourcePropertiesComponent } from './workspace/resource/resource-properties/resource-properties.component';
import { StillImageComponent } from './workspace/resource/representation/still-image/still-image.component';
+import { SwitchPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/switch-properties/switch-properties.component';
+import { SystemComponent } from './system/system.component';
+import { TermsTabViewComponent } from './project/board/terms-tab-view/terms-tab-view.component';
+import { UrlTemplateComponent } from './project/board/url-template/url-template.component';
+import { UserComponent } from './user/user.component';
+import { UserFormComponent } from './user/user-form/user-form.component';
+import { UserMenuComponent } from './user/user-menu/user-menu.component';
+import { UsersComponent } from './system/users/users.component';
+import { UsersListComponent } from './system/users/users-list/users-list.component';
+import { VisualizerComponent } from './project/ontology/ontology-visualizer/visualizer/visualizer.component';
// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
@@ -146,6 +145,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
ProjectsComponent,
ProjectsListComponent,
ProjectTabViewComponent,
+ PropertiesComponent,
PropertyFormComponent,
PropertyInfoComponent,
ResourceClassFormComponent,
@@ -160,6 +160,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
SelectProjectComponent,
SelectPropertiesComponent,
SelectResourceClassComponent,
+ StillImageComponent,
SwitchPropertiesComponent,
SystemComponent,
TermsTabViewComponent,
@@ -170,9 +171,6 @@ export function httpLoaderFactory(httpClient: HttpClient) {
UsersComponent,
UsersListComponent,
VisualizerComponent,
- ResourceToolbarComponent,
- ResourcePropertiesComponent,
- StillImageComponent,
],
imports: [
AppRoutingModule,
diff --git a/src/app/workspace/resource/properties/properties.component.html b/src/app/workspace/resource/properties/properties.component.html
new file mode 100644
index 0000000000..14574ff46a
--- /dev/null
+++ b/src/app/workspace/resource/properties/properties.component.html
@@ -0,0 +1,126 @@
+
+
+
+
+
+ {{resource.res.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This resource belongs to the project
+
+ {{project?.shortname}}
+ open_in_new
+
+
+
+
+ Created
+ by {{(user.username ? user.username : user.givenName + ' ' + user.familyName)}}
+ on {{resource.res.creationDate | date}}
+
+
+
+
+
+
+
+
+
+
+
0 )"
+ [class.border-bottom]="prop.values && !last"
+ class="property">
+
+
+
+ {{prop.propDef.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The resource {{resource?.res.resourceClassLabel}} has no defined
+ properties.
+
diff --git a/src/app/workspace/resource/resource-properties/resource-properties.component.scss b/src/app/workspace/resource/properties/properties.component.scss
similarity index 68%
rename from src/app/workspace/resource/resource-properties/resource-properties.component.scss
rename to src/app/workspace/resource/properties/properties.component.scss
index 0de3b07816..19ab7298c5 100644
--- a/src/app/workspace/resource/resource-properties/resource-properties.component.scss
+++ b/src/app/workspace/resource/properties/properties.component.scss
@@ -1,27 +1,73 @@
+@import "../../../../assets/style/config";
+
+// toolbar
+.toolbar,
+.infobar {
+ display: flex;
+ box-sizing: border-box;
+ flex-direction: row;
+ align-items: center;
+ white-space: nowrap;
+ padding: 0 16px;
+ width: 100%;
+ color: rgba(0, 0, 0, 0.87);
+}
+.toolbar {
+ background: whitesmoke;
+
+ .label {
+ margin: 0 !important;
+ max-width: 48%;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+}
+
+.infobar {
+ height: 24px;
+}
+
+.clipboard-arkurl {
+ width: 264px;
+ height: 32px;
+ border: 1px solid rgba(0, 0, 0, 0.35);
+ border-radius: 4px 0 0 4px;
+}
+.ark-url-label {
+ margin-bottom: 8px;
+}
+.btn-copy-arkurl {
+ border-radius: 0 4px 4px 0;
+ background-color: rgba(0, 0, 0, 0.35);
+}
+
+//
+// list of properties
.border-bottom {
- border-bottom: 1px solid rgba(33,33,33,.1);
+ border-bottom: 1px solid rgba(33, 33, 33, 0.1);
}
// smaller buttons: add value and value info
.info,
.create {
- cursor: pointer;
- border: none;
- padding: 0em;
- outline: none;
- background-color: transparent;
- color: #000000;
+ cursor: pointer;
+ border: none;
+ padding: 0em;
+ outline: none;
+ background-color: transparent;
+ color: #000000;
}
.info .material-icons,
.create .material-icons {
- font-size: 18px;
+ font-size: 18px;
}
.info .mat-icon,
.create .mat-icon {
- width: 18px;
- height: 18px;
+ width: 18px;
+ height: 18px;
}
// properties container with property item and property value items
diff --git a/src/app/workspace/resource/resource-properties/resource-properties.component.spec.ts b/src/app/workspace/resource/properties/properties.component.spec.ts
similarity index 50%
rename from src/app/workspace/resource/resource-properties/resource-properties.component.spec.ts
rename to src/app/workspace/resource/properties/properties.component.spec.ts
index 70c4e67127..502db0e208 100644
--- a/src/app/workspace/resource/resource-properties/resource-properties.component.spec.ts
+++ b/src/app/workspace/resource/properties/properties.component.spec.ts
@@ -1,6 +1,9 @@
+import { ClipboardModule } from '@angular/cdk/clipboard';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MatIconModule } from '@angular/material/icon';
+import { MatMenuModule } from '@angular/material/menu';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
@@ -9,7 +12,10 @@ import {
Constants,
IHasPropertyWithPropertyDefinition,
KnoraApiConnection,
+ MockProjects,
MockResource,
+ MockUsers,
+ ProjectsEndpointAdmin,
ReadLinkValue,
ReadResource,
ReadValue,
@@ -24,46 +30,33 @@ import {
EmitEvent,
Events,
PropertyInfoValues,
+ UserService,
ValueOperationEventService
} from '@dasch-swiss/dsp-ui';
-import { Subscription } from 'rxjs';
+import { of, Subscription } from 'rxjs';
import { TestConfig } from 'test.config';
-import { ResourcePropertiesComponent } from './resource-properties.component';
+import { DspResource } from '../dsp-resource';
+import { PropertiesComponent } from './properties.component';
/**
* test host component to simulate parent component.
*/
@Component({
template: `
-
- `
+
+ `
})
class TestPropertyParentComponent implements OnInit, OnDestroy {
- @ViewChild('propView') resourcePropertiesComponent: ResourcePropertiesComponent;
+ @ViewChild('propView') propertiesComponent: PropertiesComponent;
- parentResource: ReadResource;
-
- propArray: PropertyInfoValues[] = [];
-
- systemPropArray: SystemPropertyDefinition[] = [];
-
- showAllProps = false;
+ parentResource: DspResource;
voeSubscriptions: Subscription[] = [];
myNum = 0;
- linkValClicked: ReadLinkValue;
-
- linkValHovered: ReadLinkValue;
-
constructor(public _valueOperationEventService: ValueOperationEventService) { }
ngOnInit() {
@@ -73,25 +66,25 @@ class TestPropertyParentComponent implements OnInit, OnDestroy {
MockResource.getTestThing().subscribe(
(response: ReadResource) => {
- this.parentResource = response;
+ this.parentResource = new DspResource(response);
// gather resource property information
- this.propArray = this.parentResource.entityInfo.classes[this.parentResource.type].getResourcePropertiesList().map(
+ this.parentResource.resProps = this.parentResource.res.entityInfo.classes[this.parentResource.res.type].getResourcePropertiesList().map(
(prop: IHasPropertyWithPropertyDefinition) => {
const propInfoAndValues: PropertyInfoValues = {
propDef: prop.propertyDefinition,
guiDef: prop,
- values: this.parentResource.getValues(prop.propertyIndex)
+ values: this.parentResource.res.getValues(prop.propertyIndex)
};
return propInfoAndValues;
}
);
// sort properties by guiOrder
- this.propArray.sort((a, b) => (a.guiDef.guiOrder > b.guiDef.guiOrder) ? 1 : -1);
+ this.parentResource.resProps.sort((a, b) => (a.guiDef.guiOrder > b.guiDef.guiOrder) ? 1 : -1);
// get system property information
- this.systemPropArray = this.parentResource.entityInfo.getPropertyDefinitionsByType(SystemPropertyDefinition);
+ this.parentResource.systemProps = this.parentResource.res.entityInfo.getPropertyDefinitionsByType(SystemPropertyDefinition);
},
(error: ApiResponseError) => {
@@ -105,14 +98,6 @@ class TestPropertyParentComponent implements OnInit, OnDestroy {
this.voeSubscriptions.forEach(sub => sub.unsubscribe());
}
}
-
- internalLinkClicked(linkVal: ReadLinkValue) {
- this.linkValClicked = linkVal;
- }
-
- internalLinkHovered(linkVal: ReadLinkValue) {
- this.linkValHovered = linkVal;
- }
}
/**
@@ -124,9 +109,8 @@ class TestPropertyParentComponent implements OnInit, OnDestroy {
})
class TestDisplayValueComponent {
- @Input() parentResource: ReadResource;
+ @Input() parentResource: DspResource;
@Input() displayValue: ReadValue;
- @Input() propArray: PropertyInfoValues[];
@Input() configuration?: object;
@Output() referredResourceClicked: EventEmitter = new EventEmitter();
@@ -143,21 +127,33 @@ class TestDisplayValueComponent {
})
class TestAddValueComponent {
- @Input() parentResource: ReadResource;
+ @Input() parentResource: DspResource;
@Input() resourcePropertyDefinition: ResourcePropertyDefinition;
}
-describe('ResourcePropertiesComponent', () => {
+describe('PropertiesComponent', () => {
let testHostComponent: TestPropertyParentComponent;
let testHostFixture: ComponentFixture;
let voeService: ValueOperationEventService;
beforeEach(waitForAsync(() => {
+
+ const adminSpyObj = {
+ admin: {
+ projectsEndpoint: jasmine.createSpyObj('projectsEndpoint', ['getProjectByIri'])
+ }
+ };
+
+ const userServiceSpy = jasmine.createSpyObj('UserService', ['getUser']);
+
TestBed.configureTestingModule({
imports: [
+ ClipboardModule,
DspActionModule,
MatIconModule,
+ MatMenuModule,
+ MatSnackBarModule,
MatTooltipModule,
RouterTestingModule
],
@@ -165,7 +161,7 @@ describe('ResourcePropertiesComponent', () => {
TestPropertyParentComponent,
TestDisplayValueComponent,
TestAddValueComponent,
- ResourcePropertiesComponent
+ PropertiesComponent
],
providers: [
ValueOperationEventService,
@@ -177,7 +173,15 @@ describe('ResourcePropertiesComponent', () => {
{
provide: DspApiConnectionToken,
useValue: new KnoraApiConnection(TestConfig.ApiConfig)
- }
+ },
+ {
+ provide: DspApiConnectionToken,
+ useValue: adminSpyObj
+ },
+ {
+ provide: UserService,
+ useValue: userServiceSpy
+ },
]
})
.compileComponents();
@@ -186,6 +190,28 @@ describe('ResourcePropertiesComponent', () => {
}));
beforeEach(() => {
+ const adminSpy = TestBed.inject(DspApiConnectionToken);
+
+ // mock getProjectByIri response
+ (adminSpy.admin.projectsEndpoint as jasmine.SpyObj).getProjectByIri.and.callFake(
+ () => {
+ const project = MockProjects.mockProject();
+ return of(project);
+ }
+ );
+
+ // mock getUserByIri response
+ const userSpy = TestBed.inject(UserService);
+
+ // mock getUserByIri response
+ (userSpy as jasmine.SpyObj).getUser.and.callFake(
+ () => {
+ const user = MockUsers.mockUser();
+
+ return of(user.body);
+ }
+ );
+
testHostFixture = TestBed.createComponent(TestPropertyParentComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
@@ -193,90 +219,111 @@ describe('ResourcePropertiesComponent', () => {
expect(testHostComponent).toBeTruthy();
});
+ it('should get the resource testding', () => {
- it('should get 25 properties', () => {
-
- expect(testHostComponent.propArray).toBeTruthy();
- expect(testHostComponent.propArray.length).toBe(25);
+ expect(testHostComponent.parentResource).toBeTruthy();
+ expect(testHostComponent.parentResource.res.id).toEqual('http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw');
+ expect(testHostComponent.parentResource.res.label).toEqual('testding');
});
- it('should get the resource testding', () => {
+ describe('Toolbar', () => {
+ let hostCompDe;
+ let propertyToolbarComponentDe;
- expect(testHostComponent.parentResource).toBeTruthy();
- expect(testHostComponent.parentResource.id).toEqual('http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw');
- expect(testHostComponent.parentResource.label).toEqual('testding');
+ beforeEach(() => {
+ expect(testHostComponent.propertiesComponent).toBeTruthy();
- });
+ hostCompDe = testHostFixture.debugElement;
- it('should display a text value among the property list', () => {
+ propertyToolbarComponentDe = hostCompDe.query(By.directive(PropertiesComponent));
- expect(testHostComponent.propArray[4].propDef.label).toEqual('Text');
- expect(testHostComponent.propArray[4].propDef.comment).toBe(undefined);
- expect(testHostComponent.propArray[4].guiDef.cardinality).toEqual(2);
- expect(testHostComponent.propArray[4].guiDef.guiOrder).toEqual(2);
- expect(testHostComponent.propArray[4].values[0].type).toEqual('http://api.knora.org/ontology/knora-api/v2#TextValue');
+ expect(testHostComponent).toBeTruthy();
- });
+ testHostFixture.detectChanges();
+ });
- it('should get some system properties', () => {
+ it('should have the label "testding"', () => {
+ const resLabelDebugElement = propertyToolbarComponentDe.query(By.css('h3.label'));
+ const resLabelNativeElement = resLabelDebugElement.nativeElement;
- expect(testHostComponent.systemPropArray).toBeTruthy();
- expect(testHostComponent.systemPropArray.length).toEqual(13);
+ expect(resLabelNativeElement.textContent.trim()).toBe('testding');
+ });
- // check if the first system property is an ARK url
- expect(testHostComponent.systemPropArray[0].label).toEqual('ARK URL');
+ it('should toggle list of properties', () => {
+ const resLabelDebugElement = propertyToolbarComponentDe.query(By.css('button.toggle-props'));
+ const resLabelNativeElement = resLabelDebugElement.nativeElement;
+ // the button contains an icon "unfold_more" and the text "Increase properties"
+ expect(resLabelNativeElement.textContent.trim()).toBe('unfold_moreShow all properties');
- });
+ resLabelNativeElement.click();
- it('should propagate a click event on a link value', () => {
+ testHostFixture.detectChanges();
- const displayEdit = testHostFixture.debugElement.query(By.directive(TestDisplayValueComponent));
+ // the button contains an icon "unfold_less" and the text "Decrease properties"
+ expect(resLabelNativeElement.textContent.trim()).toBe('unfold_lessHide empty properties');
- const linkVal = new ReadLinkValue();
- linkVal.linkedResourceIri = 'testIri';
+ });
+ });
- expect(testHostComponent.linkValClicked).toBeUndefined();
+ // --> TODO: currently not possible to test copy to clipboard from Material Angular
+ // https://stackoverflow.com/questions/60337742/test-copy-to-clipboard-function
- (displayEdit.componentInstance as TestDisplayValueComponent).referredResourceClicked.emit(linkVal);
+ describe('List of properties', () => {
+ it('should get 25 properties', () => {
- expect(testHostComponent.linkValClicked.linkedResourceIri).toEqual('testIri');
+ expect(testHostComponent.parentResource.resProps).toBeTruthy();
+ expect(testHostComponent.parentResource.resProps.length).toBe(25);
- });
+ });
+
+ it('should get the resource testding', () => {
+
+ expect(testHostComponent.parentResource.res).toBeTruthy();
+ expect(testHostComponent.parentResource.res.id).toEqual('http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw');
+ expect(testHostComponent.parentResource.res.label).toEqual('testding');
- it('should propagate a hover event on a link value', () => {
+ });
- const displayEdit = testHostFixture.debugElement.query(By.directive(TestDisplayValueComponent));
+ it('should display a text value among the property list', () => {
- const linkVal = new ReadLinkValue();
- linkVal.linkedResourceIri = 'testIri';
+ expect(testHostComponent.parentResource.resProps[4].propDef.label).toEqual('Text');
+ expect(testHostComponent.parentResource.resProps[4].propDef.comment).toBe(undefined);
+ expect(testHostComponent.parentResource.resProps[4].guiDef.cardinality).toEqual(2);
+ expect(testHostComponent.parentResource.resProps[4].guiDef.guiOrder).toEqual(2);
+ expect(testHostComponent.parentResource.resProps[4].values[0].type).toEqual('http://api.knora.org/ontology/knora-api/v2#TextValue');
- expect(testHostComponent.linkValHovered).toBeUndefined();
+ });
- (displayEdit.componentInstance as TestDisplayValueComponent).referredResourceHovered.emit(linkVal);
+ it('should get some system properties', () => {
- expect(testHostComponent.linkValHovered.linkedResourceIri).toEqual('testIri');
+ expect(testHostComponent.parentResource.systemProps).toBeTruthy();
+ expect(testHostComponent.parentResource.systemProps.length).toEqual(13);
- });
+ // check if the first system property is an ARK url
+ expect(testHostComponent.parentResource.systemProps[0].label).toEqual('ARK URL');
- it('should trigger the callback when an event is emitted', () => {
+ });
- expect(testHostComponent.myNum).toEqual(0);
+ it('should trigger the callback when an event is emitted', () => {
- voeService.emit(new EmitEvent(Events.ValueAdded));
+ expect(testHostComponent.myNum).toEqual(0);
- expect(testHostComponent.myNum).toEqual(1);
- });
+ voeService.emit(new EmitEvent(Events.ValueAdded));
- it('should unsubscribe from changes when destroyed', () => {
- testHostComponent.voeSubscriptions.forEach(sub => {
- expect(sub.closed).toBe(false);
+ expect(testHostComponent.myNum).toEqual(1);
});
- testHostFixture.destroy();
+ it('should unsubscribe from changes when destroyed', () => {
+ testHostComponent.voeSubscriptions.forEach(sub => {
+ expect(sub.closed).toBe(false);
+ });
+
+ testHostFixture.destroy();
- testHostComponent.voeSubscriptions.forEach(sub => {
- expect(sub.closed).toBe(true);
+ testHostComponent.voeSubscriptions.forEach(sub => {
+ expect(sub.closed).toBe(true);
+ });
});
});
@@ -285,16 +332,16 @@ describe('ResourcePropertiesComponent', () => {
let propertyViewComponentDe;
beforeEach(() => {
- expect(testHostComponent.resourcePropertiesComponent).toBeTruthy();
+ expect(testHostComponent.propertiesComponent).toBeTruthy();
hostCompDe = testHostFixture.debugElement;
- propertyViewComponentDe = hostCompDe.query(By.directive(ResourcePropertiesComponent));
+ propertyViewComponentDe = hostCompDe.query(By.directive(PropertiesComponent));
expect(testHostComponent).toBeTruthy();
- testHostComponent.resourcePropertiesComponent.addButtonIsVisible = true;
- testHostComponent.resourcePropertiesComponent.addValueFormIsVisible = false;
+ testHostComponent.propertiesComponent.addButtonIsVisible = true;
+ testHostComponent.propertiesComponent.addValueFormIsVisible = false;
testHostFixture.detectChanges();
});
@@ -307,7 +354,9 @@ describe('ResourcePropertiesComponent', () => {
it('should show an add button under a property with a cardinality of 1 and does not have a value', () => {
// show all properties so that we can access properties with no values
- testHostComponent.showAllProps = true;
+ const toggleAllPropsElement = testHostFixture.debugElement.query(By.css('button.toggle-props'));
+ toggleAllPropsElement.nativeElement.click();
+
testHostFixture.detectChanges();
let addButtons = propertyViewComponentDe.queryAll(By.css('button.create'));
@@ -318,7 +367,7 @@ describe('ResourcePropertiesComponent', () => {
expect(addButtons.length).toEqual(17);
// remove value from the boolean property
- testHostComponent.propArray[9].values = [];
+ testHostComponent.parentResource.resProps[9].values = [];
testHostFixture.detectChanges();
@@ -351,31 +400,31 @@ describe('ResourcePropertiesComponent', () => {
it('should determine that adding a standoff link value is not allowed', () => {
- const standoffLinkVal = testHostComponent.propArray.filter(
+ const standoffLinkVal = testHostComponent.parentResource.resProps.filter(
propVal => propVal.propDef.id === Constants.HasStandoffLinkToValue
);
- expect(testHostComponent.resourcePropertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeFalsy();
+ expect(testHostComponent.propertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeFalsy();
});
it('should determine that adding a incoming link value is not allowed', () => {
- const standoffLinkVal = testHostComponent.propArray.filter(
+ const standoffLinkVal = testHostComponent.parentResource.resProps.filter(
propVal => propVal.propDef.id === 'http://api.knora.org/ontology/knora-api/v2#hasIncomingLinkValue'
);
- expect(testHostComponent.resourcePropertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeFalsy();
+ expect(testHostComponent.propertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeFalsy();
});
it('should determine that adding an int value is allowed', () => {
- const standoffLinkVal = testHostComponent.propArray.filter(
+ const standoffLinkVal = testHostComponent.parentResource.resProps.filter(
propVal => propVal.propDef.id === 'http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger'
);
- expect(testHostComponent.resourcePropertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeTruthy();
+ expect(testHostComponent.propertiesComponent.addValueIsAllowed(standoffLinkVal[0])).toBeTruthy();
});
diff --git a/src/app/workspace/resource/resource-properties/resource-properties.component.ts b/src/app/workspace/resource/properties/properties.component.ts
similarity index 70%
rename from src/app/workspace/resource/resource-properties/resource-properties.component.ts
rename to src/app/workspace/resource/properties/properties.component.ts
index 57b5299686..135fdbf7a0 100644
--- a/src/app/workspace/resource/resource-properties/resource-properties.component.ts
+++ b/src/app/workspace/resource/properties/properties.component.ts
@@ -1,79 +1,79 @@
+import { Component, EventEmitter, Inject, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core';
+import { MatSnackBar } from '@angular/material/snack-bar';
import {
- Component, EventEmitter,
- Inject,
- Input,
- OnDestroy,
- OnInit,
- Output,
- ViewChild
-} from '@angular/core';
-import {
+ ApiResponseData,
+ ApiResponseError,
CardinalityUtil,
Constants,
DeleteValue,
KnoraApiConnection,
PermissionUtil,
+ ProjectResponse,
ReadLinkValue,
- ReadResource,
+ ReadProject,
ReadResourceSequence,
ReadTextValueAsXml,
+ ReadUser,
ReadValue,
ResourcePropertyDefinition,
- SystemPropertyDefinition
+ UserResponse
} from '@dasch-swiss/dsp-js';
import {
AddedEventValue,
- AddValueComponent,
DeletedEventValue,
- DisplayEditComponent,
DspApiConnectionToken,
Events,
+ NotificationService,
PropertyInfoValues,
UpdatedEventValues,
+ UserService,
ValueOperationEventService,
ValueService
} from '@dasch-swiss/dsp-ui';
import { Subscription } from 'rxjs';
+import { DspResource } from '../dsp-resource';
@Component({
- selector: 'app-resource-properties',
- templateUrl: './resource-properties.component.html',
- styleUrls: ['./resource-properties.component.scss']
+ selector: 'app-properties',
+ templateUrl: './properties.component.html',
+ styleUrls: ['./properties.component.scss']
})
-export class ResourcePropertiesComponent implements OnInit, OnDestroy {
+export class PropertiesComponent implements OnInit, OnChanges, OnDestroy {
- @ViewChild('displayEdit') displayEditComponent: DisplayEditComponent;
- @ViewChild('addValue') addValueComponent: AddValueComponent;
/**
- * parent resource
- *
- * @param (parentResource)
+ * input `resource` of properties component:
+ * complete information about the current resource
*/
- @Input() parentResource: ReadResource;
+ @Input() resource: DspResource;
/**
- * array of property object with ontology class prop def, list of properties and corresponding values
- *
- * @param (propArray)
+ * input `displayProjectInfo` of properties component:
+ * display project info or not; "This resource belongs to project XYZ"
*/
- @Input() propArray: PropertyInfoValues[];
+ @Input() displayProjectInfo: false;
/**
- * array of system property object with list of system properties
- *
- * @param (systemPropArray)
+ * output `referredProjectClicked` of resource view component:
+ * can be used to go to project page
*/
- @Input() systemPropArray: SystemPropertyDefinition[];
+ @Output() referredProjectClicked: EventEmitter = new EventEmitter();
/**
- * show all properties, even if they don't have a value.
- *
- * @param (showAllProps)
+ * output `referredProjectHovered` of resource view component:
+ * can be used for preview when hovering on project
*/
- @Input() showAllProps = false;
+ @Output() referredProjectHovered: EventEmitter = new EventEmitter();
+ /**
+ * output `referredResourceClicked` of resource view component:
+ * can be used to open resource
+ */
@Output() referredResourceClicked: EventEmitter = new EventEmitter();
+ /**
+ * output `referredResourceHovered` of resource view component:
+ * can be used for preview when hovering on resource
+ */
@Output() referredResourceHovered: EventEmitter = new EventEmitter();
addButtonIsVisible: boolean; // used to toggle add value button
@@ -82,17 +82,25 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
valueOperationEventSubscriptions: Subscription[] = []; // array of ValueOperationEvent subscriptions
+ project: ReadProject;
+ user: ReadUser;
+
+ showAllProps = false; // show or hide empty properties
+
constructor(
@Inject(DspApiConnectionToken) private _dspApiConnection: KnoraApiConnection,
+ private _notification: NotificationService,
+ private _snackBar: MatSnackBar,
+ private _userService: UserService,
private _valueOperationEventService: ValueOperationEventService,
private _valueService: ValueService
) { }
- ngOnInit() {
- if (this.parentResource) {
+ ngOnInit(): void {
+ if (this.resource.res) {
// get user permissions
const allPermissions = PermissionUtil.allUserPermissions(
- this.parentResource.userHasPermission as 'RV' | 'V' | 'M' | 'D' | 'CR'
+ this.resource.res.userHasPermission as 'RV' | 'V' | 'M' | 'D' | 'CR'
);
// if user has modify permissions, set addButtonIsVisible to true so the user see's the add button
@@ -123,6 +131,25 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
));
}
+ ngOnChanges(): void {
+ // get project information
+ this._dspApiConnection.admin.projectsEndpoint.getProjectByIri(this.resource.res.attachedToProject).subscribe(
+ (response: ApiResponseData) => {
+ this.project = response.body.project;
+ },
+ (error: ApiResponseError) => {
+ this._notification.openSnackBar(error);
+ }
+ );
+
+ // get user information
+ this._userService.getUser(this.resource.res.attachedToUser).subscribe(
+ (response: UserResponse) => {
+ this.user = response.user;
+ }
+ );
+ }
+
ngOnDestroy() {
// unsubscribe from the event bus when component is destroyed
// if (this.valueOperationEventSubscription !== undefined) {
@@ -134,6 +161,43 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
}
}
+ /**
+ * opens project
+ * @param linkValue
+ */
+ openProject(project: ReadProject) {
+ window.open('/project/' + project.shortcode, '_blank');
+ }
+
+ previewProject(project: ReadProject) {
+ // --> TODO: pop up project preview on hover
+ }
+
+ /**
+ * opens resource
+ * @param linkValue
+ */
+ openResource(linkValue: ReadLinkValue) {
+ window.open('/resource/' + encodeURIComponent(linkValue.linkedResource.id), '_blank');
+ }
+
+ previewResource(linkValue: ReadLinkValue) {
+ // --> TODO: pop up resource preview on hover
+ }
+
+ /**
+ * display message to confirm the copy of the citation link (ARK URL)
+ */
+ openSnackBar() {
+ const message = 'Copied to clipboard!';
+ const action = 'Citation Link';
+ this._snackBar.open(message, action, {
+ duration: 3000,
+ horizontalPosition: 'center',
+ verticalPosition: 'top'
+ });
+ }
+
/**
* called from the template when the user clicks on the add button
*/
@@ -165,7 +229,7 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
}
const isAllowed = CardinalityUtil.createValueForPropertyAllowed(
- prop.propDef.id, prop.values.length, this.parentResource.entityInfo.classes[this.parentResource.type]);
+ prop.propDef.id, prop.values.length, this.resource.res.entityInfo.classes[this.resource.res.type]);
// check if:
// cardinality allows for a value to be added
@@ -180,8 +244,8 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
* @param valueToAdd the value to add to the end of the values array of the filtered property
*/
addValueToResource(valueToAdd: ReadValue): void {
- if (this.propArray) {
- this.propArray
+ if (this.resource.resProps) {
+ this.resource.resProps
.filter(propInfoValueArray =>
propInfoValueArray.propDef.id === valueToAdd.property) // filter to the correct property
.forEach(propInfoValue =>
@@ -190,6 +254,7 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
this._updateStandoffLinkValue();
}
} else {
+ // --> TODO: better error handler!
console.error('No properties exist for this resource');
}
}
@@ -201,8 +266,8 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
* @param updatedValue the value to replace valueToReplace with
*/
updateValueInResource(valueToReplace: ReadValue, updatedValue: ReadValue): void {
- if (this.propArray && updatedValue !== null) {
- this.propArray
+ if (this.resource.resProps && updatedValue !== null) {
+ this.resource.resProps
.filter(propInfoValueArray =>
propInfoValueArray.propDef.id === valueToReplace.property) // filter to the correct property
.forEach(filteredpropInfoValueArray => {
@@ -226,8 +291,8 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
* @param valueToDelete the value to remove from the values array of the filtered property
*/
deleteValueFromResource(valueToDelete: DeleteValue): void {
- if (this.propArray) {
- this.propArray
+ if (this.resource.resProps) {
+ this.resource.resProps
.filter(propInfoValueArray => // filter to the correct type
this._valueService.compareObjectTypeWithValueType(propInfoValueArray.propDef.objectType, valueToDelete.type))
.forEach(filteredpropInfoValueArray => {
@@ -252,7 +317,7 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
*/
private _updateStandoffLinkValue(): void {
- if (this.parentResource === undefined) {
+ if (this.resource.res === undefined) {
// this should never happen:
// if the user was able to click on a standoff link,
// then the resource must have been initialised before.
@@ -265,7 +330,7 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
?res knora-api:isMainResource true .
?res knora-api:hasStandoffLinkTo ?target .
} WHERE {
- BIND(<${this.parentResource.id}> as ?res) .
+ BIND(<${this.resource.res.id}> as ?res) .
OPTIONAL {
?res knora-api:hasStandoffLinkTo ?target .
}
@@ -283,7 +348,7 @@ export class ResourcePropertiesComponent implements OnInit, OnDestroy {
const newStandoffLinkVals = res.resources[0].getValuesAs(Constants.HasStandoffLinkToValue, ReadLinkValue);
- this.propArray.filter(
+ this.resource.resProps.filter(
resPropInfoVal => (resPropInfoVal.propDef.id === Constants.HasStandoffLinkToValue)
).forEach(
standoffLinkResPropInfoVal => {
diff --git a/src/app/workspace/resource/representation/still-image/still-image.component.scss b/src/app/workspace/resource/representation/still-image/still-image.component.scss
index 3129e07784..792bbacc74 100644
--- a/src/app/workspace/resource/representation/still-image/still-image.component.scss
+++ b/src/app/workspace/resource/representation/still-image/still-image.component.scss
@@ -21,6 +21,7 @@ $bright: #ccc;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
+ max-width: 50%;
}
.action {
diff --git a/src/app/workspace/resource/resource-properties/resource-properties.component.html b/src/app/workspace/resource/resource-properties/resource-properties.component.html
deleted file mode 100644
index ebdc0abcab..0000000000
--- a/src/app/workspace/resource/resource-properties/resource-properties.component.html
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
0 )"
- [class.border-bottom]="prop.values && !last"
- class="property">
-
-
-
- {{prop.propDef.label}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.html b/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.html
deleted file mode 100644
index 6846fc0dd6..0000000000
--- a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.html
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
- {{resource.label}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
This resource belongs to the project
-
- {{project?.shortname}}
- open_in_new
-
-
-
-
- Created
- by {{(user.username ? user.username : user.givenName + ' ' + user.familyName)}}
- on {{resource.creationDate | date}}
-
-
diff --git a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.scss b/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.scss
deleted file mode 100644
index f96e2bda13..0000000000
--- a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.scss
+++ /dev/null
@@ -1,37 +0,0 @@
-.toolbar,
-.infobar {
- display: flex;
- box-sizing: border-box;
- flex-direction: row;
- align-items: center;
- white-space: nowrap;
- padding: 0 16px;
- width: 100%;
- color: rgba(0, 0, 0, 0.87);
-
-}
-.toolbar {
- background: whitesmoke;
-
- .label {
- margin: 0 !important;
- max-width: 48%;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-}
-
-.clipboard-arkurl {
- width: 264px;
- height: 32px;
- border: 1px solid rgba(0, 0, 0, 0.35);
- border-radius: 4px 0 0 4px;
-}
-.ark-url-label {
- margin-bottom: 8px
-}
-.btn-copy-arkurl {
- border-radius: 0 4px 4px 0;
- background-color: rgba(0, 0, 0, 0.35);
-}
diff --git a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.spec.ts b/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.spec.ts
deleted file mode 100644
index c75be75874..0000000000
--- a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.spec.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-import { ClipboardModule } from '@angular/cdk/clipboard';
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
-import { FormsModule } from '@angular/forms';
-import { MatIconModule } from '@angular/material/icon';
-import { MatMenuModule } from '@angular/material/menu';
-import { MatSnackBarModule } from '@angular/material/snack-bar';
-import { MatTooltipModule } from '@angular/material/tooltip';
-import { By } from '@angular/platform-browser';
-import {
- ApiResponseError,
- MockProjects,
- MockResource,
- MockUsers,
- ProjectsEndpointAdmin,
- ReadResource
-} from '@dasch-swiss/dsp-js';
-import { DspApiConnectionToken, UserService } from '@dasch-swiss/dsp-ui';
-import { of } from 'rxjs';
-import { ResourceToolbarComponent } from './resource-toolbar.component';
-
-/**
- * test host component to simulate parent component
- */
-@Component({
- template: `
-
- `
-})
-class TestResourceParentComponent implements OnInit {
-
- @ViewChild('resToolbar') resourceToolbarComponent: ResourceToolbarComponent;
-
- parentResource: ReadResource;
-
- showAllProps = true;
-
- constructor() { }
-
- ngOnInit() {
-
- MockResource.getTestThing().subscribe(
- response => {
- this.parentResource = response;
- },
- (error: ApiResponseError) => {
- console.error('Error to get the mock resource', error);
- }
- );
- }
-
- toggleProps(show: boolean) {
- this.showAllProps = show;
- }
-}
-
-describe('ResourceToolbarComponent', () => {
- let testHostComponent: TestResourceParentComponent;
- let testHostFixture: ComponentFixture;
-
- beforeEach(waitForAsync(() => {
-
- const adminSpyObj = {
- admin: {
- projectsEndpoint: jasmine.createSpyObj('projectsEndpoint', ['getProjectByIri'])
- }
- };
-
- const userServiceSpy = jasmine.createSpyObj('UserService', ['getUser']);
-
- TestBed.configureTestingModule({
- declarations: [
- ResourceToolbarComponent,
- TestResourceParentComponent
- ],
- imports: [
- ClipboardModule,
- MatIconModule,
- MatMenuModule,
- MatSnackBarModule,
- MatTooltipModule,
- FormsModule
- ],
- providers: [
- {
- provide: DspApiConnectionToken,
- useValue: adminSpyObj
- },
- {
- provide: UserService,
- useValue: userServiceSpy
- },
- ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
-
- const adminSpy = TestBed.inject(DspApiConnectionToken);
-
- // mock getProjectByIri response
- (adminSpy.admin.projectsEndpoint as jasmine.SpyObj).getProjectByIri.and.callFake(
- () => {
- const project = MockProjects.mockProject();
- return of(project);
- }
- );
-
- // mock getUserByIri response
- const userSpy = TestBed.inject(UserService);
-
- // mock getUserByIri response
- (userSpy as jasmine.SpyObj).getUser.and.callFake(
- () => {
- const user = MockUsers.mockUser();
-
- return of(user.body);
- }
- );
-
- testHostFixture = TestBed.createComponent(TestResourceParentComponent);
- testHostComponent = testHostFixture.componentInstance;
- testHostFixture.detectChanges();
-
- expect(testHostComponent).toBeTruthy();
- });
-
- it('should get the resource testding', () => {
-
- expect(testHostComponent.parentResource).toBeTruthy();
- expect(testHostComponent.parentResource.id).toEqual('http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw');
- expect(testHostComponent.parentResource.label).toEqual('testding');
-
- });
-
- describe('Toolbar', () => {
- let hostCompDe;
- let propertyToolbarComponentDe;
-
- beforeEach(() => {
- expect(testHostComponent.resourceToolbarComponent).toBeTruthy();
-
- hostCompDe = testHostFixture.debugElement;
-
- propertyToolbarComponentDe = hostCompDe.query(By.directive(ResourceToolbarComponent));
-
- expect(testHostComponent).toBeTruthy();
-
- testHostFixture.detectChanges();
- });
-
- it('should have the label "testding"', () => {
- const resLabelDebugElement = propertyToolbarComponentDe.query(By.css('h3.label'));
- const resLabelNativeElement = resLabelDebugElement.nativeElement;
-
- expect(resLabelNativeElement.textContent.trim()).toBe('testding');
- });
-
- it('should toggle list of properties', () => {
- const resLabelDebugElement = propertyToolbarComponentDe.query(By.css('button.toggle-props'));
- const resLabelNativeElement = resLabelDebugElement.nativeElement;
- // the button contains an icon "unfold_less" and the text "Decrease properties"
- expect(resLabelNativeElement.textContent.trim()).toBe('unfold_lessHide empty properties');
-
- resLabelNativeElement.click();
-
- testHostFixture.detectChanges();
-
- // the button contains an icon "unfold_more" and the text "Increase properties"
- expect(resLabelNativeElement.textContent.trim()).toBe('unfold_moreShow all properties');
-
- });
- });
-
-
- // tODO: currently not possible to test copy to clipboard from Material Angular
- // https://stackoverflow.com/questions/60337742/test-copy-to-clipboard-function
-});
diff --git a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.ts b/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.ts
deleted file mode 100644
index 8b7b925bdb..0000000000
--- a/src/app/workspace/resource/resource-toolbar/resource-toolbar.component.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Component, EventEmitter, Inject, Input, OnChanges, Output } from '@angular/core';
-import { MatSnackBar } from '@angular/material/snack-bar';
-import { ApiResponseData, ApiResponseError, KnoraApiConnection, ProjectResponse, ReadProject, ReadResource, ReadUser, UserResponse } from '@dasch-swiss/dsp-js';
-import { DspApiConnectionToken, NotificationService, UserService } from '@dasch-swiss/dsp-ui';
-
-@Component({
- selector: 'app-resource-toolbar',
- templateUrl: './resource-toolbar.component.html',
- styleUrls: ['./resource-toolbar.component.scss']
-})
-export class ResourceToolbarComponent implements OnChanges {
-
- @Input() resource: ReadResource;
-
- @Input() showAllProps = false;
-
- @Output() toggleProps: EventEmitter = new EventEmitter();
-
- /**
- * output `referredProjectClicked` of resource view component:
- * can be used to go to project page
- */
- @Output() referredProjectClicked: EventEmitter = new EventEmitter();
-
- /**
- * output `referredProjectHovered` of resource view component:
- * can be used for preview when hovering on project
- */
- @Output() referredProjectHovered: EventEmitter = new EventEmitter();
-
- project: ReadProject;
- user: ReadUser;
-
- constructor(
- @Inject(DspApiConnectionToken) private _dspApiConnection: KnoraApiConnection,
- private _notification: NotificationService,
- private _snackBar: MatSnackBar,
- private _userService: UserService
- ) { }
-
- ngOnChanges() {
- // get project information
- this._dspApiConnection.admin.projectsEndpoint.getProjectByIri(this.resource.attachedToProject).subscribe(
- (response: ApiResponseData) => {
- this.project = response.body.project;
- },
- (error: ApiResponseError) => {
- this._notification.openSnackBar(error);
- }
- );
-
- // get user information
- this._userService.getUser(this.resource.attachedToUser).subscribe(
- (response: UserResponse) => {
- this.user = response.user;
- }
- );
- }
-
- /**
- * emits the project information on click.
- */
- projectClicked(project: ReadProject) {
- this.referredProjectClicked.emit(project);
- }
-
- /**
- * emits the project information on hover.
- */
- projectHovered(project: ReadProject) {
- this.referredProjectHovered.emit(project);
- }
-
- /**
- * display message to confirm the copy of the citation link (ARK URL)
- */
- openSnackBar() {
- const message = 'Copied to clipboard!';
- const action = 'Citation Link';
- this._snackBar.open(message, action, {
- duration: 3000,
- horizontalPosition: 'center',
- verticalPosition: 'top'
- });
- }
-}
diff --git a/src/app/workspace/resource/resource.component.html b/src/app/workspace/resource/resource.component.html
index 3f3ad2cdff..80a077f692 100644
--- a/src/app/workspace/resource/resource.component.html
+++ b/src/app/workspace/resource/resource.component.html
@@ -5,10 +5,10 @@
-
+ [compoundNavigation]="compoundPosition" (goToPage)="compoundNavigation($event)"
+ (regionClicked)="openRegion($event)">
@@ -18,74 +18,35 @@
-
-
-
-
-
-
-
-
-
- The resource {{resource?.res.resourceClassLabel}} has no defined
- properties.
+
+
-
-
-
-
-
-
-
-
-
-
- The resource {{resource?.res.resourceClassLabel}} has no defined properties.
+
+
-
+
-
+
Annotations
-
-
-
-
-
-
-
-
-
The resource {{resource?.res.resourceClassLabel}} has no defined properties.
+
-
-
-
+
diff --git a/src/app/workspace/resource/resource.component.ts b/src/app/workspace/resource/resource.component.ts
index 84f2b807e6..19b8befdda 100644
--- a/src/app/workspace/resource/resource.component.ts
+++ b/src/app/workspace/resource/resource.component.ts
@@ -144,15 +144,6 @@ export class ResourceComponent implements OnInit, OnChanges, OnDestroy {
// general methods
// ------------------------------------------------------------------------
- // open project in new tab
- openProject(project: ReadProject) {
- window.open('/project/' + project.shortcode, '_blank');
- }
-
- openResource(linkValue: ReadLinkValue) {
- window.open('/resource/' + encodeURIComponent(linkValue.linkedResource.id), '_blank');
- }
-
compoundNavigation(page: number) {
this.selectedRegion = undefined;