Skip to content

Commit

Permalink
Merge branch 'w2p-111638_Process-admin-UI-redesign_Overview-page-tabl…
Browse files Browse the repository at this point in the history
…es_PR-feedback' into process-admin-ui-redesign-8.0.0-next
  • Loading branch information
AAwouters committed Feb 7, 2024
2 parents 87bb3ca + 4651d3a commit 27d05ae
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 173 deletions.
22 changes: 13 additions & 9 deletions src/app/process-page/form/process-form.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { ControlContainer, NgForm } from '@angular/forms';
import { ScriptParameter } from '../scripts/script-parameter.model';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
import { RequestService } from '../../core/data/request.service';
import { Router } from '@angular/router';
import { Router, NavigationExtras } from '@angular/router';
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { RemoteData } from '../../core/data/remote-data';
import { getProcessListRoute } from '../process-page-routing.paths';
Expand Down Expand Up @@ -57,7 +56,6 @@ export class ProcessFormComponent implements OnInit {
private scriptService: ScriptDataService,
private notificationsService: NotificationsService,
private translationService: TranslateService,
private requestService: RequestService,
private router: Router) {
}

Expand Down Expand Up @@ -91,7 +89,7 @@ export class ProcessFormComponent implements OnInit {
const title = this.translationService.get('process.new.notification.success.title');
const content = this.translationService.get('process.new.notification.success.content');
this.notificationsService.success(title, content);
this.sendBack();
this.sendBack(rd.payload);
} else {
const title = this.translationService.get('process.new.notification.error.title');
const content = this.translationService.get('process.new.notification.error.content');
Expand Down Expand Up @@ -143,11 +141,17 @@ export class ProcessFormComponent implements OnInit {
return this.missingParameters.length > 0;
}

private sendBack() {
this.requestService.removeByHrefSubstring('/processes');
/* should subscribe on the previous method to know the action is finished and then navigate,
will fix this when the removeByHrefSubstring changes are merged */
this.router.navigateByUrl(getProcessListRoute());
/**
* Redirect the user to the processes overview page with the new process' ID,
* so it can be highlighted in the overview table.
* @param newProcess The newly created process
* @private
*/
private sendBack(newProcess: Process) {
const extras: NavigationExtras = {
queryParams: { new_process_id: newProcess.processId },
};
void this.router.navigate([getProcessListRoute()], extras);
}
}

Expand Down
34 changes: 21 additions & 13 deletions src/app/process-page/overview/process-overview.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,7 @@
<div class="d-flex">
<h1 class="flex-grow-1">{{'process.overview.title' | translate}}</h1>
</div>
<div class="d-flex justify-content-end mb-2">
<button *ngIf="processBulkDeleteService.hasSelected()" class="btn btn-primary mr-2"
(click)="processBulkDeleteService.clearAllProcesses()"><i
class="fas fa-undo pr-2"></i>{{'process.overview.delete.clear' | translate }}
</button>
<button *ngIf="processBulkDeleteService.hasSelected()" class="btn btn-danger mr-2"
(click)="openDeleteModal(deleteModal)"><i
class="fas fa-trash pr-2"></i>{{'process.overview.delete' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}
</button>
<button class="btn btn-success" routerLink="/processes/new"><i
class="fas fa-plus pr-2"></i>{{'process.overview.new' | translate}}</button>
</div>
<ng-container *ngTemplateOutlet="buttons"></ng-container>

<div class="sections">
<ds-process-overview-table
Expand All @@ -23,18 +12,37 @@ <h1 class="flex-grow-1">{{'process.overview.title' | translate}}</h1>
<ds-process-overview-table
[processStatus]="ProcessStatus.SCHEDULED"
[useAutoRefreshingSearchBy]="true"
[getInfoValueMethod]="processOverviewService.timeStarted"/>
[getInfoValueMethod]="processOverviewService.timeCreated"/>
<ds-process-overview-table
[processStatus]="ProcessStatus.COMPLETED"
[sortField]="ProcessSortField.endTime"
[useAutoRefreshingSearchBy]="true"
[getInfoValueMethod]="processOverviewService.timeCompleted"/>
<ds-process-overview-table
[processStatus]="ProcessStatus.FAILED"
[sortField]="ProcessSortField.endTime"
[useAutoRefreshingSearchBy]="true"
[getInfoValueMethod]="processOverviewService.timeCompleted"/>
</div>

<ng-container *ngTemplateOutlet="buttons"></ng-container>
</div>

<ng-template #buttons>
<div class="d-flex justify-content-end mb-2">
<button *ngIf="processBulkDeleteService.hasSelected()" class="btn btn-primary mr-2"
(click)="processBulkDeleteService.clearAllProcesses()"><i
class="fas fa-undo pr-2"></i>{{'process.overview.delete.clear' | translate }}
</button>
<button *ngIf="processBulkDeleteService.hasSelected()" class="btn btn-danger mr-2"
(click)="openDeleteModal(deleteModal)"><i
class="fas fa-trash pr-2"></i>{{'process.overview.delete' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}
</button>
<button class="btn btn-success" routerLink="/processes/new"><i
class="fas fa-plus pr-2"></i>{{'process.overview.new' | translate}}</button>
</div>
</ng-template>

<ng-template #deleteModal>

<div>
Expand Down
81 changes: 7 additions & 74 deletions src/app/process-page/overview/process-overview.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,27 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { VarDirective } from '../../shared/utils/var.directive';
import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { NO_ERRORS_SCHEMA, TemplateRef } from '@angular/core';
import { ProcessDataService } from '../../core/data/processes/process-data.service';
import { Process } from '../processes/process.model';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { EPerson } from '../../core/eperson/models/eperson.model';
import { By } from '@angular/platform-browser';
import { ProcessStatus } from '../processes/process-status.model';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { createPaginatedList } from '../../shared/testing/utils.test';
import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { DatePipe } from '@angular/common';
import { BehaviorSubject } from 'rxjs';
import { ProcessBulkDeleteService } from './process-bulk-delete.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ProcessOverviewService } from './process-overview.service';

describe('ProcessOverviewComponent', () => {
let component: ProcessOverviewComponent;
let fixture: ComponentFixture<ProcessOverviewComponent>;

let processService: ProcessDataService;
let ePersonService: EPersonDataService;
let paginationService;

let processes: Process[];
let ePerson: EPerson;

let processBulkDeleteService;
let modalService;

const pipe = new DatePipe('en-US');

function init() {
processes = [
Object.assign(new Process(), {
processId: 1,
scriptName: 'script-name',
startTime: '2020-03-19 00:30:00',
endTime: '2020-03-19 23:30:00',
processStatus: ProcessStatus.COMPLETED
}),
Object.assign(new Process(), {
processId: 2,
scriptName: 'script-name',
startTime: '2020-03-20 00:30:00',
endTime: '2020-03-20 23:30:00',
processStatus: ProcessStatus.FAILED
}),
Object.assign(new Process(), {
processId: 3,
scriptName: 'another-script-name',
startTime: '2020-03-21 00:30:00',
endTime: '2020-03-21 23:30:00',
processStatus: ProcessStatus.RUNNING
})
];
ePerson = Object.assign(new EPerson(), {
metadata: {
'eperson.firstname': [
{
value: 'John',
language: null
}
],
'eperson.lastname': [
{
value: 'Doe',
language: null
}
]
}
});
processService = jasmine.createSpyObj('processService', {
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(processes))
processService = jasmine.createSpyObj('processOverviewService', {
timeStarted: '2024-02-05 16:43:32',
});
ePersonService = jasmine.createSpyObj('ePersonService', {
findById: createSuccessfulRemoteDataObject$(ePerson)
});

paginationService = new PaginationServiceStub();

processBulkDeleteService = jasmine.createSpyObj('processBulkDeleteService', {
clearAllProcesses: {},
Expand All @@ -96,11 +37,7 @@ describe('ProcessOverviewComponent', () => {
});

(processBulkDeleteService.isToBeDeleted as jasmine.Spy).and.callFake((id) => {
if (id === 2) {
return true;
} else {
return false;
}
return id === 2;
});

modalService = jasmine.createSpyObj('modalService', {
Expand All @@ -114,9 +51,7 @@ describe('ProcessOverviewComponent', () => {
declarations: [ProcessOverviewComponent, VarDirective],
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])],
providers: [
{ provide: ProcessDataService, useValue: processService },
{ provide: EPersonDataService, useValue: ePersonService },
{ provide: PaginationService, useValue: paginationService },
{ provide: ProcessOverviewService, useValue: processService },
{ provide: ProcessBulkDeleteService, useValue: processBulkDeleteService },
{ provide: NgbModal, useValue: modalService },
],
Expand Down Expand Up @@ -165,21 +100,19 @@ describe('ProcessOverviewComponent', () => {

describe('openDeleteModal', () => {
it('should open the modal', () => {
component.openDeleteModal({});
component.openDeleteModal({} as TemplateRef<any>);
expect(modalService.open).toHaveBeenCalledWith({});
});
});

describe('deleteSelected', () => {
it('should call the deleteSelectedProcesses method on the processBulkDeleteService and close the modal when processing is done', () => {
spyOn(component, 'closeModal');
spyOn(component, 'setProcesses');

component.deleteSelected();

expect(processBulkDeleteService.deleteSelectedProcesses).toHaveBeenCalled();
expect(component.closeModal).toHaveBeenCalled();
expect(component.setProcesses).toHaveBeenCalled();
});
});
});
64 changes: 7 additions & 57 deletions src/app/process-page/overview/process-overview.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list.model';
import { Process } from '../processes/process.model';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { switchMap } from 'rxjs/operators';
import { ProcessDataService } from '../../core/data/processes/process-data.service';
import { PaginationService } from '../../core/pagination/pagination.service';
import { FindListOptions } from '../../core/data/find-list-options.model';
import { Component, OnDestroy, OnInit, TemplateRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { ProcessBulkDeleteService } from './process-bulk-delete.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { hasValue } from '../../shared/empty.util';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { ProcessOverviewService } from './process-overview.service';
import { ProcessOverviewService, ProcessSortField } from './process-overview.service';
import { ProcessStatus } from '../processes/process-status.model';

@Component({
Expand All @@ -25,64 +15,25 @@ import { ProcessStatus } from '../processes/process-status.model';
*/
export class ProcessOverviewComponent implements OnInit, OnDestroy {

// Enums are redeclared here so they can be used in the template
protected readonly ProcessStatus = ProcessStatus;
protected readonly ProcessSortField = ProcessSortField;

/**
* List of all processes
*/
processesRD$: Observable<RemoteData<PaginatedList<Process>>>;

/**
* The current pagination configuration for the page used by the FindAll method
*/
config: FindListOptions = Object.assign(new FindListOptions(), {
elementsPerPage: 20
});

/**
* The current pagination configuration for the page
*/
pageConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'po',
pageSize: 20
});

/**
* Date format to use for start and end time of processes
*/
dateFormat = 'yyyy-MM-dd HH:mm:ss';

processesToDelete: string[] = [];
private modalRef: any;

isProcessingSub: Subscription;

constructor(protected processService: ProcessDataService,
protected processOverviewService: ProcessOverviewService,
protected paginationService: PaginationService,
protected ePersonService: EPersonDataService,
constructor(protected processOverviewService: ProcessOverviewService,
protected modalService: NgbModal,
public processBulkDeleteService: ProcessBulkDeleteService,
protected dsoNameService: DSONameService,
) {
}

ngOnInit(): void {
this.setProcesses();
this.processBulkDeleteService.clearAllProcesses();
}

/**
* Send a request to fetch all processes for the current page
*/
setProcesses() {
this.processesRD$ = this.paginationService.getFindListOptions(this.pageConfig.id, this.config).pipe(
switchMap((config) => this.processService.findAll(config, true, false))
);
}

ngOnDestroy(): void {
this.paginationService.clearPagination(this.pageConfig.id);
if (hasValue(this.isProcessingSub)) {
this.isProcessingSub.unsubscribe();
}
Expand All @@ -92,7 +43,7 @@ export class ProcessOverviewComponent implements OnInit, OnDestroy {
* Open a given modal.
* @param content - the modal content.
*/
openDeleteModal(content) {
openDeleteModal(content: TemplateRef<any>) {
this.modalRef = this.modalService.open(content);
}

Expand All @@ -118,7 +69,6 @@ export class ProcessOverviewComponent implements OnInit, OnDestroy {
.subscribe((isProcessing) => {
if (!isProcessing) {
this.closeModal();
this.setProcesses();
}
});
}
Expand Down
Loading

0 comments on commit 27d05ae

Please sign in to comment.