mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
added create-from functionality
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
<div class="container" *ngVar="(processRD$ | async)?.payload as process">
|
<div class="container" *ngVar="(processRD$ | async)?.payload as process">
|
||||||
<h2>{{'process.detail.title' | translate:{ id: process?.processId, name: process?.scriptName } }}</h2>
|
<div class="d-flex">
|
||||||
|
<h2 class="flex-grow-1">{{'process.detail.title' | translate:{id: process?.processId, name: process?.scriptName} }}</h2>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-light" [routerLink]="'/processes/new'" [queryParams]="{id: process?.processId}">{{'process.detail.create' | translate}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<ds-process-detail-field id="process-name" [title]="'process.detail.script'">
|
<ds-process-detail-field id="process-name" [title]="'process.detail.script'">
|
||||||
<div>{{ process?.scriptName }}</div>
|
<div>{{ process?.scriptName }}</div>
|
||||||
</ds-process-detail-field>
|
</ds-process-detail-field>
|
||||||
|
25
src/app/process-page/form/process-form.component.html
Normal file
25
src/app/process-page/form/process-form.component.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<h2 class="col-12">
|
||||||
|
{{headerKey | translate}}
|
||||||
|
</h2>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<form #form="ngForm" (ngSubmit)="submitForm(form)">
|
||||||
|
<ds-scripts-select [script]="selectedScript" (select)="selectedScript = $event; parameters = undefined"></ds-scripts-select>
|
||||||
|
<ds-process-parameters [initialParams]="parameters" [script]="selectedScript" (updateParameters)="parameters = $event"></ds-process-parameters>
|
||||||
|
<button [routerLink]="['/processes']" class="btn btn-light float-left">{{ 'process.new.cancel' | translate }}</button>
|
||||||
|
<button type="submit" class="btn btn-light float-right">{{ 'process.new.submit' | translate }}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<ds-script-help [script]="selectedScript"></ds-script-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="missingParameters.length > 0" class="alert alert-danger validation-error">
|
||||||
|
{{'process.new.parameter.required.missing' | translate}}
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let missing of missingParameters">{{missing}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
86
src/app/process-page/form/process-form.component.spec.ts
Normal file
86
src/app/process-page/form/process-form.component.spec.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ProcessFormComponent } from './process-form.component';
|
||||||
|
import { ScriptDataService } from '../../core/data/processes/script-data.service';
|
||||||
|
import { ScriptParameter } from '../scripts/script-parameter.model';
|
||||||
|
import { Script } from '../scripts/script.model';
|
||||||
|
import { ProcessParameter } from '../processes/process-parameter.model';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
|
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
||||||
|
import { RequestService } from '../../core/data/request.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
describe('NewProcessComponent', () => {
|
||||||
|
let component: ProcessFormComponent;
|
||||||
|
let fixture: ComponentFixture<ProcessFormComponent>;
|
||||||
|
let scriptService;
|
||||||
|
let parameterValues;
|
||||||
|
let script;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
const param1 = new ScriptParameter();
|
||||||
|
const param2 = new ScriptParameter();
|
||||||
|
script = Object.assign(new Script(), { parameters: [param1, param2] });
|
||||||
|
parameterValues = [
|
||||||
|
Object.assign(new ProcessParameter(), { name: '-a', value: 'bla' }),
|
||||||
|
Object.assign(new ProcessParameter(), { name: '-b', value: '123' }),
|
||||||
|
Object.assign(new ProcessParameter(), { name: '-c', value: 'value' }),
|
||||||
|
];
|
||||||
|
scriptService = jasmine.createSpyObj(
|
||||||
|
'scriptService',
|
||||||
|
{
|
||||||
|
invoke: observableOf({
|
||||||
|
response:
|
||||||
|
{
|
||||||
|
isSuccessful: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
init();
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
FormsModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderMock
|
||||||
|
}
|
||||||
|
})],
|
||||||
|
declarations: [ProcessFormComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: ScriptDataService, useValue: scriptService },
|
||||||
|
{ provide: NotificationsService, useClass: NotificationsServiceStub },
|
||||||
|
{ provide: RequestService, useValue: {} },
|
||||||
|
{ provide: Router, useValue: {} },
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ProcessFormComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
component.parameters = parameterValues;
|
||||||
|
component.selectedScript = script;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call invoke on the scriptService on submit', () => {
|
||||||
|
component.submitForm({ invalid: false } as any);
|
||||||
|
expect(scriptService.invoke).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
146
src/app/process-page/form/process-form.component.ts
Normal file
146
src/app/process-page/form/process-form.component.ts
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { Script } from '../scripts/script.model';
|
||||||
|
import { Process } from '../processes/process.model';
|
||||||
|
import { ProcessParameter } from '../processes/process-parameter.model';
|
||||||
|
import { ScriptDataService } from '../../core/data/processes/script-data.service';
|
||||||
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
|
import { ScriptParameter } from '../scripts/script-parameter.model';
|
||||||
|
import { RequestEntry } from '../../core/data/request.reducer';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { RequestService } from '../../core/data/request.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to create a new script
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-process-form',
|
||||||
|
templateUrl: './process-form.component.html',
|
||||||
|
styleUrls: ['./process-form.component.scss'],
|
||||||
|
})
|
||||||
|
export class ProcessFormComponent implements OnInit {
|
||||||
|
/**
|
||||||
|
* The currently selected script
|
||||||
|
*/
|
||||||
|
@Input() public selectedScript: Script = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The process to create
|
||||||
|
*/
|
||||||
|
@Input() public process: Process = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter values to use to start the process
|
||||||
|
*/
|
||||||
|
@Input() public parameters: ProcessParameter[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional files that are used as parameter values
|
||||||
|
*/
|
||||||
|
public files: File[] = [];
|
||||||
|
|
||||||
|
@Input() public headerKey: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the missing parameters on submission
|
||||||
|
*/
|
||||||
|
public missingParameters = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private scriptService: ScriptDataService,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private translationService: TranslateService,
|
||||||
|
private requestService: RequestService,
|
||||||
|
private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.process = new Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the form, sets the parameters to correct values and invokes the script with the correct parameters
|
||||||
|
* @param form
|
||||||
|
*/
|
||||||
|
submitForm(form: NgForm) {
|
||||||
|
if (!this.validateForm(form) || this.isRequiredMissing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stringParameters: ProcessParameter[] = this.parameters.map((parameter: ProcessParameter) => {
|
||||||
|
return {
|
||||||
|
name: parameter.name,
|
||||||
|
value: this.checkValue(parameter)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.scriptService.invoke(this.selectedScript.id, stringParameters, this.files)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((requestEntry: RequestEntry) => {
|
||||||
|
if (requestEntry.response.isSuccessful) {
|
||||||
|
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();
|
||||||
|
} else {
|
||||||
|
const title = this.translationService.get('process.new.notification.error.title');
|
||||||
|
const content = this.translationService.get('process.new.notification.error.content');
|
||||||
|
this.notificationsService.error(title, content)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the parameter values are files
|
||||||
|
* Replaces file parameters by strings and stores the files in a separate list
|
||||||
|
* @param processParameter The parameter value to check
|
||||||
|
*/
|
||||||
|
private checkValue(processParameter: ProcessParameter): string {
|
||||||
|
if (typeof processParameter.value === 'object') {
|
||||||
|
this.files = [...this.files, processParameter.value];
|
||||||
|
return processParameter.value.name;
|
||||||
|
}
|
||||||
|
return processParameter.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the form
|
||||||
|
* Returns false if the form is invalid
|
||||||
|
* Returns true if the form is valid
|
||||||
|
* @param form The NgForm object to validate
|
||||||
|
*/
|
||||||
|
private validateForm(form: NgForm) {
|
||||||
|
if (form.invalid) {
|
||||||
|
Object.keys(form.controls).forEach((key) => {
|
||||||
|
form.controls[key].markAsDirty();
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isRequiredMissing() {
|
||||||
|
const setParams: string[] = this.parameters
|
||||||
|
.map((param) => param.name);
|
||||||
|
const requiredParams: ScriptParameter[] = this.selectedScript.parameters.filter((param) => param.mandatory);
|
||||||
|
for (const rp of requiredParams) {
|
||||||
|
if (!setParams.includes(rp.name)) {
|
||||||
|
this.missingParameters.push(rp.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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('/processes');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function controlContainerFactory(controlContainer?: ControlContainer) {
|
||||||
|
return controlContainer;
|
||||||
|
}
|
@@ -9,7 +9,7 @@
|
|||||||
{{param.nameLong || param.name}}
|
{{param.nameLong || param.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<ds-parameter-value-input [parameter]="selectedScriptParameter" (updateValue)="selectedParameterValue = $event" class="d-block col" [index]="index"></ds-parameter-value-input>
|
<ds-parameter-value-input [initialValue]="parameterValue.value" [parameter]="selectedScriptParameter" (updateValue)="selectedParameterValue = $event" class="d-block col" [index]="index"></ds-parameter-value-input>
|
||||||
<button *ngIf="removable" class="btn btn-light col-1 remove-button" (click)="removeParameter.emit(parameterValue);"><span class="fas fa-trash"></span></button>
|
<button *ngIf="removable" class="btn btn-light col-1 remove-button" (click)="removeParameter.emit(parameterValue);"><span class="fas fa-trash"></span></button>
|
||||||
<span *ngIf="!removable" class="col-1"></span>
|
<span *ngIf="!removable" class="col-1"></span>
|
||||||
</div>
|
</div>
|
@@ -3,7 +3,7 @@ import { ProcessParameter } from '../../../processes/process-parameter.model';
|
|||||||
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
||||||
import { hasNoValue } from '../../../../shared/empty.util';
|
import { hasNoValue } from '../../../../shared/empty.util';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../new-process.component';
|
import { controlContainerFactory } from '../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to select a single parameter for a process
|
* Component to select a single parameter for a process
|
||||||
@@ -12,17 +12,19 @@ import { controlContainerFactory } from '../../new-process.component';
|
|||||||
selector: 'ds-parameter-select',
|
selector: 'ds-parameter-select',
|
||||||
templateUrl: './parameter-select.component.html',
|
templateUrl: './parameter-select.component.html',
|
||||||
styleUrls: ['./parameter-select.component.scss'],
|
styleUrls: ['./parameter-select.component.scss'],
|
||||||
viewProviders: [ { provide: ControlContainer,
|
viewProviders: [{
|
||||||
|
provide: ControlContainer,
|
||||||
useFactory: controlContainerFactory,
|
useFactory: controlContainerFactory,
|
||||||
deps: [[new Optional(), NgForm]] } ]
|
deps: [[new Optional(), NgForm]]
|
||||||
|
}]
|
||||||
})
|
})
|
||||||
export class ParameterSelectComponent implements OnInit {
|
export class ParameterSelectComponent {
|
||||||
@Input() index: number;
|
@Input() index: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current parameter value of the selected parameter
|
* The current parameter value of the selected parameter
|
||||||
*/
|
*/
|
||||||
@Input() parameterValue: ProcessParameter;
|
@Input() parameterValue: ProcessParameter = new ProcessParameter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The available script parameters for the script
|
* The available script parameters for the script
|
||||||
@@ -44,12 +46,6 @@ export class ParameterSelectComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
@Output() changeParameter: EventEmitter<ProcessParameter> = new EventEmitter<ProcessParameter>();
|
@Output() changeParameter: EventEmitter<ProcessParameter> = new EventEmitter<ProcessParameter>();
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
if (hasNoValue(this.parameterValue)) {
|
|
||||||
this.parameterValue = new ProcessParameter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the script parameter based on the currently selected name
|
* Returns the script parameter based on the currently selected name
|
||||||
*/
|
*/
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit, Optional } from '@angular/core';
|
import { Component, OnInit, Optional } from '@angular/core';
|
||||||
import { ValueInputComponent } from '../value-input.component';
|
import { ValueInputComponent } from '../value-input.component';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../../new-process.component';
|
import { controlContainerFactory } from '../../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the value of a boolean parameter
|
* Represents the value of a boolean parameter
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit, Optional } from '@angular/core';
|
import { Component, OnInit, Optional, Input } from '@angular/core';
|
||||||
import { ValueInputComponent } from '../value-input.component';
|
import { ValueInputComponent } from '../value-input.component';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../../new-process.component';
|
import { controlContainerFactory } from '../../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the user inputted value of a date parameter
|
* Represents the user inputted value of a date parameter
|
||||||
@@ -19,6 +19,11 @@ export class DateValueInputComponent extends ValueInputComponent<string> {
|
|||||||
* The current value of the date string
|
* The current value of the date string
|
||||||
*/
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
|
@Input() initialValue;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.value = this.initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
setValue(value) {
|
setValue(value) {
|
||||||
this.value = value;
|
this.value = value;
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, Optional } from '@angular/core';
|
import { Component, Optional } from '@angular/core';
|
||||||
import { ValueInputComponent } from '../value-input.component';
|
import { ValueInputComponent } from '../value-input.component';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../../new-process.component';
|
import { controlContainerFactory } from '../../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the user inputted value of a file parameter
|
* Represents the user inputted value of a file parameter
|
@@ -0,0 +1,7 @@
|
|||||||
|
<div [ngSwitch]="parameter?.type">
|
||||||
|
<ds-string-value-input *ngSwitchCase="parameterTypes.STRING" [initialValue]="initialValue" (updateValue)="updateValue.emit($event)" [index]="index"></ds-string-value-input>
|
||||||
|
<ds-string-value-input *ngSwitchCase="parameterTypes.OUTPUT" [initialValue]="initialValue" (updateValue)="updateValue.emit($event)" [index]="index"></ds-string-value-input>
|
||||||
|
<ds-date-value-input *ngSwitchCase="parameterTypes.DATE" [initialValue]="initialValue" (updateValue)="updateValue.emit($event)" [index]="index"></ds-date-value-input>
|
||||||
|
<ds-file-value-input *ngSwitchCase="parameterTypes.FILE" (updateValue)="updateValue.emit($event)" [index]="index"></ds-file-value-input>
|
||||||
|
<ds-boolean-value-input *ngSwitchCase="parameterTypes.BOOLEAN" (updateValue)="updateValue.emit($event)" [index]="index"></ds-boolean-value-input>
|
||||||
|
</div>
|
@@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output } f
|
|||||||
import { ScriptParameterType } from '../../../scripts/script-parameter-type.model';
|
import { ScriptParameterType } from '../../../scripts/script-parameter-type.model';
|
||||||
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../new-process.component';
|
import { controlContainerFactory } from '../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that renders the correct parameter value input based the script parameter's type
|
* Component that renders the correct parameter value input based the script parameter's type
|
||||||
@@ -23,6 +23,8 @@ export class ParameterValueInputComponent {
|
|||||||
*/
|
*/
|
||||||
@Input() parameter: ScriptParameter;
|
@Input() parameter: ScriptParameter;
|
||||||
|
|
||||||
|
|
||||||
|
@Input() initialValue: any;
|
||||||
/**
|
/**
|
||||||
* Emits the value of the input when its updated
|
* Emits the value of the input when its updated
|
||||||
*/
|
*/
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, Optional } from '@angular/core';
|
import { Component, Optional, Input } from '@angular/core';
|
||||||
import { ValueInputComponent } from '../value-input.component';
|
import { ValueInputComponent } from '../value-input.component';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../../../new-process.component';
|
import { controlContainerFactory } from '../../../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the user inputted value of a string parameter
|
* Represents the user inputted value of a string parameter
|
||||||
@@ -19,6 +19,11 @@ export class StringValueInputComponent extends ValueInputComponent<string> {
|
|||||||
* The current value of the string
|
* The current value of the string
|
||||||
*/
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
|
@Input() initialValue;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.value = this.initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
setValue(value) {
|
setValue(value) {
|
||||||
this.value = value;
|
this.value = value;
|
@@ -4,7 +4,7 @@ import { ProcessParameter } from '../../processes/process-parameter.model';
|
|||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { ScriptParameter } from '../../scripts/script-parameter.model';
|
import { ScriptParameter } from '../../scripts/script-parameter.model';
|
||||||
import { controlContainerFactory } from '../new-process.component';
|
import { controlContainerFactory } from '../process-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents the selected list of parameters for a script
|
* Component that represents the selected list of parameters for a script
|
||||||
@@ -13,15 +13,18 @@ import { controlContainerFactory } from '../new-process.component';
|
|||||||
selector: 'ds-process-parameters',
|
selector: 'ds-process-parameters',
|
||||||
templateUrl: './process-parameters.component.html',
|
templateUrl: './process-parameters.component.html',
|
||||||
styleUrls: ['./process-parameters.component.scss'],
|
styleUrls: ['./process-parameters.component.scss'],
|
||||||
viewProviders: [ { provide: ControlContainer,
|
viewProviders: [{
|
||||||
|
provide: ControlContainer,
|
||||||
useFactory: controlContainerFactory,
|
useFactory: controlContainerFactory,
|
||||||
deps: [[new Optional(), NgForm]] } ]
|
deps: [[new Optional(), NgForm]]
|
||||||
|
}]
|
||||||
})
|
})
|
||||||
export class ProcessParametersComponent implements OnChanges {
|
export class ProcessParametersComponent implements OnChanges {
|
||||||
/**
|
/**
|
||||||
* The currently selected script
|
* The currently selected script
|
||||||
*/
|
*/
|
||||||
@Input() script: Script;
|
@Input() script: Script;
|
||||||
|
@Input() initialParams: ProcessParameter[];
|
||||||
/**
|
/**
|
||||||
* Emits the parameter values when they're updated
|
* Emits the parameter values when they're updated
|
||||||
*/
|
*/
|
||||||
@@ -32,6 +35,12 @@ export class ProcessParametersComponent implements OnChanges {
|
|||||||
*/
|
*/
|
||||||
parameterValues: ProcessParameter[];
|
parameterValues: ProcessParameter[];
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (hasValue(this.initialParams)) {
|
||||||
|
this.parameterValues = this.initialParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure the parameters are reset when the script changes
|
* Makes sure the parameters are reset when the script changes
|
||||||
* @param changes
|
* @param changes
|
||||||
@@ -47,9 +56,13 @@ export class ProcessParametersComponent implements OnChanges {
|
|||||||
* Initializes the first parameter value
|
* Initializes the first parameter value
|
||||||
*/
|
*/
|
||||||
initParameters() {
|
initParameters() {
|
||||||
|
if (hasValue(this.initialParams)) {
|
||||||
|
this.parameterValues = this.initialParams;
|
||||||
|
} else {
|
||||||
this.parameterValues = [];
|
this.parameterValues = [];
|
||||||
this.initializeParameter();
|
this.initializeParameter();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a single parameter value using its new value and index
|
* Updates a single parameter value using its new value and index
|
@@ -1,14 +1,14 @@
|
|||||||
import { Component, EventEmitter, OnDestroy, OnInit, Optional, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Optional, Output } from '@angular/core';
|
||||||
import { ScriptDataService } from '../../../core/data/processes/script-data.service';
|
import { ScriptDataService } from '../../../core/data/processes/script-data.service';
|
||||||
import { Script } from '../../scripts/script.model';
|
import { Script } from '../../scripts/script.model';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { distinctUntilChanged, filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators';
|
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasNoValue, hasValue } from '../../../shared/empty.util';
|
||||||
import { ControlContainer, FormControl, NgForm } from '@angular/forms';
|
import { ControlContainer, NgForm } from '@angular/forms';
|
||||||
import { controlContainerFactory } from '../new-process.component';
|
import { controlContainerFactory } from '../process-form.component';
|
||||||
|
|
||||||
const SCRIPT_QUERY_PARAMETER = 'script';
|
const SCRIPT_QUERY_PARAMETER = 'script';
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ export class ScriptsSelectComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.routeSub = this.route.queryParams
|
this.routeSub = this.route.queryParams
|
||||||
.pipe(
|
.pipe(
|
||||||
|
filter((params: Params) => hasNoValue(params.id)),
|
||||||
map((params: Params) => params[SCRIPT_QUERY_PARAMETER]),
|
map((params: Params) => params[SCRIPT_QUERY_PARAMETER]),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
switchMap((id: string) =>
|
switchMap((id: string) =>
|
||||||
@@ -82,11 +83,15 @@ export class ScriptsSelectComponent implements OnInit, OnDestroy {
|
|||||||
this.router.navigate([],
|
this.router.navigate([],
|
||||||
{
|
{
|
||||||
queryParams: { [SCRIPT_QUERY_PARAMETER]: value },
|
queryParams: { [SCRIPT_QUERY_PARAMETER]: value },
|
||||||
queryParamsHandling: 'merge'
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
set script(value: Script) {
|
||||||
|
this._selectedScript = value;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
if (hasValue(this.routeSub)) {
|
if (hasValue(this.routeSub)) {
|
||||||
this.routeSub.unsubscribe();
|
this.routeSub.unsubscribe();
|
@@ -1,25 +1,6 @@
|
|||||||
<div class="container">
|
<ng-container *ngIf="fromExisting$ && (fromExisting$ | async)">
|
||||||
<div class="row">
|
<ds-process-form *ngVar="fromExisting$ | async as process" headerKey="process.new.header" [selectedScript]="script$ | async" [parameters]="process.parameters"></ds-process-form>
|
||||||
<h2 class="col-12">
|
</ng-container>
|
||||||
{{'process.new.header' | translate}}
|
<ng-container *ngIf="!fromExisting$ || !(fromExisting$ | async)">
|
||||||
</h2>
|
<ds-process-form headerKey="process.new.header"></ds-process-form>
|
||||||
<div class="col-12 col-md-6">
|
</ng-container>
|
||||||
<form #form="ngForm" (ngSubmit)="submitForm(form)">
|
|
||||||
<ds-scripts-select (select)="selectedScript = $event"></ds-scripts-select>
|
|
||||||
<ds-process-parameters [script]="selectedScript" (updateParameters)="parameters = $event"></ds-process-parameters>
|
|
||||||
<button [routerLink]="['/processes']" class="btn btn-light float-left">{{ 'process.new.cancel' | translate }}</button>
|
|
||||||
<button type="submit" class="btn btn-light float-right">{{ 'process.new.submit' | translate }}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-md-6">
|
|
||||||
<ds-script-help [script]="selectedScript"></ds-script-help>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="missingParameters.length > 0" class="alert alert-danger validation-error">
|
|
||||||
{{'process.new.parameter.required.missing' | translate}}
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let missing of missingParameters">{{missing}}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
@@ -13,7 +13,10 @@ import { of as observableOf } from 'rxjs';
|
|||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
||||||
import { RequestService } from '../../core/data/request.service';
|
import { RequestService } from '../../core/data/request.service';
|
||||||
import { Router } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { LinkService } from '../../core/cache/builders/link.service';
|
||||||
|
import { VarDirective } from '../../shared/utils/var.directive';
|
||||||
|
import { ProcessDataService } from '../../core/data/processes/process-data.service';
|
||||||
|
|
||||||
describe('NewProcessComponent', () => {
|
describe('NewProcessComponent', () => {
|
||||||
let component: NewProcessComponent;
|
let component: NewProcessComponent;
|
||||||
@@ -55,12 +58,14 @@ describe('NewProcessComponent', () => {
|
|||||||
useClass: TranslateLoaderMock
|
useClass: TranslateLoaderMock
|
||||||
}
|
}
|
||||||
})],
|
})],
|
||||||
declarations: [NewProcessComponent],
|
declarations: [NewProcessComponent, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: ScriptDataService, useValue: scriptService },
|
{ provide: ScriptDataService, useValue: scriptService },
|
||||||
{ provide: NotificationsService, useClass: NotificationsServiceStub },
|
{ provide: NotificationsService, useClass: NotificationsServiceStub },
|
||||||
{ provide: RequestService, useValue: {} },
|
{ provide: RequestService, useValue: {} },
|
||||||
{ provide: Router, useValue: {} },
|
{ provide: ActivatedRoute, useValue: { snapshot: { queryParams: {} } } },
|
||||||
|
{ provide: LinkService, useValue: {} },
|
||||||
|
{ provide: ProcessDataService, useValue: {} },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
})
|
})
|
||||||
@@ -70,17 +75,10 @@ describe('NewProcessComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(NewProcessComponent);
|
fixture = TestBed.createComponent(NewProcessComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.parameters = parameterValues;
|
|
||||||
component.selectedScript = script;
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call invoke on the scriptService on submit', () => {
|
|
||||||
component.submitForm({ invalid: false } as any);
|
|
||||||
expect(scriptService.invoke).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -1,16 +1,13 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Script } from '../scripts/script.model';
|
|
||||||
import { Process } from '../processes/process.model';
|
import { Process } from '../processes/process.model';
|
||||||
import { ProcessParameter } from '../processes/process-parameter.model';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ScriptDataService } from '../../core/data/processes/script-data.service';
|
import { ProcessDataService } from '../../core/data/processes/process-data.service';
|
||||||
import { ControlContainer, NgForm } from '@angular/forms';
|
import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
|
||||||
import { ScriptParameter } from '../scripts/script-parameter.model';
|
import { Observable } from 'rxjs';
|
||||||
import { RequestEntry } from '../../core/data/request.reducer';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { LinkService } from '../../core/cache/builders/link.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||||
import { take } from 'rxjs/operators';
|
import { Script } from '../scripts/script.model';
|
||||||
import { RequestService } from '../../core/data/request.service';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to create a new script
|
* Component to create a new script
|
||||||
@@ -21,124 +18,23 @@ import { Router } from '@angular/router';
|
|||||||
styleUrls: ['./new-process.component.scss'],
|
styleUrls: ['./new-process.component.scss'],
|
||||||
})
|
})
|
||||||
export class NewProcessComponent implements OnInit {
|
export class NewProcessComponent implements OnInit {
|
||||||
/**
|
fromExisting$?: Observable<Process>;
|
||||||
* The currently selected script
|
script$?: Observable<Script>;
|
||||||
*/
|
|
||||||
public selectedScript: Script;
|
|
||||||
|
|
||||||
/**
|
constructor(private route: ActivatedRoute, private processService: ProcessDataService, private linkService: LinkService) {
|
||||||
* The process to create
|
|
||||||
*/
|
|
||||||
public process: Process;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parameter values to use to start the process
|
|
||||||
*/
|
|
||||||
public parameters: ProcessParameter[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional files that are used as parameter values
|
|
||||||
*/
|
|
||||||
public files: File[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains the missing parameters on submission
|
|
||||||
*/
|
|
||||||
public missingParameters = [];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private scriptService: ScriptDataService,
|
|
||||||
private notificationsService: NotificationsService,
|
|
||||||
private translationService: TranslateService,
|
|
||||||
private requestService: RequestService,
|
|
||||||
private router: Router) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit() {
|
||||||
this.process = new Process();
|
const id = this.route.snapshot.queryParams.id;
|
||||||
}
|
if (id) {
|
||||||
|
this.fromExisting$ = this.processService.findById(id).pipe(getFirstSucceededRemoteDataPayload());
|
||||||
/**
|
this.script$ = this.fromExisting$.pipe(
|
||||||
* Validates the form, sets the parameters to correct values and invokes the script with the correct parameters
|
map((process: Process) => this.linkService.resolveLink<Process>(process, followLink('script'))),
|
||||||
* @param form
|
switchMap((process: Process) => process.script),
|
||||||
*/
|
getFirstSucceededRemoteDataPayload()
|
||||||
submitForm(form: NgForm) {
|
|
||||||
if (!this.validateForm(form) || this.isRequiredMissing()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stringParameters: ProcessParameter[] = this.parameters.map((parameter: ProcessParameter) => {
|
|
||||||
return {
|
|
||||||
name: parameter.name,
|
|
||||||
value: this.checkValue(parameter)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
this.scriptService.invoke(this.selectedScript.id, stringParameters, this.files)
|
|
||||||
.pipe(take(1))
|
|
||||||
.subscribe((requestEntry: RequestEntry) => {
|
|
||||||
if (requestEntry.response.isSuccessful) {
|
|
||||||
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();
|
|
||||||
} else {
|
|
||||||
const title = this.translationService.get('process.new.notification.error.title');
|
|
||||||
const content = this.translationService.get('process.new.notification.error.content');
|
|
||||||
this.notificationsService.error(title, content)
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the parameter values are files
|
|
||||||
* Replaces file parameters by strings and stores the files in a separate list
|
|
||||||
* @param processParameter The parameter value to check
|
|
||||||
*/
|
|
||||||
private checkValue(processParameter: ProcessParameter): string {
|
|
||||||
if (typeof processParameter.value === 'object') {
|
|
||||||
this.files = [...this.files, processParameter.value];
|
|
||||||
return processParameter.value.name;
|
|
||||||
}
|
|
||||||
return processParameter.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the form
|
|
||||||
* Returns false if the form is invalid
|
|
||||||
* Returns true if the form is valid
|
|
||||||
* @param form The NgForm object to validate
|
|
||||||
*/
|
|
||||||
private validateForm(form: NgForm) {
|
|
||||||
if (form.invalid) {
|
|
||||||
Object.keys(form.controls).forEach((key) => {
|
|
||||||
form.controls[key].markAsDirty();
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isRequiredMissing() {
|
|
||||||
const setParams: string[] = this.parameters
|
|
||||||
.map((param) => param.name);
|
|
||||||
const requiredParams: ScriptParameter[] = this.selectedScript.parameters.filter((param) => param.mandatory)
|
|
||||||
for (const rp of requiredParams) {
|
|
||||||
if (!setParams.includes(rp.name)) {
|
|
||||||
this.missingParameters.push(rp.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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('/processes');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function controlContainerFactory(controlContainer?: ControlContainer) {
|
|
||||||
return controlContainer;
|
|
||||||
}
|
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
<div [ngSwitch]="parameter?.type">
|
|
||||||
<ds-string-value-input *ngSwitchCase="parameterTypes.STRING" (updateValue)="updateValue.emit($event)" [index]="index"></ds-string-value-input>
|
|
||||||
<ds-string-value-input *ngSwitchCase="parameterTypes.OUTPUT" (updateValue)="updateValue.emit($event)" [index]="index"></ds-string-value-input>
|
|
||||||
<ds-date-value-input *ngSwitchCase="parameterTypes.DATE" (updateValue)="updateValue.emit($event)" [index]="index"></ds-date-value-input>
|
|
||||||
<ds-file-value-input *ngSwitchCase="parameterTypes.FILE" (updateValue)="updateValue.emit($event)" [index]="index"></ds-file-value-input>
|
|
||||||
<ds-boolean-value-input *ngSwitchCase="parameterTypes.BOOLEAN" (updateValue)="updateValue.emit($event)" [index]="index"></ds-boolean-value-input>
|
|
||||||
</div>
|
|
@@ -2,20 +2,21 @@ import { NgModule } from '@angular/core';
|
|||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { ProcessPageRoutingModule } from './process-page-routing.module';
|
import { ProcessPageRoutingModule } from './process-page-routing.module';
|
||||||
import { NewProcessComponent } from './new/new-process.component';
|
import { NewProcessComponent } from './new/new-process.component';
|
||||||
import { ScriptsSelectComponent } from './new/scripts-select/scripts-select.component';
|
import { ScriptsSelectComponent } from './form/scripts-select/scripts-select.component';
|
||||||
import { ScriptHelpComponent } from './new/script-help/script-help.component';
|
import { ScriptHelpComponent } from './form/script-help/script-help.component';
|
||||||
import { ParameterSelectComponent } from './new/process-parameters/parameter-select/parameter-select.component';
|
import { ParameterSelectComponent } from './form/process-parameters/parameter-select/parameter-select.component';
|
||||||
import { ProcessParametersComponent } from './new/process-parameters/process-parameters.component';
|
import { ProcessParametersComponent } from './form/process-parameters/process-parameters.component';
|
||||||
import { StringValueInputComponent } from './new/process-parameters/parameter-value-input/string-value-input/string-value-input.component';
|
import { StringValueInputComponent } from './form/process-parameters/parameter-value-input/string-value-input/string-value-input.component';
|
||||||
import { ParameterValueInputComponent } from './new/process-parameters/parameter-value-input/parameter-value-input.component';
|
import { ParameterValueInputComponent } from './form/process-parameters/parameter-value-input/parameter-value-input.component';
|
||||||
import { FileValueInputComponent } from './new/process-parameters/parameter-value-input/file-value-input/file-value-input.component';
|
import { FileValueInputComponent } from './form/process-parameters/parameter-value-input/file-value-input/file-value-input.component';
|
||||||
import { BooleanValueInputComponent } from './new/process-parameters/parameter-value-input/boolean-value-input/boolean-value-input.component';
|
import { BooleanValueInputComponent } from './form/process-parameters/parameter-value-input/boolean-value-input/boolean-value-input.component';
|
||||||
import { DateValueInputComponent } from './new/process-parameters/parameter-value-input/date-value-input/date-value-input.component';
|
import { DateValueInputComponent } from './form/process-parameters/parameter-value-input/date-value-input/date-value-input.component';
|
||||||
import { ProcessOverviewComponent } from './overview/process-overview.component';
|
import { ProcessOverviewComponent } from './overview/process-overview.component';
|
||||||
import { ProcessDetailComponent } from './detail/process-detail.component';
|
import { ProcessDetailComponent } from './detail/process-detail.component';
|
||||||
import { ProcessDetailFieldComponent } from './detail/process-detail-field/process-detail-field.component';
|
import { ProcessDetailFieldComponent } from './detail/process-detail-field/process-detail-field.component';
|
||||||
import { ProcessBreadcrumbsService } from './process-breadcrumbs.service';
|
import { ProcessBreadcrumbsService } from './process-breadcrumbs.service';
|
||||||
import { ProcessBreadcrumbResolver } from './process-breadcrumb.resolver';
|
import { ProcessBreadcrumbResolver } from './process-breadcrumb.resolver';
|
||||||
|
import { ProcessFormComponent } from './form/process-form.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -35,7 +36,8 @@ import { ProcessBreadcrumbResolver } from './process-breadcrumb.resolver';
|
|||||||
DateValueInputComponent,
|
DateValueInputComponent,
|
||||||
ProcessOverviewComponent,
|
ProcessOverviewComponent,
|
||||||
ProcessDetailComponent,
|
ProcessDetailComponent,
|
||||||
ProcessDetailFieldComponent
|
ProcessDetailFieldComponent,
|
||||||
|
ProcessFormComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ProcessBreadcrumbResolver,
|
ProcessBreadcrumbResolver,
|
||||||
|
@@ -13,6 +13,7 @@ import { RemoteData } from '../../core/data/remote-data';
|
|||||||
import { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { SCRIPT } from '../scripts/script.resource-type';
|
import { SCRIPT } from '../scripts/script.resource-type';
|
||||||
import { Script } from '../scripts/script.model';
|
import { Script } from '../scripts/script.model';
|
||||||
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object representing a process
|
* Object representing a process
|
||||||
@@ -83,7 +84,7 @@ export class Process implements CacheableObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The Script that created this Process
|
* The Script that created this Process
|
||||||
* Will be undefined unless the owningCollection {@link HALLink} has been resolved.
|
* Will be undefined unless the script {@link HALLink} has been resolved.
|
||||||
*/
|
*/
|
||||||
@link(SCRIPT)
|
@link(SCRIPT)
|
||||||
script?: Observable<RemoteData<Script>>;
|
script?: Observable<RemoteData<Script>>;
|
||||||
|
@@ -22,7 +22,11 @@ import { RouterLinkDirectiveStub } from './router-link-directive.stub';
|
|||||||
MySimpleItemActionComponent,
|
MySimpleItemActionComponent,
|
||||||
RouterLinkDirectiveStub,
|
RouterLinkDirectiveStub,
|
||||||
NgComponentOutletDirectiveStub
|
NgComponentOutletDirectiveStub
|
||||||
], schemas: [
|
],
|
||||||
|
exports: [
|
||||||
|
QueryParamsDirectiveStub
|
||||||
|
],
|
||||||
|
schemas: [
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@@ -1971,6 +1971,8 @@
|
|||||||
|
|
||||||
"process.detail.status" : "Status",
|
"process.detail.status" : "Status",
|
||||||
|
|
||||||
|
"process.detail.create" : "Create similar process",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"process.overview.table.finish" : "Finish time",
|
"process.overview.table.finish" : "Finish time",
|
||||||
|
Reference in New Issue
Block a user