created new process page

This commit is contained in:
lotte
2020-03-19 16:20:41 +01:00
committed by Art Lowel
parent b535d166e0
commit 1cb39cef41
25 changed files with 460 additions and 0 deletions

View File

@@ -86,6 +86,7 @@ export function getDSOPath(dso: DSpaceObject): string {
path: PROFILE_MODULE_PATH,
loadChildren: './profile-page/profile-page.module#ProfilePageModule', canActivate: [AuthenticatedGuard]
},
{ path: 'processes', loadChildren: './process-page/process-page.module#ProcessPageModule', canActivate: [AuthenticatedGuard] },
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent },
],
{

View File

@@ -139,6 +139,8 @@ import { VersionDataService } from './data/version-data.service';
import { VersionHistoryDataService } from './data/version-history-data.service';
import { Version } from './shared/version.model';
import { VersionHistory } from './shared/version-history.model';
import { Script } from '../process-page/scripts/script.model';
import { Process } from '../process-page/processes/process.model';
/**
* When not in production, endpoint responses can be mocked for testing purposes
@@ -307,6 +309,8 @@ export const models =
ItemType,
ExternalSource,
ExternalSourceEntry,
Script,
Process,
Version,
VersionHistory
];

View File

@@ -0,0 +1,10 @@
<div class="container">
<div class="row">
<div class="col-12 col-md-6">
<ds-scripts-select (select)="selectScript($event)"></ds-scripts-select>
</div>
<div class="col-12 col-md-6">
<ds-script-help [script]="selectedScript"></ds-script-help>
</div>
</div>
</div>

View File

@@ -0,0 +1,16 @@
import { Component } from '@angular/core';
import { Script } from '../scripts/script.model';
@Component({
selector: 'ds-new-process',
templateUrl: './new-process.component.html',
styleUrls: ['./new-process.component.scss'],
})
export class NewProcessComponent {
public selectedScript: Script;
selectScript(script: Script) {
this.selectedScript = script;
console.log('selected script: ', script);
}
}

View File

@@ -0,0 +1,9 @@
<h3>{{script?.name}}</h3>
<span>{{script?.description}}</span>
<table class="table-border less mt-3">
<tr *ngFor="let param of script?.parameters">
<td>{{param.name}} {{param.nameLong}}{{param.type !== 'boolean' ? '<<' + param.type + '>>' : ''}}</td>
<td>{{param.description}}</td>
</tr>
</table>

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ScriptHelpComponent } from './script-help.component';
describe('ScriptHelpComponent', () => {
let component: ScriptHelpComponent;
let fixture: ComponentFixture<ScriptHelpComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ScriptHelpComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ScriptHelpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,11 @@
import { Component, Input } from '@angular/core';
import { Script } from '../../scripts/script.model';
@Component({
selector: 'ds-script-help',
templateUrl: './script-help.component.html',
styleUrls: ['./script-help.component.scss']
})
export class ScriptHelpComponent {
@Input() script: Script;
}

View File

@@ -0,0 +1,6 @@
<select [(ngModel)]="selectedScript">
<option selected>Choose a script...</option>
<option *ngFor="let script of scripts | async" [ngValue]="script">
{{script.name}}
</option>
</select>

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ScriptsSelectComponent } from './scripts-select.component';
describe('ScriptsSelectComponent', () => {
let component: ScriptsSelectComponent;
let fixture: ComponentFixture<ScriptsSelectComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ScriptsSelectComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ScriptsSelectComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,41 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { ScriptDataService } from '../../scripts/script-data.service';
import { Script } from '../../scripts/script.model';
import { Observable } from 'rxjs';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
import { PaginatedList } from '../../../core/data/paginated-list';
import { map } from 'rxjs/operators';
@Component({
selector: 'ds-scripts-select',
templateUrl: './scripts-select.component.html',
styleUrls: ['./scripts-select.component.scss']
})
export class ScriptsSelectComponent implements OnInit {
@Output() select: EventEmitter<Script> = new EventEmitter<Script>();
scripts: Observable<Script[]>;
private _selectedScript;
constructor(
private scriptService: ScriptDataService
) {
}
ngOnInit() {
this.scripts = this.scriptService.findAll({ elementsPerPage: Number.MAX_SAFE_INTEGER })
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((paginatedList: PaginatedList<Script>) => paginatedList.page)
)
}
get selectedScript() {
return this._selectedScript;
}
set selectedScript(value) {
this._selectedScript = value;
this.select.emit(value);
}
}

View File

@@ -0,0 +1,17 @@
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { NewProcessComponent } from './new/new-process.component';
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'new',
component: NewProcessComponent,
},
])
]
})
export class ProcessPageRoutingModule {
}

View File

@@ -0,0 +1,30 @@
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { ProcessPageRoutingModule } from './process-page-routing.module';
import { ProcessDataService } from './processes/process-data.service';
import { ScriptDataService } from './scripts/script-data.service';
import { NewProcessComponent } from './new/new-process.component';
import { ScriptsSelectComponent } from './new/scripts-select/scripts-select.component';
import { ScriptHelpComponent } from './new/script-help/script-help.component';
@NgModule({
imports: [
ProcessPageRoutingModule,
SharedModule,
],
declarations: [
NewProcessComponent,
ScriptsSelectComponent,
ScriptHelpComponent
],
entryComponents: [
],
providers: [
ProcessDataService,
ScriptDataService
]
})
export class ProcessPageModule {
}

View File

@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { DataService } from '../../core/data/data.service';
import { RequestService } from '../../core/data/request.service';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../../core/core.reducers';
import { ObjectCacheService } from '../../core/cache/object-cache.service';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from '../../core/data/default-change-analyzer.service';
import { Process } from './process.model';
@Injectable()
export class ProcessDataService extends DataService<Process> {
protected linkPath = 'processes';
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<Process>) {
super();
}
}

View File

@@ -0,0 +1,13 @@
/**
* A parameter used for running a process
*/
export class ProcessParameter {
/**
* The name of the parameter Eg. '-d', '-f' etc.
*/
name: string;
/**
* The value of the parameter
*/
value: string;
}

View File

@@ -0,0 +1,9 @@
/**
* List of process statuses
*/
export enum ProcessStatus {
SCHEDULED,
RUNNING,
COMPLETED,
FAILED
}

View File

@@ -0,0 +1,74 @@
import { ProcessStatus } from './process-status.model';
import { ProcessParameter } from './process-parameter.model';
import { CacheableObject } from '../../core/cache/object-cache.reducer';
import { HALLink } from '../../core/shared/hal-link.model';
import { autoserialize, deserialize } from 'cerialize';
import { PROCESS } from './process.resource-type';
import { excludeFromEquals } from '../../core/utilities/equals.decorators';
import { ResourceType } from '../../core/shared/resource-type';
import { typedObject } from '../../core/cache/builders/build-decorators';
@typedObject
export class Process implements CacheableObject {
static type = PROCESS;
/**
* The object type
*/
@excludeFromEquals
@autoserialize
type: ResourceType;
/**
* The identifier for this process
*/
@autoserialize
processId: string;
/**
* The UUID for the user that started the process
*/
@autoserialize
userId: string;
/**
* The start time for this process
*/
@autoserialize
startTime: string;
/**
* The end time for this process
*/
@autoserialize
endTime: string;
/**
* The name of the script run by this process
*/
@autoserialize
scriptName: string;
/**
* The status of this process
*/
@autoserialize
processStatus: ProcessStatus;
/**
* The parameters for this process
*/
@autoserialize
parameters: ProcessParameter[];
/**
* The {@link HALLink}s for this Process
*/
@deserialize
_links: {
self: HALLink,
script: HALLink,
output: HALLink,
files: HALLink
};
}

View File

@@ -0,0 +1,9 @@
/**
* The resource type for Process
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
import { ResourceType } from '../../core/shared/resource-type';
export const PROCESS = new ResourceType('process');

View File

@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { DataService } from '../../core/data/data.service';
import { RequestService } from '../../core/data/request.service';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../../core/core.reducers';
import { ObjectCacheService } from '../../core/cache/object-cache.service';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from '../../core/data/default-change-analyzer.service';
import { Script } from './script.model';
@Injectable()
export class ScriptDataService extends DataService<Script> {
protected linkPath = 'scripts';
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<Script>) {
super();
}
}

View File

@@ -0,0 +1,10 @@
/**
* List of parameter types used for scripts
*/
export enum ScriptParameterType {
STRING = 'string',
DATE = 'date',
BOOLEAN = 'boolean',
FILE = 'file',
OUTPUT = 'output'
}

View File

@@ -0,0 +1,31 @@
import { ScriptParameterType } from './script-parameter-type.model';
/**
* A parameter that can be used when running a script
*/
export class ScriptParameter {
/**
* The name of the parameter Eg. '-d', '-f' etc.
*/
name: string;
/**
* Short description about the purpose of this parameter
*/
description: string;
/**
* The type of parameter
*/
type: ScriptParameterType;
/**
* The long name for this parameter Eg. '--directory', '--force' etc.
*/
nameLong: string;
/**
* Whether or not this parameter is mandatory
*/
mandatory: boolean;
}

View File

@@ -0,0 +1,52 @@
import { CacheableObject } from '../../core/cache/object-cache.reducer';
import { HALLink } from '../../core/shared/hal-link.model';
import { autoserialize, deserialize } from 'cerialize';
import { SCRIPT } from './script.resource-type';
import { ScriptParameter } from './script-parameter.model';
import { typedObject } from '../../core/cache/builders/build-decorators';
import { excludeFromEquals } from '../../core/utilities/equals.decorators';
import { ResourceType } from '../../core/shared/resource-type';
@typedObject
export class Script implements CacheableObject {
static type = SCRIPT;
/**
* The object type
*/
@excludeFromEquals
@autoserialize
type: ResourceType;
/**
* The identifier of this script
*/
@autoserialize
id: string;
/**
* The name of this script
*/
@autoserialize
name: string;
/**
* A short description of this script
*/
@autoserialize
description: string;
/**
* The available parameters for this script
*/
@autoserialize
parameters: ScriptParameter[];
/**
* The {@link HALLink}s for this Script
*/
@deserialize
_links: {
self: HALLink,
};
}

View File

@@ -0,0 +1,9 @@
/**
* The resource type for Script
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
import { ResourceType } from '../../core/shared/resource-type';
export const SCRIPT = new ResourceType('script');