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(resource): delete and erase resource (DSP-1228) #489

Merged
merged 9 commits into from Jul 26, 2021
31 changes: 15 additions & 16 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 @@ -34,7 +34,7 @@
"@angular/platform-browser-dynamic": "^11.2.9",
"@angular/router": "^11.2.9",
"@ckeditor/ckeditor5-angular": "^1.2.3",
"@dasch-swiss/dsp-js": "^2.6.2",
"@dasch-swiss/dsp-js": "^2.7.0",
"@dasch-swiss/dsp-ui": "^1.6.0",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "5.0.0",
Expand Down
39 changes: 39 additions & 0 deletions src/app/main/dialog/dialog.component.html
Expand Up @@ -324,6 +324,45 @@
</app-resource-instance-form>
</div>

<div *ngSwitchCase="'deleteResource'">
<app-dialog-header [title]="data.title" [subtitle]="'Delete resource instance'"></app-dialog-header>
<mat-dialog-content>
Do you want to delete this resource?
<textarea
matinput
class="deletion-comment"
type="text"
(keyup)="onKey($event)"
[placeholder]="'Comment why resource is being deleted'"
></textarea>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close class="cancel-button center" [mat-dialog-close]="{confirmed: false, comment: comment}">
No, keep it
</button>
<span class="fill-remaining-space"></span>
<button mat-button mat-raised-button [color]="'warn'" class="confirm-button center"
[mat-dialog-close]="{confirmed: true, comment: comment}">
Yes, delete
</button>
</mat-dialog-actions>
</div>

<div *ngSwitchCase="'eraseResource'">
<app-dialog-header [title]="data.title" [subtitle]="'Delete resource'"></app-dialog-header>
Do you want to erase this resource forever?<br>WARNING: This action cannot be undone, so use it with care.
<mat-dialog-actions>
<button mat-button mat-dialog-close class="cancel-button center" [mat-dialog-close]="{confirmed: false, comment: comment}">
No, keep it
</button>
<span class="fill-remaining-space"></span>
<button mat-button mat-raised-button [color]="'warn'" class="confirm-button center"
[mat-dialog-close]="{confirmed: true, comment: comment}">
Yes, erase forever
</button>
</mat-dialog-actions>
</div>

<!-- general error message -->
<div *ngSwitchCase="'error'">
<app-error [status]="data.id"></app-error>
Expand Down
15 changes: 11 additions & 4 deletions src/app/main/dialog/dialog.component.scss
@@ -1,6 +1,13 @@
.todo {
background-color: bisque;
padding: 6px;
border-radius: 4px;
text-align: center;
background-color: bisque;
padding: 6px;
border-radius: 4px;
text-align: center;
}

.deletion-comment {
width: calc(100% - 48px);
margin: 8px;
padding: 8px;
height: 64px;
}
13 changes: 12 additions & 1 deletion src/app/main/dialog/dialog.component.ts
@@ -1,4 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { PropertyInfoObject } from 'src/app/project/ontology/default-data/default-properties';

Expand All @@ -18,6 +18,11 @@ export interface DialogData {
projectCode?: string;
}

export interface ConfirmationWithComment {
confirmed: boolean;
comment?: string;
}

