Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(list-editor): insert a child node at a specific position (DSP-1301) #395

Merged
merged 9 commits into from Feb 26, 2021
12 changes: 8 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -31,7 +31,7 @@
"@angular/platform-browser-dynamic": "~9.1.12",
"@angular/router": "~9.1.12",
"@ckeditor/ckeditor5-angular": "^1.2.3",
"@dasch-swiss/dsp-js": "^2.0.2",
"@dasch-swiss/dsp-js": "^2.1.0",
"@dasch-swiss/dsp-ui": "^1.2.2",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
Expand Down
9 changes: 8 additions & 1 deletion src/app/main/dialog/dialog.component.html
Expand Up @@ -145,6 +145,13 @@
(updateParent)="replaceTitle($event)"></app-list-info-form>
</div>

<!-- Insert list child node -->
<div *ngSwitchCase="'insertListNode'">
<app-dialog-header [title]="data.title" [subtitle]="'Insert new child node'">
</app-dialog-header>
<app-edit-list-item [iri]="data.id" [projectIri]="data.project" mode="insert" [projectCode]="data.projectCode" [parentIri]="data.parentIri" [position]="data.position" (closeDialog)="dialogRef.close($event)"></app-edit-list-item>
</div>

<!-- Update list info -->
<div *ngSwitchCase="'editListInfo'">
<app-dialog-header [title]="data.title" [subtitle]="'Edit list info'">
Expand All @@ -157,7 +164,7 @@
<div *ngSwitchCase="'editListNode'">
<app-dialog-header [title]="data.title" [subtitle]="'Edit child node'">
</app-dialog-header>
<app-edit-list-item [iri]="data.id" [projectIri]="data.project" (closeDialog)="dialogRef.close($event)"></app-edit-list-item>
<app-edit-list-item [iri]="data.id" [projectIri]="data.project" mode="update" (closeDialog)="dialogRef.close($event)"></app-edit-list-item>
</div>

<!-- Delete list node-->
Expand Down
Expand Up @@ -37,8 +37,8 @@
type="submit"
color="primary"
[disabled]="saveButtonDisabled"
(click)="updateChildNode()">
{{ 'appLabels.form.action.update' | translate }}
(click)=" mode === 'editListNode' ? updateChildNode() : insertChildNode()">
{{ mode === 'editListNode' ? 'appLabels.form.action.update' : 'appLabels.form.action.submit' | translate }}
</button>
</span>
</div>
Expand Down

Large diffs are not rendered by default.

@@ -1,5 +1,5 @@
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
import { ApiResponseData, ApiResponseError, ChildNodeInfoResponse, KnoraApiConnection, List, ListNodeInfo, ListNodeInfoResponse, StringLiteral, UpdateChildNodeRequest } from '@dasch-swiss/dsp-js';
import { ApiResponseData, ApiResponseError, ChildNodeInfoResponse, CreateChildNodeRequest, KnoraApiConnection, List, ListNodeInfo, ListNodeInfoResponse, StringLiteral, UpdateChildNodeRequest } from '@dasch-swiss/dsp-js';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This long line should be aligned

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 0b490f3

import { DspApiConnectionToken } from '@dasch-swiss/dsp-ui';

