[DURACOM-134] Administer workflow actions fixed

This commit is contained in:
Alisa Ismailati
2023-04-28 18:03:52 +02:00
parent c89adf4f81
commit 2895cfe083
15 changed files with 342 additions and 9 deletions

View File

@@ -0,0 +1,26 @@
import { ThemedComponent } from '../../shared/theme-support/themed.component';
import { Component } from '@angular/core';
import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page.component';
/**
* Themed wrapper for WorkspaceItemsDeletePageComponent
*/
@Component({
selector: 'ds-themed-workspace-items-delete',
styleUrls: [],
templateUrl: './../../shared/theme-support/themed.component.html'
})
export class ThemedWorkspaceItemsDeletePageComponent extends ThemedComponent<WorkspaceItemsDeletePageComponent> {
protected getComponentName(): string {
return 'WorkspaceItemsDeletePageComponent';
}
protected importThemedComponent(themeName: string): Promise<any> {
return import(`../../../themes/${themeName}/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component`);
}
protected importUnthemedComponent(): Promise<any> {
return import(`./workspaceitems-delete-page.component`);
}
}

View File

@@ -0,0 +1,24 @@
<div class="container">
<h2>{{ 'workspace-item.delete.header' | translate }}</h2>
<ds-modify-item-overview *ngIf="(dso$ | async)" [item]="(dso$ | async)"></ds-modify-item-overview>
<button class="btn btn-default" (click)="previousPage()">{{ 'workspace-item.delete.button.cancel' | translate }}</button>
<button class="btn btn-danger" (click)="$event.preventDefault();confirmDelete(content)">{{ 'workspace-item.delete.button.confirm' | translate }}</button>
</div>
<ng-template #content let-c="close" let-d="dismiss" id="delete-modal">
<div class="modal-header">
<h4 class="modal-title text-danger">{{ 'workspace-item.delete.header' | translate }}</h4>
<button type="button" id="delete_close" class="close" aria-label="Close" (click)="d('cancel')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>{{ 'submission.general.discard.confirm.info' | translate }}</p>
</div>
<div class="modal-footer">
<button type="button" id="delete_cancel" class="btn btn-secondary"
(click)="c('cancel')">{{ 'submission.general.discard.confirm.cancel' | translate }}</button>
<button type="button" id="delete_confirm" class="btn btn-danger"
(click)="c('ok')">{{ 'submission.general.discard.confirm.submit' | translate }}</button>
</div>
</ng-template>

View File

@@ -0,0 +1,4 @@
:host ::ng-deep ds-modify-item-overview table {
display: inline-table !important;
}

View File

