src/app/apps/apps-add/register/apps-register.component.ts
Applications Register Provide forms to register application
selector | app-apps |
styleUrls | styles.scss |
templateUrl | ./apps-register.component.html |
Properties |
|
Methods |
constructor(appsService: AppsService, notificationService: NotificationService, fb: FormBuilder, blockerService: BlockerService, loggerService: LoggerService, router: Router)
|
||||||||||||||||||||||||||||
Constructor
Parameters :
|
cancel |
cancel()
|
Navigate to the applications list
Returns :
void
|
isFormEmpty | ||||||||
isFormEmpty(form: FormGroup)
|
||||||||
State of a form (is empty)
Parameters :
Returns :
any
|
isValid |
isValid()
|
Return true if no form is invalid and at least one form is fill correctly
Returns :
boolean
|
newForm | ||||||||
newForm(index?: number)
|
||||||||
Adds form with the default values
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Will cleanup any {@link Subscription}s to prevent memory leaks.
Returns :
void
|
ngOnInit |
ngOnInit()
|
Initialize by creating the first form registration
Returns :
void
|
noValue |
noValue()
|
Return true if all the forms are empty
Returns :
boolean
|
register |
register()
|
Collect the filled forms and submit them to the service
Returns :
void
|
removeForm | ||||||||
removeForm(index: number)
|
||||||||
Removes form
Parameters :
Returns :
void
|
applicationTypes |
applicationTypes:
|
Default value : ApplicationType
|
Application types |
forms |
forms:
|
Type : FormGroup[]
|
Array of forms registration |
Private ngUnsubscribe$ |
ngUnsubscribe$:
|
Type : Subject<any>
|
Unsubscribe |
submitted |
submitted:
|
Default value : false
|
Form Submitted |
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription, Subject } from 'rxjs';
import { Router } from '@angular/router';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { AppsRegisterValidator } from './apps-register.validator';
import { finalize, takeUntil } from 'rxjs/operators';
import { ApplicationType } from '../../../shared/model/application-type';
import { AppsService } from '../../apps.service';
import { NotificationService } from '../../../shared/services/notification.service';
import { LoggerService } from '../../../shared/services/logger.service';
import { AppRegisterParams } from '../../components/apps.interface';
import { AppError } from '../../../shared/model/error.model';
import { BlockerService } from '../../../shared/components/blocker/blocker.service';
/**
* Applications Register
* Provide forms to register application
*
* @author Gunnar Hillert
* @author Damien Vitrac
*/
@Component({
selector: 'app-apps',
styleUrls: ['./styles.scss'],
templateUrl: './apps-register.component.html'
})
export class AppsRegisterComponent implements OnInit, OnDestroy {
/**
* Unsubscribe
*/
private ngUnsubscribe$: Subject<any> = new Subject();
/**
* Array of forms registration
* @type {Array}
*/
forms: FormGroup[] = [];
/**
* Application types
* @type {ApplicationType}
*/
applicationTypes = ApplicationType;
/**
* Form Submitted
*/
submitted = false;
/**
* Constructor
*
* @param {AppsService} appsService
* @param {NotificationService} notificationService
* @param {FormBuilder} fb
* @param {BlockerService} blockerService
* @param {LoggerService} loggerService
* @param {Router} router
*/
constructor(private appsService: AppsService,
private notificationService: NotificationService,
private fb: FormBuilder,
private blockerService: BlockerService,
private loggerService: LoggerService,
private router: Router) {
}
/**
* Will cleanup any {@link Subscription}s to prevent
* memory leaks.
*/
ngOnDestroy() {
this.ngUnsubscribe$.next();
this.ngUnsubscribe$.complete();
}
/**
* Initialize by creating the first form registration
*/
ngOnInit() {
this.newForm();
}
/**
* Collect the filled forms and submit them to the service
*/
register() {
this.submitted = true;
if (!this.isValid()) {
if (this.noValue()) {
this.notificationService.error('Please, register at least one application.');
} else {
this.notificationService.error('Some field(s) are missing or invalid.');
}
} else {
const applications: AppRegisterParams[] = this.forms.map((form: FormGroup) => {
if (!form.invalid && !this.isFormEmpty(form)) {
return {
name: form.get('name').value,
type: form.get('type').value as ApplicationType,
uri: form.get('uri').value,
metaDataUri: form.get('metaDataUri').value,
force: form.get('force').value
};
}
}).filter((a) => a != null);
this.blockerService.lock();
this.appsService.registerApps(applications)
.pipe(takeUntil(this.ngUnsubscribe$), finalize(() => this.blockerService.unlock()))
.subscribe(
data => {
this.notificationService.success(`${data.length} App(s) registered.`);
this.cancel();
},
error => {
this.notificationService.error(AppError.is(error) ? error.getMessage() : error);
}
);
}
}
/**
* Return true if no form is invalid and at least one form is fill correctly
*
* @returns {boolean}
*/
isValid(): boolean {
let count = 0;
for (let i = 0; i < this.forms.length; i++) {
if (this.isFormEmpty(this.forms[i])) {
continue;
}
if (this.forms[i].invalid) {
return false;
}
count++;
}
return (count > 0);
}
/**
* Return true if all the forms are empty
*
* @returns {boolean}
*/
noValue(): boolean {
for (let i = 0; i < this.forms.length; i++) {
if (!this.isFormEmpty(this.forms[i])) {
return false;
}
}
return true;
}
/**
* State of a form (is empty)
*
* @param {FormGroup} form
* @returns {boolean}
*/
isFormEmpty(form: FormGroup) {
return (form.get('uri').hasError('required') && form.get('name').hasError('required')
&& form.get('metaDataUri').value === '' && form.get('type').hasError('required'));
}
/**
* Adds form with the default values
* @param index Insertion index
*/
newForm(index?: number) {
index = index || this.forms.length;
const form = this.fb.group({
name: new FormControl('', [AppsRegisterValidator.appName, Validators.required]),
type: new FormControl('', Validators.required),
uri: new FormControl('', [AppsRegisterValidator.uri, Validators.required]),
metaDataUri: new FormControl('', AppsRegisterValidator.uri),
force: new FormControl(false)
});
this.forms.splice(index + 1, 0, form);
}
/**
* Removes form
* @param {number} index Index of the entry
*/
removeForm(index: number) {
this.forms.splice(index, 1);
}
/**
* Navigate to the applications list
*/
cancel() {
this.loggerService.log('Back to apps page ...');
this.router.navigate(['apps']);
}
}
<app-page-head class="step2">
<app-page-head-back [defaultUrl]="'/apps/add'" [isNotRegex]="'^(\/apps\/add\/)'"></app-page-head-back>
<app-page-head-title><strong>Register one or more applications</strong></app-page-head-title>
</app-page-head>
<div dataflowLayoutType type="medium">
<div class="dataflow-alert dataflow-alert-info">
Register one or more applications by entering a <strong>Name</strong>,
<strong>Type</strong> and <strong>App URI</strong> of the application Jar.<br>
You can also provide an optional <strong>metadata artifact URI</strong>. <br>
The App <strong>URI</strong> & the <strong>Metadata Artifact URI</strong> are typically provided using the Maven
coordinates of the Jar but can be a local file or a docker image URI.
</div>
<!--<p>
The App URI & the Metadata Artifact URI are typically provided using the Maven coordinates of the Jar
(),
but can be a local file or a docker image URI.
</p>-->
<form name="register-apps" class="clearfix" (submit)="register()" novalidate>
<div class="form-register-app form-register-app-box" [formGroup]="forms[i]"
id="registerAppsForm{{i}}" *ngFor="let form of forms; let i = index">
<div [class.has-error]="submitted && form.get('name').invalid && !isFormEmpty(form)"
class="control-name{{i}} form-group">
<label class="control-label" for="name{{i}}">Name <em class="required">*</em></label>
<input type="text" name="name{{i}}" id="name{{i}}" autofocus formControlName="name"
class="form-control" placeholder="scdf-sample-app"
[dataflowFocus]="true"/>
<span class="help-block" *ngIf="submitted && form.get('name').invalid && !isFormEmpty(form)">Please provide a valid name
for the app.</span>
</div>
<div [class.has-error]="submitted && form.get('type').invalid && !isFormEmpty(form)"
class="control-type{{i}} form-group">
<label class="control-label" for="type{{i}}">Type <em class="required">*</em></label>
<select formControlName="type" name="type{{i}}" id="type{{i}}" class="form-select" style="width: 300px">
<option value="">Please select a type...</option>
<option *ngFor="let typeKey of applicationTypes.getKeys()" value="{{ typeKey }}">
{{ applicationTypes[typeKey] | capitalize }}
</option>
</select>
<span class="help-block" *ngIf="submitted && form.get('type').invalid && !isFormEmpty(form)">Please provide a valid type.</span>
</div>
<div [class.has-error]="submitted && form.get('uri').invalid && !isFormEmpty(form)"
class="control-uri{{i}} form-group">
<label class="control-label" for="uri{{i}}">URI: <em class="required">*</em></label>
<input type="text" name="uri{{i}}" id="uri{{i}}" formControlName="uri"
class="form-control" placeholder="maven://io.spring.cloud:scdf-sample-app:jar:1.0.0">
<span class="help-block" *ngIf="submitted && form.get('uri').invalid && !isFormEmpty(form)">Please provide a valid URI
pointing to the respective properties file.</span>
<span class="help-block">e.g. maven://io.spring.cloud:scdf-sample-app:jar:1.0.0.BUILD-SNAPSHOT</span>
</div>
<div [class.has-error]="submitted && form.get('metaDataUri').invalid && !isFormEmpty(form)"
class="control-metaDataUri{{i}} form-group">
<label class="control-label" for="metaDataUri{{i}}">Metadata URI:</label>
<input type="text" id="metaDataUri{{i}}" name="metaDataUri{{i}}" formControlName="metaDataUri"
class="form-control"
placeholder="maven://io.spring.cloud:scdf-sample-app:jar:metadata:1.0.0 [OPTIONAL]">
<span class="help-block" *ngIf="submitted && form.get('metaDataUri').invalid && !isFormEmpty(form)">Please provide a
valid URI pointing to the respective properties file.</span>
</div>
<div class="form-group">
<div style="margin-left: 8px;">
<label class="checkbox-inline">
<input type="checkbox" name="force{{i}}" id="force{{i}}" formControlName="force">
Force<span class="checkbox-description">, the applications will be imported and installed
even if it already exists but only if not being used already.</span>
</label>
</div>
</div>
<div class="form-group">
<div style="margin-left: 8px;">
<button type="button" (click)="removeForm(i)" [disabled]="forms.length <= 1"
class="btn btn-default btn-fa btn-remove" title="Remove">
<span class="fa fa-trash"></span>
Remove
</button>
</div>
</div>
</div>
<div class="form-register-app form-register-app-empty">
<p>
<button type="button" name="add-form" (click)="newForm()" class="btn btn-primary btn-fa"
title="Add application">
<span class="fa fa-plus"></span>
New application
</button>
</p>
</div>
<app-page-actions>
<button name="cancel" type="button" class="btn btn-default" (click)="cancel()">Cancel</button>
<button name="register" type="submit" class="btn btn-primary">
Register the application(s)
</button>
</app-page-actions>
</form>
<ng-template #popTemplate>By checking <strong>force</strong>, the applications will be imported and installed
even if it already exists but only if not being used already.
</ng-template>
</div>