@Component({
Expand All @@ -12,6 +12,14 @@ export class EditListItemComponent implements OnInit {

@Input() iri: string;

@Input() mode: 'insert' | 'update';

@Input() parentIri?: string;

@Input() position?: number;

@Input() projectCode?: string;

@Input() projectIri: string;

@Output() closeDialog: EventEmitter<List | ListNodeInfo> = new EventEmitter<List>();
Expand Down Expand Up @@ -46,16 +54,23 @@ export class EditListItemComponent implements OnInit {
ngOnInit(): void {
this.loading = true;

// get list
this._dspApiConnection.admin.listsEndpoint.getListNodeInfo(this.iri).subscribe(
(response: ApiResponseData<ListNodeInfoResponse>) => {
this.listNode = response.body.nodeinfo;
this.buildForm(response.body.nodeinfo);
},
(error: ApiResponseError) => {
console.error(error);
}
);
// if updating a node, get the existing node info
if (this.mode === 'update') {
this._dspApiConnection.admin.listsEndpoint.getListNodeInfo(this.iri).subscribe(
(response: ApiResponseData<ListNodeInfoResponse>) => {
this.listNode = response.body.nodeinfo;
this.buildForm(response.body.nodeinfo);
},
(error: ApiResponseError) => {
console.error(error);
}
);
} else {
this.labels = [];
this.comments = [];

this.loading = false;
}
}

/**
Expand Down Expand Up @@ -105,8 +120,8 @@ export class EditListItemComponent implements OnInit {
}

/**
* Called from the template when the 'update' button is clicked.
* Sends a request to DSP-API to update the list node with the data inside the two local arrays.
* Called from the template when the 'submit' button is clicked in update mode.
* Sends a request to DSP-API to update the list child node with the data inside the two local arrays.
*/
updateChildNode() {
const childNodeUpdateData: UpdateChildNodeRequest = new UpdateChildNodeRequest();
Expand All @@ -127,4 +142,30 @@ export class EditListItemComponent implements OnInit {
);
}

/**
* Called from the template when the 'submit' button is clicked in insert mode.
* Sends a request to DSP-API to insert a new list child node in the provided position.
*/
insertChildNode() {
const createChildNodeRequest: CreateChildNodeRequest = new CreateChildNodeRequest();

createChildNodeRequest.name = this.projectCode + '-' + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
createChildNodeRequest.parentNodeIri = this.parentIri;
createChildNodeRequest.labels = this.labels;
createChildNodeRequest.comments = this.comments.length > 0 ? this.comments : [];
createChildNodeRequest.projectIri = this.projectIri;
createChildNodeRequest.position = this.position;

this._dspApiConnection.admin.listsEndpoint.createChildNode(createChildNodeRequest).subscribe(
(response: ApiResponseData<ListNodeInfoResponse>) => {
this.loading = false;
this.closeDialog.emit(response.body.nodeinfo);
},
(error: ApiResponseError) => {
this.errorMessage = error;
this.loading = false;
}
);
}

}
@@ -1,5 +1,5 @@
<!-- add new node item -->
<div class="new-list-item medium-field" *ngIf="parentIri && projectIri">
<div class="new-list-item medium-field" *ngIf="newNode">
<dsp-string-literal-input class="list-item-label" [placeholder]="placeholder" [value]="[]"
(dataChanged)="handleData($event)" [language]="language" (enter)="createChildNode()">
</dsp-string-literal-input>
Expand All @@ -14,7 +14,7 @@

<!-- node item -->
<div class="list-item medium-field"
*ngIf="!(parentIri && projectIri) && labels"
*ngIf="!newNode"
(mouseenter)="mouseEnter()"
(mouseleave)="mouseLeave()">
<dsp-string-literal-input class="list-item-label"
Expand All @@ -37,6 +37,12 @@
class="reposition down">
<mat-icon>arrow_downward</mat-icon>
</button>
<button mat-button
title="insert new child node above"
(click)="$event.stopPropagation(); openDialog('insertListNode', labels[0].value, iri)"
class="insert">
<mat-icon>vertical_align_top</mat-icon>
</button>
<button mat-button
class="edit"
title="edit"
Expand Down
35 changes: 27 additions & 8 deletions src/app/project/list/list-item-form/list-item-form.component.ts
Expand Up @@ -11,15 +11,14 @@ import {
ListInfoResponse,
ListNode,
ListNodeInfoResponse,
RepositionChildNodeRequest,
StringLiteral
} from '@dasch-swiss/dsp-js';
import { DspApiConnectionToken } from '@dasch-swiss/dsp-ui';
import { DialogComponent } from 'src/app/main/dialog/dialog.component';
import { ErrorHandlerService } from 'src/app/main/error/error-handler.service';

export class ListNodeOperation {
operation: 'create' | 'update' | 'delete' | 'reposition';
operation: 'create' | 'insert' | 'update' | 'delete' | 'reposition';
listNode: ListNode;
}

Expand Down Expand Up @@ -82,6 +81,8 @@ export class ListItemFormComponent implements OnInit {
// is this node in the last position of the list
@Input() lastPosition: boolean = false;

@Input() newNode: boolean = false;

@Output() refreshParent: EventEmitter<ListNodeOperation> = new EventEmitter<ListNodeOperation>();

loading: boolean;
Expand All @@ -107,7 +108,7 @@ export class ListItemFormComponent implements OnInit {
}

// it can be used in the input placeholder
if (this.parentIri) {
if (this.newNode) {
this._dspApiConnection.admin.listsEndpoint.getListNodeInfo(this.parentIri).subscribe(
(response: ApiResponseData<ListNodeInfoResponse | ListInfoResponse>) => {
if (response.body instanceof ListInfoResponse) { // root node
Expand Down Expand Up @@ -211,12 +212,21 @@ export class ListItemFormComponent implements OnInit {
* @param iri iri of the node.
*/
openDialog(mode: string, name: string, iri?: string): void {

const dialogConfig: MatDialogConfig = {
width: '640px',
position: {
top: '112px'
},
data: { mode: mode, title: name, id: iri, project: this.projectIri }
data: {
mode: mode,
title: mode === 'editListNode' ? name : 'Insert new child node',
id: iri,
project: this.projectIri,
projectCode: this.projectcode,
parentIri: this.parentIri,
position: this.position
}
};

// open the dialog box
Expand All @@ -226,19 +236,24 @@ export class ListItemFormComponent implements OnInit {
);

dialogRef.afterClosed().subscribe((data: ChildNodeInfo | boolean) => {

// init data to emit to parent
const listNodeOperation = new ListNodeOperation();

if (data instanceof ChildNodeInfo) { // update
if (mode === 'insertListNode' && data) {
// the call to DSP-API to insert the new node is done in the child component
listNodeOperation.listNode = (data as ListNode);
listNodeOperation.operation = 'insert';

this.refreshParent.emit(listNodeOperation);
} else if (mode === 'editListNode' && data) { // update
// the call to DSP-API to update the node is done in the child component
listNodeOperation.listNode = (data as ListNode);
listNodeOperation.operation = 'update';

// emit data to parent to update the view
this.refreshParent.emit(listNodeOperation);
this.labels = data.labels;
} else if (typeof(data) === 'boolean' && data === true) { // delete
this.labels = (data as ChildNodeInfo).labels;
} else if (mode === 'deleteListNode' && typeof(data) === 'boolean' && data === true) { // delete
// delete the node
this._dspApiConnection.admin.listsEndpoint.deleteListNode(iri).subscribe(
(response: ApiResponseData<DeleteListNodeResponse>) => {
Expand Down Expand Up @@ -272,6 +287,10 @@ export class ListItemFormComponent implements OnInit {
});
}

/**
* Called from the template when either of the two reposition buttons is clicked
* @param direction in which direction the node should move
*/
repositionNode(direction: 'up' | 'down') {
const listNodeOperation = new ListNodeOperation();

Expand Down
6 changes: 3 additions & 3 deletions src/app/project/list/list-item/list-item.component.html
Expand Up @@ -11,7 +11,7 @@
<!-- existing node: show label in form; value is e.g. {{node.labels[0].value}} -->
<app-list-item-form [iri]="node.id" [language]="language" (refreshParent)="updateView($event, true)"
[projectIri]="projectIri" [projectcode]="projectcode" [labels]="node.labels"
[position]="node.position" [lastPosition]="last">
[position]="node.position" [lastPosition]="last" [parentIri]="parentIri">
</app-list-item-form>


Expand All @@ -26,15 +26,15 @@
<div *ngIf="node.id === expandedNode && node.children.length === 0" class="child-node">
<!-- first child should have an empty list? yes -->
<app-list-item-form class="append-child-node" [parentIri]="node.id" [projectIri]="projectIri"
[projectcode]="projectcode" [language]="language"
[projectcode]="projectcode" [language]="language" [newNode]="true"
(refreshParent)="updateView($event, true)">
</app-list-item-form>
</div>

<!-- form to append new item to parent node -->
<app-list-item-form class="list-node append-child-node" *ngIf="last" [parentIri]="parentIri"
[projectIri]="projectIri" [projectcode]="projectcode" [language]="language"
(refreshParent)="updateView($event)">
[newNode]="true" (refreshParent)="updateView($event)">
</app-list-item-form>

</div>
Expand Down