@Component({
selector: 'app-material-dialog',
templateUrl: './dialog.component.html',
Expand All @@ -27,6 +32,8 @@ export class DialogComponent implements OnInit {

notYetImplemented = `The component <strong>${this.data.mode}</strong> is not implemented yet.`;

comment?: string;

constructor(
public dialogRef: MatDialogRef<DialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData
Expand All @@ -45,4 +52,8 @@ export class DialogComponent implements OnInit {
this.data.subtitle = heading.subtitle;
}
}

onKey(event: KeyboardEvent) {
this.comment = (event.target as HTMLInputElement).value;
}
}
67 changes: 41 additions & 26 deletions src/app/workspace/resource/properties/properties.component.html
@@ -1,26 +1,20 @@

<!-- toolbar -->
<div class="toolbar" *ngIf="project">
<div class="toolbar" *ngIf="project" [class.deleted]="deletedResource">
<!-- resource info -->
<h3 class="label mat-title">
{{resource.res.label}}
{{resource.res.label}} <span *ngIf="deletedResource">(deleted)</span>
</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>
-->
<span class="action">

<!-- 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">
<button mat-icon-button class="toggle-props" [matTooltip]="(showAllProps ? 'Hide empty' : 'Show all')+' properties'" matTooltipPosition="above"
(click)="toggleAllProps(showAllProps)">
<mat-icon>{{showAllProps ? 'unfold_less' : 'unfold_more'}}</mat-icon>
<span class="desktop-only">{{showAllProps ? 'Hide empty' : 'Show all'}} properties</span>
<!-- <span class="desktop-only">{{showAllProps ? 'Hide empty' : 'Show all'}} properties</span> -->
</button>

<!-- TODO: activate delete action to delete the whole resource -->
Expand All @@ -30,25 +24,46 @@ <h3 class="label mat-title">
</button>
-->

<!-- Share resource by copying the ark url -->
<button mat-button class="share-res" matTooltip="Share resource by copying ARK url" matTooltipPosition="above"
<!-- Share resource: copy ark url, add to favorites or open in new tab -->
<button mat-icon-button class="share-res" matTooltip="Share resource: {{resource.res.versionArkUrl}}" matTooltipPosition="above"
[disabled]="deletedResource"
[matMenuTriggerFor]="share">
<mat-icon>share</mat-icon>
<span class="desktop-only">Citation Link</span>
<!-- <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 mat-menu-item matTooltip="Copy ARK url" matTooltipPosition="above"
[cdkCopyToClipboard]="resource.res.versionArkUrl" (click)="openSnackBar()">
<mat-icon>content_copy</mat-icon>
Copy ARK url to clipboard
</button>
<button mat-menu-item matTooltip="Open in new tab" matTooltipPosition="above"
(click)="openResource(resource.res.id)">
<mat-icon>open_in_new</mat-icon>
Open resource in new tab
</button>
<!-- TODO: activate favorite action to add resource to collection -->
<!--
<button mat-button class="add-res-to-collection">
<mat-icon>star_border</mat-icon>
</button>
</div>
-->
</mat-menu>

<!-- more menu with: delete, erase resource -->
<button *ngIf="editPermissions" mat-icon-button class="more-menu" matTooltip="More" matTooltipPosition="above" [matMenuTriggerFor]="more" [disabled]="deletedResource">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #more="matMenu" class="res-more-menu">
<button mat-menu-item matTooltip="Move resource to trash bin." matTooltipPosition="above" (click)="openDialog('delete')">
<mat-icon>delete</mat-icon>
Delete resource
</button>
<button mat-menu-item matTooltip="Erase resource forever. This cannot be undone." matTooltipPosition="above"
[disabled]="!adminPermissions" (click)="openDialog('erase')">
<mat-icon>delete_forever</mat-icon>
Erase resource
</button>
</mat-menu>
</span>
</div>
Expand Down
10 changes: 9 additions & 1 deletion src/app/workspace/resource/properties/properties.component.scss
Expand Up @@ -13,7 +13,11 @@
color: rgba(0, 0, 0, 0.87);
}
.toolbar {
background: whitesmoke;
background: $primary_200;

&.deleted {
background: $warn;
}

.label {
margin: 0 !important;
Expand All @@ -22,6 +26,10 @@
overflow: hidden;
text-overflow: ellipsis;
}

.action button {
border-radius: 0;
}
}

.infobar {
Expand Down
24 changes: 22 additions & 2 deletions src/app/workspace/resource/properties/properties.component.spec.ts
Expand Up @@ -189,6 +189,26 @@ describe('PropertiesComponent', () => {
voeService = TestBed.inject(ValueOperationEventService);
}));

// mock localStorage
beforeEach(() => {
let store = {};

spyOn(localStorage, 'getItem').and.callFake(
(key: string): string => store[key] || null
);
spyOn(localStorage, 'removeItem').and.callFake(
(key: string): void => {
delete store[key];
}
);
spyOn(localStorage, 'setItem').and.callFake(
(key: string, value: string): string => (store[key] = <any>value)
);
spyOn(localStorage, 'clear').and.callFake(() => {
store = {};
});
});

beforeEach(() => {
const adminSpy = TestBed.inject(DspApiConnectionToken);

Expand Down Expand Up @@ -254,14 +274,14 @@ describe('PropertiesComponent', () => {
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');
expect(resLabelNativeElement.textContent.trim()).toBe('unfold_more');

resLabelNativeElement.click();

testHostFixture.detectChanges();

// the button contains an icon "unfold_less" and the text "Decrease properties"
expect(resLabelNativeElement.textContent.trim()).toBe('unfold_lessHide empty properties');
expect(resLabelNativeElement.textContent.trim()).toBe('unfold_less');

});
});
Expand Down