@@ -0,0 +1,110 @@
import { RouteService } from '../..//core/services/route.service';
import { NotificationsService } from '../..//shared/notifications/notifications.service';
import { WorkspaceitemDataService } from '../..//core/submission/workspaceitem-data.service';
import { RouterMock } from './../../shared/mocks/router.mock';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page.component';
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import { EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core';
import { Location } from '@angular/common';
import { of as observableOf } from 'rxjs';
import { routeServiceStub } from '../../shared/testing/route-service.stub';
import { LocationStub } from '../../shared/testing/location.stub';
import { By } from '@angular/platform-browser';
import { ActivatedRouteStub } from 'src/app/shared/testing/active-router.stub';
import { createSuccessfulRemoteDataObject } from 'src/app/shared/remote-data.utils';
import { WorkspaceItem } from 'src/app/core/submission/models/workspaceitem.model';
import { DSpaceObject } from 'src/app/core/shared/dspace-object.model';
describe('WorkspaceitemsDeletePageComponent', () => {
let component: WorkspaceItemsDeletePageComponent;
let fixture: ComponentFixture<WorkspaceItemsDeletePageComponent>;
const workspaceitemDataServiceSpy = jasmine.createSpyObj('WorkspaceitemDataService', {
delete: jasmine.createSpy('delete')
});
const wsi = new WorkspaceItem();
wsi.id = '1234';
const dso = new DSpaceObject();
dso.uuid = '1234';
const translateServiceStub = {
get: () => observableOf('test-message'),
onLangChange: new EventEmitter(),
onTranslationChange: new EventEmitter(),
onDefaultLangChange: new EventEmitter()
};
const modalService = {
open: () => {/** empty */},
};
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
declarations: [WorkspaceItemsDeletePageComponent],
providers: [
{
provide: ActivatedRoute,
useValue: new ActivatedRouteStub(
{},
{
wsi: createSuccessfulRemoteDataObject(wsi),
dso: createSuccessfulRemoteDataObject(dso),
}
),
},
{ provide: Router, useValue: new RouterMock() },
{
provide: WorkspaceitemDataService,
useValue: workspaceitemDataServiceSpy,
},
{ provide: Location, useValue: new LocationStub() },
{ provide: NgbModal, useValue: modalService },
{
provide: NotificationsService,
useValue: new NotificationsServiceStub(),
},
{ provide: TranslateService, useValue: translateServiceStub },
{ provide: RouteService, useValue: routeServiceStub },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(WorkspaceItemsDeletePageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have the current WorkspaceItem', () => {
console.log( (component as any).activatedRoute, 'data wsi');
(component as any).activatedRoute.data.subscribe((data) => {
console.log(data, 'dataaa');
expect(data.wsi.payload.id).toEqual('1234');
});
});
it('should delete the target workspace item', () => {
spyOn((component as any).modalService, 'open').and.returnValue({});
component.confirmDelete(By.css('#delete-modal'));
fixture.detectChanges();
expect((component as any).modalService.open).toHaveBeenCalled();
});
it('should call workspaceItemService.delete', () => {
spyOn(workspaceitemDataServiceSpy, 'delete').and.returnValue(observableOf(createSuccessfulRemoteDataObject({})));
component.sendDeleteRequest();
expect((component as any).workspaceItemService.delete).toHaveBeenCalledWith('1234');
});
});

View File

@@ -0,0 +1,111 @@
import { NotificationsService } from 'src/app/shared/notifications/notifications.service';
import { NoContent } from './../../core/shared/NoContent.model';
import { RouteService } from 'src/app/core/services/route.service';
import { getFirstCompletedRemoteData, getRemoteDataPayload } from './../../core/shared/operators';
import { RemoteData } from 'src/app/core/data/remote-data';
import { Component, OnInit } from '@angular/core';
import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model';
import { Observable, map, switchMap, take } from 'rxjs';
import { ActivatedRoute, Data, Params, Router } from '@angular/router';
import { Location } from '@angular/common';
import { WorkspaceitemDataService } from 'src/app/core/submission/workspaceitem-data.service';
import { TranslateService } from '@ngx-translate/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { DSpaceObject } from 'src/app/core/shared/dspace-object.model';
@Component({
selector: 'ds-workspaceitems-delete-page',
templateUrl: './workspaceitems-delete-page.component.html',
styleUrls: ['./workspaceitems-delete-page.component.scss']
})
export class WorkspaceItemsDeletePageComponent implements OnInit {
/**
* The workspaceitem to delete
*/
public wsi$: Observable<WorkspaceItem>;
/**
* The dspace object
*/
public dso$: Observable<DSpaceObject>;
/**
* The previous query parameters
*/
private previousQueryParameters?: Params;
constructor(
private activatedRoute: ActivatedRoute,
private router: Router,
private routeService: RouteService,
private workspaceItemService: WorkspaceitemDataService,
private notificationsService: NotificationsService,
private translationService: TranslateService,
private location: Location,
private modalService: NgbModal,
) { }
ngOnInit(): void {
this.wsi$ = this.activatedRoute.data.pipe(map((data: Data) => data.wsi as RemoteData<WorkspaceItem>), getRemoteDataPayload());
this.dso$ = this.activatedRoute.data.pipe(map((data: Data) => data.dso as RemoteData<WorkspaceItem>), getRemoteDataPayload());
this.previousQueryParameters = (this.location.getState() as { [key: string]: any }).previousQueryParams;
}
/**
* Navigates to the previous url
* If there's not previous url, it continues to the mydspace page instead
*/
previousPage() {
this.routeService.getPreviousUrl().pipe(take(1))
.subscribe((url: string) => {
let params: Params = {};
if (!url) {
url = '/mydspace';
params = this.previousQueryParameters;
}
if (url.split('?').length > 1) {
for (const param of url.split('?')[1].split('&')) {
params[param.split('=')[0]] = decodeURIComponent(param.split('=')[1]);
}
}
void this.router.navigate([url.split('?')[0]], { queryParams: params });
}
);
}
/**
* Open the modal to confirm the deletion of the workspaceitem
*/
public async confirmDelete(content) {
await this.modalService.open(content).result.then(
(result) => {
if (result === 'ok') {
this.sendDeleteRequest();
}
}
);
}
/**
* Delete the target workspaceitem object
*/
sendDeleteRequest() {
this.wsi$.pipe(
switchMap((wsi: WorkspaceItem) => this.workspaceItemService.delete(wsi.id).pipe(
getFirstCompletedRemoteData(),
))
).subscribe((response: RemoteData<NoContent>) => {
if (response.hasSucceeded) {
const title = this.translationService.get('workspace-item.delete.notification.success.title');
const content = this.translationService.get('workspace-item.delete.title');
this.notificationsService.success(title, content);
this.previousPage();
} else {
const title = this.translationService.get('workspace-item.delete.notification.error.title');
const content = this.translationService.get('workspace-item.delete.notification.error.content');
this.notificationsService.error(title, content);
}
});
}
}

View File

@@ -7,6 +7,8 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso
import { ThemedFullItemPageComponent } from '../item-page/full/themed-full-item-page.component';
import { ItemFromWorkspaceResolver } from './item-from-workspace.resolver';
import { WorkspaceItemPageResolver } from './workspace-item-page.resolver';
import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/workspaceitems-delete-page.component';
import { ThemedWorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/themed-workspaceitems-delete-page.component';
@NgModule({
imports: [
@@ -34,7 +36,27 @@ import { WorkspaceItemPageResolver } from './workspace-item-page.resolver';
breadcrumb: I18nBreadcrumbResolver
},
data: { title: 'workspace-item.view.title', breadcrumbKey: 'workspace-item.view' }
}
},
{
canActivate: [AuthenticatedGuard],
path: 'delete',
component: WorkspaceItemsDeletePageComponent,
resolve: {
dso: ItemFromWorkspaceResolver,
breadcrumb: I18nBreadcrumbResolver
},
data: { title: 'workspace-item.delete', breadcrumbKey: 'workspace-item.delete' }
},
{
canActivate: [AuthenticatedGuard],
path: 'delete',
component: ThemedWorkspaceItemsDeletePageComponent,
resolve: {
dso: ItemFromWorkspaceResolver,
breadcrumb: I18nBreadcrumbResolver
},
data: { title: 'workspace-item.delete', breadcrumbKey: 'workspace-item.delete' }
},
]
}
])

View File

@@ -3,6 +3,8 @@ import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { WorkspaceitemsEditPageRoutingModule } from './workspaceitems-edit-page-routing.module';
import { SubmissionModule } from '../submission/submission.module';
import { WorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/workspaceitems-delete-page.component';
import { ThemedWorkspaceItemsDeletePageComponent } from './workspaceitems-delete-page/themed-workspaceitems-delete-page.component';
@NgModule({
imports: [
@@ -11,7 +13,10 @@ import { SubmissionModule } from '../submission/submission.module';
SharedModule,
SubmissionModule,
],
declarations: []
declarations: [
WorkspaceItemsDeletePageComponent,
ThemedWorkspaceItemsDeletePageComponent,
]
})
/**
* This module handles all modules that need to access the workspaceitems edit page.