Skip to content

Commit

Permalink
feat(ontology): new method to change gui order (DSP-1567/DSP-1646) (#440
Browse files Browse the repository at this point in the history
)

* fix(ontology): new method to change gui order

* chore(deps): bump dsp-js to v2.3.0

* chore(deps): update dependencies

* fix(ontology): use correct method to update gui order

* fix(ontology): bug fix in gui-order and cardinality function

* feat(ontology): init new drag'n'drop for gui-order

* style(ontology): fix drag'n'drop style issue

* feat(ontology): new setup to change gui order

* refactor(ontology): bring back the old cardinality form

* refactor(ontology): clean up

* test(ontology): bug fix in test

* feat(ontology): improve drag'n'drop functionality

* test(ontology): add some imports

* test(ontology): bug fixes in tests
  • Loading branch information
kilchenmann committed May 21, 2021
1 parent a56a45b commit dfd0ce0
Show file tree
Hide file tree
Showing 18 changed files with 776 additions and 434 deletions.
867 changes: 506 additions & 361 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -33,7 +33,7 @@
"@angular/platform-browser-dynamic": "^11.2.9",
"@angular/router": "^11.2.9",
"@ckeditor/ckeditor5-angular": "^1.2.3",
"@dasch-swiss/dsp-js": "^2.2.0",
"@dasch-swiss/dsp-js": "^2.3.0",
"@dasch-swiss/dsp-ui": "^1.3.0",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "5.0.0",
Expand All @@ -47,7 +47,7 @@
"jdnconvertiblecalendar": "^0.0.6",
"jdnconvertiblecalendardateadapter": "^0.0.16",
"json2typescript": "^1.0.6",
"jsonld": "^1.1.0",
"jsonld": "^5.2.0",
"moment": "^2.27.0",
"ngx-color-picker": "^11.0.0",
"openseadragon": "^2.4.0",
Expand All @@ -61,7 +61,7 @@
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.8",
"@angular-devkit/build-angular": "^0.1102.12",
"@angular-eslint/eslint-plugin": "^1.2.0",
"@angular/cli": "^11.2.8",
"@angular/compiler-cli": "^11.2.9",
Expand Down
6 changes: 4 additions & 2 deletions src/app/project/ontology/ontology.component.html
Expand Up @@ -180,6 +180,8 @@ <h2 class="mat-title">
<app-resource-class-info *ngFor="let resClass of ontoClasses" [resourceClass]="resClass"
[expanded]="expandClasses"
[projectCode]="projectCode"
[lastModificationDate]="lastModificationDate"
(updateParent)="lastModificationDate = $event"
(editResourceClass)="openResourceClassForm('editResourceClass', $event)"
(updateCardinality)="updateCard($event)"
(deleteResourceClass)="delete('ResourceClass', $event)">
Expand All @@ -188,7 +190,7 @@ <h2 class="mat-title">
<div class="ontology-editor-list properties" *ngIf="view === 'properties'">
<!-- list of resource properties -->
<mat-list>
<span *ngFor="let prop of ontoProperties">
<mat-list-item class="property" *ngFor="let prop of ontoProperties">
<!-- display only properties with guiOrder and if they exist in list of properties;
objectType is not a linkValue (otherwise we have the property twice) -->
<app-property-info [propDef]="ontology?.properties[prop.id]"
Expand All @@ -197,7 +199,7 @@ <h2 class="mat-title">
(deleteResourceProperty)="delete('Property', $event)"
(clickedOnClass)="updateCard($event)">
</app-property-info>
</span>
</mat-list-item>
<!-- <mat-list-item *ngFor="let prop of ontoProperties">{{prop.label}}</mat-list-item> -->
</mat-list>
</div>
Expand Down
9 changes: 9 additions & 0 deletions src/app/project/ontology/ontology.component.scss
Expand Up @@ -82,6 +82,15 @@ $width: 340px;
&.properties {
width: 80%;
margin: 16px 10%;

.property {
height: 56px !important;
margin: 4px 0;

&:hover {
background-color: $black-12-opacity;
}
}
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/app/project/ontology/ontology.component.ts
Expand Up @@ -15,7 +15,6 @@ import {
ListsResponse,
OntologiesMetadata,
OntologyMetadata,
ProjectResponse,
PropertyDefinition,
ReadOntology,
ReadProject,
Expand All @@ -26,7 +25,7 @@ import { DspApiConnectionToken, Session, SessionService, SortingService } from '
import { CacheService } from 'src/app/main/cache/cache.service';
import { DialogComponent } from 'src/app/main/dialog/dialog.component';
import { ErrorHandlerService } from 'src/app/main/error/error-handler.service';
import { DefaultProperties, DefaultProperty, PropertyCategory, PropertyInfoObject } from './default-data/default-properties';
import { DefaultProperties, PropertyCategory, PropertyInfoObject } from './default-data/default-properties';
import { DefaultClass, DefaultResourceClasses } from './default-data/default-resource-classes';
import { ResourceClassFormService } from './resource-class-form/resource-class-form.service';

Expand Down Expand Up @@ -70,6 +69,8 @@ export class OntologyComponent implements OnInit {
// current/selected ontology
ontology: ReadOntology;

lastModificationDate: string;

ontoClasses: ClassDefinition[];
expandClasses = false;

Expand Down Expand Up @@ -222,6 +223,7 @@ export class OntologyComponent implements OnInit {
// with all classes, properties and connected lists
this.loadOntology = true;
this.ontology = readOnto;
this.lastModificationDate = this.ontology.lastModificationDate;
this._cache.set('currentOntology', this.ontology);

// grab the onto class information to display
Expand Down
Expand Up @@ -136,7 +136,7 @@ describe('PropertyFormComponent', () => {

const ontologyEndpointSpyObj = {
v2: {
ontologyEndpoint: jasmine.createSpyObj('onto', ['updateResourceProperty', 'createResourceProperty'])
onto: jasmine.createSpyObj('onto', ['updateResourceProperty', 'createResourceProperty'])
}
};

Expand Down
@@ -1,6 +1,4 @@
<mat-list-item (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">
<span *ngIf="propCard && propCard.guiOrder >=0" mat-list-icon
class="order additional-info">{{propCard.guiOrder}})</span>
<div class="property-info" (mouseenter)="mouseEnter()" (mouseleave)="mouseLeave()">

<div mat-line class="title">
<span class="icon" *ngIf="propType" [matTooltip]="propType?.group + ': ' + propType?.label"
Expand Down Expand Up @@ -60,4 +58,4 @@
</span>
</div>
</div>
</mat-list-item>
</div>
@@ -1,24 +1,14 @@
@import "~@angular/material/theming";
@import "../../../../assets/style/config";

.mat-list-item {
height: 56px !important;
margin: 4px 0;
&:hover {
background-color: $black-12-opacity;
}
:host {
width: 100%;
}

.additional-info {
color: $primary_700;
}

.mat-list-icon.order {
font-size: 16px;
height: 16px;
width: 16px;
}

.mat-line.title {
line-height: 1.8;
.mat-icon {
Expand Down
Expand Up @@ -63,19 +63,12 @@
</mat-form-field>

<!-- propertiy: one line, with "add" icon to add additional properties -->
<div cdkDropList class="properties-list" (cdkDropListDropped)="drop($event)">
<div cdkDrag class="property-line"
<div class="properties-list">
<div class="property-line"
*ngFor="let prop of properties?.controls; let last = last; let i = index;">

<!-- <div *ngIf="prop.value.objectType !== 'http://api.knora.org/ontology/knora-api/v2#LinkValue'"> -->

<div class="drag-n-drop-placeholder" *cdkDragPlaceholder></div>

<button *ngIf="properties.length > 1" cdkDragHandle mat-icon-button type="button"
aria-label="Change order of properties" class="prefix drag-n-drop-line">
<mat-icon>drag_indicator</mat-icon>
</button>

<app-resource-class-property-form [propertyForm]="prop" [index]="i" [resClassIri]="iri">
</app-resource-class-property-form>

Expand Down
Expand Up @@ -103,9 +103,4 @@ button {
}
}

.drag-n-drop-placeholder {
background: #ccc;
border: dotted 3px #999;
min-height: 100px;
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

@@ -1,4 +1,3 @@
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { AfterViewChecked, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import {
Expand Down Expand Up @@ -309,17 +308,7 @@ export class ResourceClassFormComponent implements OnInit, OnDestroy, AfterViewC
this._resourceClassFormService.resetProperties();
this.addProperty();
}
/**
* drag and drop property line
*/
drop(event: CdkDragDrop<string[]>) {

// set sort order for child component
moveItemInArray(this.properties.controls, event.previousIndex, event.currentIndex);

// set sort order in form value
moveItemInArray(this.resourceClassForm.value.properties, event.previousIndex, event.currentIndex);
}
/**
* set stringLiterals for label or comment from dsp-string-literal-input
* @param {StringLiteral[]} data
Expand Down Expand Up @@ -619,6 +608,8 @@ export class ResourceClassFormComponent implements OnInit, OnDestroy, AfterViewC

onto.entity = addCard;

onto.entity = addCard;

this._dspApiConnection.v2.onto.replaceCardinalityOfResourceClass(onto).subscribe(
(res: ResourceClassDefinitionWithAllLanguages) => {
this.lastModificationDate = res.lastModificationDate;
Expand All @@ -630,6 +621,8 @@ export class ResourceClassFormComponent implements OnInit, OnDestroy, AfterViewC
this._errorHandler.showMessage(error);
}
);
}

this.loading = false;
this.closeDialog.emit();
}
}
Expand Up @@ -39,17 +39,25 @@
</mat-card-header>
<!-- resource class card content with list of properties -->
<mat-card-content>
<mat-list class="resource-class-properties">
<span *ngFor="let prop of resourceClass.propertiesList; let i = index">
<!-- display only properties with guiOrder and if they exist in list of properties;
<mat-list cdkDropList class="resource-class-properties" (cdkDropListDropped)="drop($event)">
<div cdkDrag [cdkDragDisabled]="!ontology.lastModificationDate" *ngFor="let prop of propsToDisplay; let i = index">
<div class="drag-n-drop-placeholder" *cdkDragPlaceholder></div>
<mat-list-item class="drag-n-drop-property" *ngIf="expanded">

<span cdkDragHandle mat-list-icon class="gui-order">
<span *ngIf="prop.guiOrder" [class.hide-on-hover]="cardinalityUpdateEnabled">{{i + 1}})</span>
<span *ngIf="lastModificationDate && cardinalityUpdateEnabled" class="display-on-hover drag-n-drop-handle">
<mat-icon>drag_indicator</mat-icon>
</span>
</span>

<!-- display only properties with guiOrder and if they exist in list of properties;
objectType is not a linkValue (otherwise we have the property twice) -->
<app-property-info *ngIf="ontology?.properties[prop.propertyIndex]
&& ontology?.properties[prop.propertyIndex].objectType !== 'http://api.knora.org/ontology/knora-api/v2#LinkValue'
&& !ontology?.properties[prop.propertyIndex].subjectType?.includes('Standoff')
&& expanded" [propDef]="ontology?.properties[prop.propertyIndex]"
[propCard]="prop" [projectCode]="projectCode">
</app-property-info>
</span>
<app-property-info class="property-info" [propDef]="ontology?.properties[prop.propertyIndex]" [propCard]="propsToDisplay[i]"
[projectCode]="projectCode">
</app-property-info>
</mat-list-item>
</div>
</mat-list>
</mat-card-content>
<!-- resource class card actions; TODO: can be reacitviated if we decide to add some special buttons to res class card -->
Expand Down
@@ -1,8 +1,9 @@
@import "~@angular/material/theming";
@import "../../../../assets/style/config";
@import "../../../../assets/style/mixins";

.resource-class {
min-height: 120px;
min-height: 60px;
height: auto;
position: relative;
@include mat-elevation-transition;
Expand Down Expand Up @@ -43,3 +44,62 @@
@include mat-elevation(8);
}
}

.drag-n-drop-placeholder {
background: #ccc;
border: dotted 3px #999;
min-height: 54px;
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

.drag-n-drop-property {
&:hover,
&:active,
&:focus {
background-color: $black-12-opacity;

.gui-order {
.display-on-hover {
display: block;
}

.hide-on-hover {
display: none;
}
}
}

.gui-order {
font-size: 16px;
color: $primary_700;
margin-left: -16px;
.display-on-hover {
display: none;
}

.drag-n-drop-handle {
cursor: move;
}
}

}

.cdk-drag-preview {
background-color: rgba(254, 254, 254, 1);
@include box-shadow();
cursor: move;
.gui-order {
.display-on-hover {
display: block;
}

.hide-on-hover {
display: none;
}
}
.property-info {
position: fixed;
left: 32px;
top: 4px;
}
}
@@ -1,14 +1,17 @@
import { DragDropModule } from '@angular/cdk/drag-drop';
import { Component, DebugElement, OnInit, ViewChild } from '@angular/core';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MatCardModule } from '@angular/material/card';
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 { ClassDefinition, Constants, MockOntology, ReadOntology } from '@dasch-swiss/dsp-js';
import { DspActionModule, SortingService } from '@dasch-swiss/dsp-ui';
import { DspActionModule, DspApiConnectionToken, SortingService } from '@dasch-swiss/dsp-ui';
import { of } from 'rxjs';
import { CacheService } from 'src/app/main/cache/cache.service';
import { PropertyInfoComponent } from '../property-info/property-info.component';
import { ResourceClassInfoComponent } from './resource-class-info.component';

/**
Expand Down Expand Up @@ -67,9 +70,9 @@ describe('ResourceClassInfoComponent', () => {
let hostFixture: ComponentFixture<HostComponent>;

beforeEach(waitForAsync(() => {
const dspConnSpy = {
const ontologyEndpointSpyObj = {
v2: {
onto: jasmine.createSpyObj('onto', ['getOntology']),
onto: jasmine.createSpyObj('onto', ['getOntology', 'replaceGuiOrderOfCardinalities'])
}
};

Expand All @@ -88,6 +91,10 @@ describe('ResourceClassInfoComponent', () => {
MatTooltipModule
],
providers: [
{
provide: DspApiConnectionToken,
useValue: ontologyEndpointSpyObj
},
{
provide: CacheService,
useValue: cacheServiceSpy
Expand Down

0 comments on commit dfd0ce0

Please sign in to comment.