mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
fixed tests and feedback
This commit is contained in:
@@ -1616,6 +1616,8 @@
|
||||
|
||||
"process.new.select-parameters": "Parameters",
|
||||
|
||||
"process.new.cancel": "Cancel",
|
||||
|
||||
"process.new.submit": "Submit",
|
||||
|
||||
"process.new.select-script": "Script",
|
||||
@@ -1630,6 +1632,24 @@
|
||||
|
||||
"process.new.parameter.string.required": "Parameter value is required",
|
||||
|
||||
"process.new.parameter.type.value": "value",
|
||||
|
||||
"process.new.parameter.type.file": "file",
|
||||
|
||||
"process.new.parameter.required.missing": "The following parameters are required but still missing:",
|
||||
|
||||
"process.new.notification.success.title": "Success",
|
||||
|
||||
"process.new.notification.success.content": "The process was successfully created",
|
||||
|
||||
"process.new.notification.error.title": "Error",
|
||||
|
||||
"process.new.notification.error.content": "An error occurred while creating this process",
|
||||
|
||||
"process.new.header": "Create a new process",
|
||||
|
||||
"process.new.title": "Create a new process",
|
||||
|
||||
|
||||
|
||||
"publication.listelement.badge": "Publication",
|
||||
|
@@ -10,10 +10,12 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { DefaultChangeAnalyzer } from '../default-change-analyzer.service';
|
||||
import { Script } from '../../../process-page/scripts/script.model';
|
||||
import { ProcessParameter } from '../../../process-page/processes/process-parameter.model';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { find, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { URLCombiner } from '../../url-combiner/url-combiner';
|
||||
import { MultipartPostRequest, RestRequest } from '../request.models';
|
||||
import { RequestService } from '../request.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RequestEntry } from '../request.reducer';
|
||||
|
||||
@Injectable()
|
||||
export class ScriptDataService extends DataService<Script> {
|
||||
@@ -31,15 +33,18 @@ export class ScriptDataService extends DataService<Script> {
|
||||
super();
|
||||
}
|
||||
|
||||
public invoke(scriptName: string, parameters: ProcessParameter[], files: File[]) {
|
||||
this.getBrowseEndpoint().pipe(
|
||||
public invoke(scriptName: string, parameters: ProcessParameter[], files: File[]): Observable<RequestEntry> {
|
||||
const requestId = this.requestService.generateRequestId();
|
||||
return this.getBrowseEndpoint().pipe(
|
||||
map((endpoint: string) => new URLCombiner(endpoint, scriptName, 'processes').toString()),
|
||||
map((endpoint: string) => {
|
||||
const body = this.getInvocationFormData(parameters, files);
|
||||
return new MultipartPostRequest(this.requestService.generateRequestId(), endpoint, body)
|
||||
return new MultipartPostRequest(requestId, endpoint, body)
|
||||
}),
|
||||
map((request: RestRequest) => this.requestService.configure(request))
|
||||
).subscribe();
|
||||
map((request: RestRequest) => this.requestService.configure(request)),
|
||||
switchMap(() => this.requestService.getByUUID(requestId)),
|
||||
find((request: RequestEntry) => request.completed)
|
||||
);
|
||||
}
|
||||
|
||||
private getInvocationFormData(parameters: ProcessParameter[], files: File[]): FormData {
|
||||
|
@@ -1,14 +1,25 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h2 class="col-12">
|
||||
{{'process.new.header' | translate}}
|
||||
</h2>
|
||||
<div class="col-12 col-md-6">
|
||||
<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 [disabled]="form.invalid" type="submit" class="btn btn-light float-right">{{ 'process.new.submit' | translate }}</button>
|
||||
<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>
|
||||
|
@@ -9,6 +9,9 @@ import { MockTranslateLoader } from '../../shared/testing/mock-translate-loader'
|
||||
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 { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
|
||||
describe('NewProcessComponent', () => {
|
||||
let component: NewProcessComponent;
|
||||
@@ -26,7 +29,17 @@ describe('NewProcessComponent', () => {
|
||||
Object.assign(new ProcessParameter(), { name: '-b', value: '123' }),
|
||||
Object.assign(new ProcessParameter(), { name: '-c', value: 'value' }),
|
||||
];
|
||||
scriptService = jasmine.createSpyObj('scriptService', ['invoke'])
|
||||
scriptService = jasmine.createSpyObj(
|
||||
'scriptService',
|
||||
{
|
||||
invoke: observableOf({
|
||||
response:
|
||||
{
|
||||
isSuccessful: true
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
beforeEach(async(() => {
|
||||
@@ -43,6 +56,7 @@ describe('NewProcessComponent', () => {
|
||||
declarations: [NewProcessComponent],
|
||||
providers: [
|
||||
{ provide: ScriptDataService, useValue: scriptService },
|
||||
{ provide: NotificationsService, useValue: NotificationsServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
@@ -62,7 +76,7 @@ describe('NewProcessComponent', () => {
|
||||
});
|
||||
|
||||
it('should call invoke on the scriptService on submit', () => {
|
||||
component.submitForm({ invalid: false });
|
||||
component.submitForm({ invalid: false } as any);
|
||||
expect(scriptService.invoke).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -3,7 +3,13 @@ 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 { NgForm } from '@angular/forms';
|
||||
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 { pipe } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Component to create a new script
|
||||
@@ -27,14 +33,19 @@ export class NewProcessComponent implements OnInit {
|
||||
/**
|
||||
* The parameter values to use to start the process
|
||||
*/
|
||||
public parameters: ProcessParameter[];
|
||||
public parameters: ProcessParameter[] = [];
|
||||
|
||||
/**
|
||||
* Optional files that are used as parameter values
|
||||
*/
|
||||
public files: File[] = [];
|
||||
|
||||
constructor(private scriptService: ScriptDataService) {
|
||||
/**
|
||||
* Contains the missing parameters on submission
|
||||
*/
|
||||
public missingParameters = [];
|
||||
|
||||
constructor(private scriptService: ScriptDataService, private notificationsService: NotificationsService, private translationService: TranslateService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -46,7 +57,7 @@ export class NewProcessComponent implements OnInit {
|
||||
* @param form
|
||||
*/
|
||||
submitForm(form: NgForm) {
|
||||
if (!this.validateForm(form)) {
|
||||
if (!this.validateForm(form) || this.isRequiredMissing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,6 +69,18 @@ export class NewProcessComponent implements OnInit {
|
||||
}
|
||||
);
|
||||
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)
|
||||
} 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,4 +111,20 @@ export class NewProcessComponent implements OnInit {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
export function controlContainerFactory(controlContainer?: ControlContainer) {
|
||||
return controlContainer;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="form-row mb-2">
|
||||
<select required id="process-parameters"
|
||||
<select id="process-parameters"
|
||||
class="form-control col"
|
||||
name="script"
|
||||
name="parameter-{{index}}"
|
||||
[(ngModel)]="selectedParameter"
|
||||
#param="ngModel">
|
||||
<option [ngValue]="undefined">Add a parameter...</option>
|
||||
@@ -9,7 +9,7 @@
|
||||
{{param.nameLong || param.name}}
|
||||
</option>
|
||||
</select>
|
||||
<ds-parameter-value-input [parameter]="selectedScriptParameter" (updateValue)="selectedParameterValue = $event" class="d-block col"></ds-parameter-value-input>
|
||||
<ds-parameter-value-input [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>
|
||||
<span *ngIf="!removable" class="col-1"></span>
|
||||
</div>
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, Optional } from '@angular/core';
|
||||
import { ProcessParameter } from '../../../processes/process-parameter.model';
|
||||
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
||||
import { hasNoValue } from '../../../../shared/empty.util';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../new-process.component';
|
||||
|
||||
/**
|
||||
* Component to select a single parameter for a process
|
||||
@@ -9,13 +11,19 @@ import { hasNoValue } from '../../../../shared/empty.util';
|
||||
@Component({
|
||||
selector: 'ds-parameter-select',
|
||||
templateUrl: './parameter-select.component.html',
|
||||
styleUrls: ['./parameter-select.component.scss']
|
||||
styleUrls: ['./parameter-select.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class ParameterSelectComponent implements OnInit {
|
||||
@Input() index: number;
|
||||
|
||||
/**
|
||||
* The current parameter value of the selected parameter
|
||||
*/
|
||||
@Input() parameterValue: ProcessParameter;
|
||||
|
||||
/**
|
||||
* The available script parameters for the script
|
||||
*/
|
||||
|
@@ -1 +1 @@
|
||||
<input type="hidden" value="true"/>
|
||||
<input type="hidden" value="true" name="boolean-value-{{index}}" id="boolean-value-{{index}}"/>
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, Optional } from '@angular/core';
|
||||
import { ValueInputComponent } from '../value-input.component';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../../new-process.component';
|
||||
|
||||
/**
|
||||
* Represents the value of a boolean parameter
|
||||
@@ -7,7 +9,10 @@ import { ValueInputComponent } from '../value-input.component';
|
||||
@Component({
|
||||
selector: 'ds-boolean-value-input',
|
||||
templateUrl: './boolean-value-input.component.html',
|
||||
styleUrls: ['./boolean-value-input.component.scss']
|
||||
styleUrls: ['./boolean-value-input.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class BooleanValueInputComponent extends ValueInputComponent<boolean> implements OnInit {
|
||||
ngOnInit() {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<input required #string="ngModel" type="text" class="form-control" id="string-value-input" [ngModel]="value" (ngModelChange)="setValue($event)"/>
|
||||
<input required #string="ngModel" type="text" class="form-control" name="date-value-{{index}}" id="date-value-{{index}}" [ngModel]="value" (ngModelChange)="setValue($event)"/>
|
||||
<div *ngIf="string.invalid && (string.dirty || string.touched)"
|
||||
class="alert alert-danger validation-error">
|
||||
<div *ngIf="string.errors.required">
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, Optional } from '@angular/core';
|
||||
import { ValueInputComponent } from '../value-input.component';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../../new-process.component';
|
||||
|
||||
/**
|
||||
* Represents the user inputted value of a date parameter
|
||||
@@ -7,7 +9,10 @@ import { ValueInputComponent } from '../value-input.component';
|
||||
@Component({
|
||||
selector: 'ds-date-value-input',
|
||||
templateUrl: './date-value-input.component.html',
|
||||
styleUrls: ['./date-value-input.component.scss']
|
||||
styleUrls: ['./date-value-input.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class DateValueInputComponent extends ValueInputComponent<string> {
|
||||
/**
|
||||
|
@@ -1,7 +1,10 @@
|
||||
<label for="file-upload" class="btn btn-light">
|
||||
<label for="file-upload-{{index}}" class="d-flex align-items-center">
|
||||
<span class="btn btn-light">
|
||||
{{'process.new.parameter.file.upload-button' | translate}}
|
||||
</span>
|
||||
<span class="file-name ml-1">{{fileObject?.name}}</span>
|
||||
</label>
|
||||
<input requireFile #file="ngModel" type="file" id="file-upload" class="form-control-file d-none" [ngModel]="file" (ngModelChange)="setFile($event)"/>
|
||||
<input requireFile #file="ngModel" type="file" name="file-upload-{{index}}" id="file-upload-{{index}}" class="form-control-file d-none" [ngModel]="fileObject" (ngModelChange)="setFile($event)"/>
|
||||
<div *ngIf="file.invalid && (file.dirty || file.touched)"
|
||||
class="alert alert-danger validation-error">
|
||||
<div *ngIf="file.errors.required">
|
||||
|
@@ -0,0 +1,6 @@
|
||||
.file-name {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule, NgForm, ReactiveFormsModule } from '@angular/forms';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { MockTranslateLoader } from '../../../../../shared/mocks/mock-translate-loader';
|
||||
import { By } from '@angular/platform-browser';
|
||||
@@ -9,7 +9,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { FileValueAccessorDirective } from '../../../../../shared/utils/file-value-accessor.directive';
|
||||
import { FileValidator } from '../../../../../shared/utils/require-file.validator';
|
||||
|
||||
describe('FileValueInputComponent', () => {
|
||||
‡describe('FileValueInputComponent', () => {
|
||||
let component: FileValueInputComponent;
|
||||
let fixture: ComponentFixture<FileValueInputComponent>;
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, Optional } from '@angular/core';
|
||||
import { ValueInputComponent } from '../value-input.component';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../../new-process.component';
|
||||
|
||||
/**
|
||||
* Represents the user inputted value of a file parameter
|
||||
@@ -7,15 +9,18 @@ import { ValueInputComponent } from '../value-input.component';
|
||||
@Component({
|
||||
selector: 'ds-file-value-input',
|
||||
templateUrl: './file-value-input.component.html',
|
||||
styleUrls: ['./file-value-input.component.scss']
|
||||
styleUrls: ['./file-value-input.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class FileValueInputComponent extends ValueInputComponent<File> {
|
||||
/**
|
||||
* The current value of the file
|
||||
*/
|
||||
file: File;
|
||||
fileObject: File;
|
||||
setFile(files) {
|
||||
this.file = files.length > 0 ? files[0] : undefined;
|
||||
this.updateValue.emit(this.file);
|
||||
this.fileObject = files.length > 0 ? files[0] : undefined;
|
||||
this.updateValue.emit(this.fileObject);
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div [ngSwitch]="parameter?.type">
|
||||
<ds-string-value-input *ngSwitchCase="parameterTypes.STRING" (updateValue)="updateValue.emit($event)"></ds-string-value-input>
|
||||
<ds-string-value-input *ngSwitchCase="parameterTypes.OUTPUT" (updateValue)="updateValue.emit($event)"></ds-string-value-input>
|
||||
<ds-date-value-input *ngSwitchCase="parameterTypes.DATE" (updateValue)="updateValue.emit($event)"></ds-date-value-input>
|
||||
<ds-file-value-input *ngSwitchCase="parameterTypes.FILE" (updateValue)="updateValue.emit($event)"></ds-file-value-input>
|
||||
<ds-boolean-value-input *ngSwitchCase="parameterTypes.BOOLEAN" (updateValue)="updateValue.emit($event)"></ds-boolean-value-input>
|
||||
<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>
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output } from '@angular/core';
|
||||
import { ScriptParameterType } from '../../../scripts/script-parameter-type.model';
|
||||
import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../new-process.component';
|
||||
|
||||
/**
|
||||
* Component that renders the correct parameter value input based the script parameter's type
|
||||
@@ -8,9 +10,14 @@ import { ScriptParameter } from '../../../scripts/script-parameter.model';
|
||||
@Component({
|
||||
selector: 'ds-parameter-value-input',
|
||||
templateUrl: './parameter-value-input.component.html',
|
||||
styleUrls: ['./parameter-value-input.component.scss']
|
||||
styleUrls: ['./parameter-value-input.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class ParameterValueInputComponent {
|
||||
@Input() index: number;
|
||||
|
||||
/**
|
||||
* The current script parameter
|
||||
*/
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<input required #string="ngModel" type="text" class="form-control" id="string-value-input" [ngModel]="value" (ngModelChange)="setValue($event)"/>
|
||||
<input required #string="ngModel" type="text" name="string-value-{{index}}" class="form-control" id="string-value-{{index}}" [ngModel]="value" (ngModelChange)="setValue($event)"/>
|
||||
<div *ngIf="string.invalid && (string.dirty || string.touched)"
|
||||
class="alert alert-danger validation-error">
|
||||
<div *ngIf="string.errors.required">
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule, NgForm } from '@angular/forms';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { MockTranslateLoader } from '../../../../../shared/mocks/mock-translate-loader';
|
||||
import { By } from '@angular/platform-browser';
|
||||
@@ -20,7 +20,9 @@ describe('StringValueInputComponent', () => {
|
||||
useClass: MockTranslateLoader
|
||||
}
|
||||
})],
|
||||
declarations: [StringValueInputComponent]
|
||||
declarations: [StringValueInputComponent],
|
||||
providers: [
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, Optional } from '@angular/core';
|
||||
import { ValueInputComponent } from '../value-input.component';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../../../new-process.component';
|
||||
|
||||
/**
|
||||
* Represents the user inputted value of a string parameter
|
||||
@@ -7,7 +9,10 @@ import { ValueInputComponent } from '../value-input.component';
|
||||
@Component({
|
||||
selector: 'ds-string-value-input',
|
||||
templateUrl: './string-value-input.component.html',
|
||||
styleUrls: ['./string-value-input.component.scss']
|
||||
styleUrls: ['./string-value-input.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class StringValueInputComponent extends ValueInputComponent<string> {
|
||||
/**
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { EventEmitter, Output } from '@angular/core';
|
||||
import { EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Abstract class that represents value input components
|
||||
*/
|
||||
export abstract class ValueInputComponent<T> {
|
||||
@Input() index: number;
|
||||
/**
|
||||
* Used by the subclasses to emit the value when it's updated
|
||||
*/
|
||||
|
@@ -5,6 +5,7 @@
|
||||
[parameters]="script.parameters"
|
||||
[parameterValue]="value"
|
||||
[removable]="!last"
|
||||
[index]="i"
|
||||
(removeParameter)="removeParameter(i)"
|
||||
(changeParameter)="updateParameter($event, i)"></ds-parameter-select>
|
||||
</div>
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnChanges, Optional, Output, SimpleChanges } from '@angular/core';
|
||||
import { Script } from '../../scripts/script.model';
|
||||
import { ProcessParameter } from '../../processes/process-parameter.model';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { ControlContainer, NgForm } from '@angular/forms';
|
||||
import { ScriptParameter } from '../../scripts/script-parameter.model';
|
||||
import { controlContainerFactory } from '../new-process.component';
|
||||
|
||||
/**
|
||||
* Component that represents the selected list of parameters for a script
|
||||
@@ -9,7 +12,10 @@ import { hasValue } from '../../../shared/empty.util';
|
||||
@Component({
|
||||
selector: 'ds-process-parameters',
|
||||
templateUrl: './process-parameters.component.html',
|
||||
styleUrls: ['./process-parameters.component.scss']
|
||||
styleUrls: ['./process-parameters.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class ProcessParametersComponent implements OnChanges {
|
||||
/**
|
||||
@@ -42,7 +48,7 @@ export class ProcessParametersComponent implements OnChanges {
|
||||
*/
|
||||
initParameters() {
|
||||
this.parameterValues = [];
|
||||
this.addParameter();
|
||||
this.initializeParameter();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +73,20 @@ export class ProcessParametersComponent implements OnChanges {
|
||||
this.parameterValues = this.parameterValues.filter((value, i) => i !== index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes parameter values based on the selected script
|
||||
*/
|
||||
initializeParameter() {
|
||||
if (hasValue(this.script)) {
|
||||
this.parameterValues = this.script.parameters
|
||||
.filter((param) => param.mandatory)
|
||||
.map(
|
||||
(parameter: ScriptParameter) => Object.assign(new ProcessParameter(), { name: parameter.name })
|
||||
);
|
||||
}
|
||||
this.addParameter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an empty parameter value to the end of the list
|
||||
*/
|
||||
|
@@ -3,7 +3,16 @@
|
||||
|
||||
<table class="table-borderless mt-3 text-secondary">
|
||||
<tr *ngFor="let param of script?.parameters">
|
||||
<td>{{param.name}} {{param.nameLong}} {{param.type !== 'boolean' ? '<' + param.type + '>' : ''}}</td>
|
||||
<td class="align-top text-nowrap">{{param.name}} {{param.nameLong}} <ng-container *ngTemplateOutlet="type; context: param"></ng-container></td>
|
||||
<td>{{param.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ng-template #type let-type="type">
|
||||
<ng-container [ngSwitch]="type">
|
||||
<span *ngSwitchCase="parameterTypes.DATE"><{{'process.new.parameter.type.value' | translate}}></span>
|
||||
<span *ngSwitchCase="parameterTypes.STRING"><{{'process.new.parameter.type.value' | translate}}></span>
|
||||
<span *ngSwitchCase="parameterTypes.OUTPUT"><{{'process.new.parameter.type.value' | translate}}></span>
|
||||
<span *ngSwitchCase="parameterTypes.FILE"><{{'process.new.parameter.type.file' | translate}}></span>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
@@ -5,6 +5,10 @@ import { ScriptParameter } from '../../scripts/script-parameter.model';
|
||||
import { Script } from '../../scripts/script.model';
|
||||
import { ScriptParameterType } from '../../scripts/script-parameter-type.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MockTranslateLoader } from '../../../shared/testing/mock-translate-loader';
|
||||
|
||||
describe('ScriptHelpComponent', () => {
|
||||
let component: ScriptHelpComponent;
|
||||
@@ -25,7 +29,16 @@ describe('ScriptHelpComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
init();
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ScriptHelpComponent ]
|
||||
imports: [
|
||||
FormsModule,
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: MockTranslateLoader
|
||||
}
|
||||
})],
|
||||
declarations: [ ScriptHelpComponent ],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Script } from '../../scripts/script.model';
|
||||
import { ScriptParameterType } from '../../scripts/script-parameter-type.model';
|
||||
|
||||
/**
|
||||
* Components that represents a help section for the script use and parameters
|
||||
@@ -14,4 +15,9 @@ export class ScriptHelpComponent {
|
||||
* The current script to show the help information for
|
||||
*/
|
||||
@Input() script: Script;
|
||||
|
||||
/**
|
||||
* The available script parameter types
|
||||
*/
|
||||
parameterTypes = ScriptParameterType;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<div class="form-group" *ngIf="scripts$ | async">
|
||||
<label for="process-script"><label>{{'process.new.select-script' | translate}}</label></label>
|
||||
<label for="process-script">{{'process.new.select-script' | translate}}</label>
|
||||
<select required id="process-script"
|
||||
class="form-control"
|
||||
name="script"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, OnDestroy, OnInit, Optional, Output } from '@angular/core';
|
||||
import { ScriptDataService } from '../../../core/data/processes/script-data.service';
|
||||
import { Script } from '../../scripts/script.model';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
@@ -7,6 +7,8 @@ import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { ControlContainer, FormControl, NgForm } from '@angular/forms';
|
||||
import { controlContainerFactory } from '../new-process.component';
|
||||
|
||||
const SCRIPT_QUERY_PARAMETER = 'script';
|
||||
|
||||
@@ -16,7 +18,10 @@ const SCRIPT_QUERY_PARAMETER = 'script';
|
||||
@Component({
|
||||
selector: 'ds-scripts-select',
|
||||
templateUrl: './scripts-select.component.html',
|
||||
styleUrls: ['./scripts-select.component.scss']
|
||||
styleUrls: ['./scripts-select.component.scss'],
|
||||
viewProviders: [ { provide: ControlContainer,
|
||||
useFactory: controlContainerFactory,
|
||||
deps: [[new Optional(), NgForm]] } ]
|
||||
})
|
||||
export class ScriptsSelectComponent implements OnInit, OnDestroy {
|
||||
@Output() select: EventEmitter<Script> = new EventEmitter<Script>();
|
||||
|
@@ -8,6 +8,7 @@ import { NewProcessComponent } from './new/new-process.component';
|
||||
{
|
||||
path: 'new',
|
||||
component: NewProcessComponent,
|
||||
data: { title: 'process.new.title' }
|
||||
},
|
||||
])
|
||||
]
|
||||
|
Reference in New Issue
Block a user