Skip to content

Commit

Permalink
refactor(resource): improve list of properties in resource viewer (#453)
Browse files Browse the repository at this point in the history
* feat(resource): combination of two components

* test(resource): complete tests in properties comp

* refactor(resource): delete unused components

* test(resource): enable all tests

* refactor(resource): clean up code

* refactor(resource): clean up code

* style(resource): fix style issue in still image viewer

* refactor: sort imports
  • Loading branch information
kilchenmann committed May 26, 2021
1 parent 721c851 commit 49d9b7f
Show file tree
Hide file tree
Showing 13 changed files with 512 additions and 704 deletions.
100 changes: 49 additions & 51 deletions src/app/app.module.ts
Expand Up @@ -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) {
Expand Down Expand Up @@ -146,6 +145,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
ProjectsComponent,
ProjectsListComponent,
ProjectTabViewComponent,
PropertiesComponent,
PropertyFormComponent,
PropertyInfoComponent,
ResourceClassFormComponent,
Expand All @@ -160,6 +160,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
SelectProjectComponent,
SelectPropertiesComponent,
SelectResourceClassComponent,
StillImageComponent,
SwitchPropertiesComponent,
SystemComponent,
TermsTabViewComponent,
Expand All @@ -170,9 +171,6 @@ export function httpLoaderFactory(httpClient: HttpClient) {
UsersComponent,
UsersListComponent,
VisualizerComponent,
ResourceToolbarComponent,
ResourcePropertiesComponent,
StillImageComponent,
],
imports: [
AppRoutingModule,
Expand Down
126 changes: 126 additions & 0 deletions src/app/workspace/resource/properties/properties.component.html
@@ -0,0 +1,126 @@

<!-- toolbar -->
<div class="toolbar" *ngIf="project">
<!-- resource info -->
<h3 class="label mat-title">
{{resource.res.label}}
</h3>
<span class="fill-remaining-space"></span>

<!-- tools: share, add to favorites, edit, delete etc. -->
<span>
<!-- TODO: activate favorite action to add resource to collection -->
<!--
<button mat-button class="add-res-to-collection">
<mat-icon>star_border</mat-icon>
</button>
-->

<!-- Toggle list of properties: all or only the ones with value -->
<button mat-button class="toggle-props" matTooltip="Toggle list of properties" matTooltipPosition="above"
(click)="showAllProps = !showAllProps">
<mat-icon>{{showAllProps ? 'unfold_less' : 'unfold_more'}}</mat-icon>
<span class="desktop-only">{{showAllProps ? 'Hide empty' : 'Show all'}} properties</span>
</button>

<!-- TODO: activate delete action to delete the whole resource -->
<!--
<button mat-button class="delete-res">
<mat-icon>delete</mat-icon>
</button>
-->

<!-- Share resource by copying the ark url -->
<button mat-button class="share-res" matTooltip="Share resource by copying ARK url" matTooltipPosition="above"
[matMenuTriggerFor]="share">
<mat-icon>share</mat-icon>
<span class="desktop-only">Citation Link</span>
</button>
<mat-menu #share="matMenu" class="res-share-menu">
<!-- citation link - ARK URL -->
<div class="ark-url-label mat-body">
<label for="clipboard-arkurl">Citation Link (ARK URL)</label>
</div>
<div class="ark-url-input">
<input id="clipboard-arkurl" class="clipboard-arkurl" cols="30" rows="10" readonly
[(ngModel)]="resource.res.versionArkUrl" />
<button mat-button class="btn-copy-arkurl" [cdkCopyToClipboard]="resource.res.versionArkUrl"
matTooltip="Copy ARK url" matTooltipPosition="below" (click)="openSnackBar()">
<mat-icon class="icon-arkurl">content_copy</mat-icon>
</button>
</div>
</mat-menu>
</span>
</div>

<!-- additional line with project and user information -->
<div class="infobar mat-caption" *ngIf="project && user">
<p *ngIf="displayProjectInfo">This resource belongs to the project
<span class="project link" (click)="openProject(project)" (mouseover)="previewProject(project)">
<b>{{project?.shortname}}</b>
<mat-icon inline>open_in_new</mat-icon>
</span>
</p>
<span class="fill-remaining-space"></span>
<p *ngIf="user || resource.res.creationDate">
Created
<span *ngIf="user">by {{(user.username ? user.username : user.givenName + ' ' + user.familyName)}}</span>
<span *ngIf="resource.res.creationDate"> on {{resource.res.creationDate | date}}</span>
</p>
</div>

<!-- list of properties -->
<div class="properties-container">
<div class="properties" *ngIf="resource.resProps.length !== 0; else noProperties">

<!-- list of properties -->
<div *ngFor="let prop of resource.resProps; let last = last">
<!-- show property; all in case of showAll === true or only the ones with prop.values -->
<div *ngIf="!prop.propDef['isLinkProperty'] && showAllProps || ( prop.values && prop.values.length > 0 )"
[class.border-bottom]="prop.values && !last"
class="property">
<div class="property-label">
<!-- label of the property -->
<h3 class="label mat-subheading-1"
[class.label-info]="prop.propDef.comment"
[matTooltip]="prop.propDef.comment"
matTooltipPosition="above">
{{prop.propDef.label}}
</h3>
</div>
<div class="property-value">
<!-- the value(s) of the property -->
<div *ngFor="let val of prop.values">
<dsp-display-edit *ngIf="val"
#displayEdit
[parentResource]="resource.res"
[displayValue]="val"
[propArray]="resource.resProps"
(referredResourceClicked)="openResource($event)"
(referredResourceHovered)="previewResource($event)">
</dsp-display-edit>
</div>
<!-- Add value form -->
<div *ngIf="addValueFormIsVisible && propID === prop.propDef.id">
<dsp-add-value #addValue
class="add-value"
[parentResource]="resource.res"
[resourcePropertyDefinition]="$any(resource.res.entityInfo.properties[prop.propDef.id])"
(operationCancelled)="hideAddValueForm()">
</dsp-add-value>
</div>
<!-- Add button -->
<div *ngIf="addValueIsAllowed(prop)">
<button class="create"
(click)="showAddValueForm(prop)"
title="Add a new value">
<mat-icon>add_box</mat-icon>
</button>
</div>
</div>
</div>
</div>
</div>
<ng-template #noProperties>The resource {{resource?.res.resourceClassLabel}} has no defined
properties.</ng-template>
</div>
@@ -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
Expand Down

0 comments on commit 49d9b7f

Please sign in to comment.