aboutsummaryrefslogtreecommitdiffstats
path: root/webapp/src/app/pages/build
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/src/app/pages/build')
-rw-r--r--webapp/src/app/pages/build/build.component.html63
-rw-r--r--webapp/src/app/pages/build/build.component.scss37
-rw-r--r--webapp/src/app/pages/build/build.component.spec.ts25
-rw-r--r--webapp/src/app/pages/build/build.component.ts198
-rw-r--r--webapp/src/app/pages/build/build.module.ts20
-rw-r--r--webapp/src/app/pages/build/settings/project-select-dropdown.component.ts40
-rw-r--r--webapp/src/app/pages/build/settings/sdk-select-dropdown.component.ts44
7 files changed, 427 insertions, 0 deletions
diff --git a/webapp/src/app/pages/build/build.component.html b/webapp/src/app/pages/build/build.component.html
new file mode 100644
index 0000000..a1ef62d
--- /dev/null
+++ b/webapp/src/app/pages/build/build.component.html
@@ -0,0 +1,63 @@
+<div class="row">
+ <div class="col-12">
+ <nb-card-body>
+ <nb-actions size="medium">
+ <nb-action>
+ <xds-project-select-dropdown></xds-project-select-dropdown>
+ </nb-action>
+ <nb-action>
+ <xds-sdk-select-dropdown></xds-sdk-select-dropdown>
+ </nb-action>
+ </nb-actions>
+ </nb-card-body>
+ </div>
+ <div class="col-md-12 col-lg-12 col-xxxl-6">
+ <nb-card size="xlarge">
+ <nb-tabset fullWidth>
+
+ <nb-tab tabTitle="Build">
+
+ <div class="row" style="margin-top:1em;">
+ <!-- FIXME SEB
+ <button class="btn pull-right " (click)="reset() ">
+ <span class="fa fa-eraser fa-size-x2"></span>
+ </button>
+ -->
+ <div class="col-md-12 text-center ">
+ <textarea rows="20" class="textarea-scroll" #scrollOutput>{{ cmdOutput }}</textarea>
+ </div>
+ </div>
+
+ <nb-card-body>
+ <nb-actions size="medium" fullWidth>
+ <nb-action (click)="clean()">
+ <i class="fa fa-eraser"></i>
+ <span>Clean</span>
+ </nb-action>
+ <nb-action (click)="preBuild()">
+ <i class="nb-list"></i>
+ <span>Pre-Build</span>
+ </nb-action>
+ <nb-action (click)="build()">
+ <i class="fa fa-wrench"></i>
+ <span>Build</span>
+ </nb-action>
+ <nb-action (click)="populate()">
+ <i class="fa fa-send"></i>
+ <span>Populate</span>
+ </nb-action>
+ </nb-actions>
+ </nb-card-body>
+
+ </nb-tab>
+
+ <nb-tab tabTitle="Deploy">
+ <span> Content deploy...</span>
+ </nb-tab>
+ <nb-tab tabTitle="Debug">
+ <span> Content debug...</span>
+ </nb-tab>
+ </nb-tabset>
+ </nb-card>
+ </div>
+</div>
diff --git a/webapp/src/app/pages/build/build.component.scss b/webapp/src/app/pages/build/build.component.scss
new file mode 100644
index 0000000..b256f66
--- /dev/null
+++ b/webapp/src/app/pages/build/build.component.scss
@@ -0,0 +1,37 @@
+@import '../../@theme/styles/themes';
+@import '~bootstrap/scss/mixins/breakpoints';
+@import '~@nebular/theme/styles/global/bootstrap/breakpoints';
+@include nb-install-component() {
+ nb-tabset {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ }
+ nb-tab {
+ padding: nb-theme(padding);
+ }
+ /deep/ ngx-tab1,
+ /deep/ ngx-tab2 {
+ display: block;
+ padding: nb-theme(padding);
+ }
+ @include media-breakpoint-down(xs) {
+ nb-tabset /deep/ul {
+ font-size: 1rem;
+ padding: 0 0.25rem;
+ }
+ }
+}
+
+nb-action {
+ i {
+ font-size: 2rem;
+ margin-right: 0.5rem;
+ }
+}
+
+.textarea-scroll {
+ border-color: lightgray;
+ width: 97%;
+ overflow-y: scroll;
+}
diff --git a/webapp/src/app/pages/build/build.component.spec.ts b/webapp/src/app/pages/build/build.component.spec.ts
new file mode 100644
index 0000000..016192c
--- /dev/null
+++ b/webapp/src/app/pages/build/build.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BuildComponent } from './build.component';
+
+describe('BuildComponent', () => {
+ let component: BuildComponent;
+ let fixture: ComponentFixture<BuildComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ BuildComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BuildComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/webapp/src/app/pages/build/build.component.ts b/webapp/src/app/pages/build/build.component.ts
new file mode 100644
index 0000000..5adb9bc
--- /dev/null
+++ b/webapp/src/app/pages/build/build.component.ts
@@ -0,0 +1,198 @@
+import { Component, ViewEncapsulation, AfterViewChecked, ElementRef, ViewChild, OnInit, Input } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms';
+import { CookieService } from 'ngx-cookie';
+
+import 'rxjs/add/operator/scan';
+import 'rxjs/add/operator/startWith';
+
+import { XDSAgentService, ICmdOutput } from '../../@core-xds/services/xdsagent.service';
+import { ProjectService, IProject } from '../../@core-xds/services/project.service';
+import { AlertService, IAlert } from '../../@core-xds/services/alert.service';
+import { SdkService } from '../../@core-xds/services/sdk.service';
+
+@Component({
+ selector: 'xds-panel-build',
+ templateUrl: './build.component.html',
+ styleUrls: ['./build.component.scss'],
+ encapsulation: ViewEncapsulation.None,
+})
+
+export class BuildComponent implements OnInit, AfterViewChecked {
+ @ViewChild('scrollOutput') private scrollContainer: ElementRef;
+
+ // FIXME workaround of https://github.com/angular/angular-cli/issues/2034
+ // should be removed with angular 5
+ // @Input() curProject: IProject;
+ @Input() curProject = <IProject>null;
+
+ public buildForm: FormGroup;
+ public subpathCtrl = new FormControl('', Validators.required);
+ public debugEnable = false;
+ public buildIsCollapsed = false;
+ public cmdOutput: string;
+ public cmdInfo: string;
+
+ private startTime: Map<string, number> = new Map<string, number>();
+
+ constructor(
+ private prjSvr: ProjectService,
+ private xdsSvr: XDSAgentService,
+ private fb: FormBuilder,
+ private alertSvr: AlertService,
+ private sdkSvr: SdkService,
+ private cookie: CookieService,
+ ) {
+ this.cmdOutput = '';
+ this.cmdInfo = ''; // TODO: to be remove (only for debug)
+ this.buildForm = fb.group({
+ subpath: this.subpathCtrl,
+ cmdClean: ['', Validators.nullValidator],
+ cmdPrebuild: ['', Validators.nullValidator],
+ cmdBuild: ['', Validators.nullValidator],
+ cmdPopulate: ['', Validators.nullValidator],
+ cmdArgs: ['', Validators.nullValidator],
+ envVars: ['', Validators.nullValidator],
+ });
+ }
+
+ ngOnInit() {
+ // Set default settings
+ // TODO save & restore values from cookies
+ this.buildForm.patchValue({
+ subpath: '',
+ cmdClean: 'rm -rf build',
+ cmdPrebuild: 'mkdir -p build && cd build && cmake ..',
+ cmdBuild: 'cd build && make',
+ cmdPopulate: 'cd build && make remote-target-populate',
+ cmdArgs: '',
+ envVars: '',
+ });
+
+ // Command output data tunneling
+ this.xdsSvr.CmdOutput$.subscribe(data => {
+ this.cmdOutput += data.stdout;
+ this.cmdOutput += data.stderr;
+ });
+
+ // Command exit
+ this.xdsSvr.CmdExit$.subscribe(exit => {
+ if (this.startTime.has(exit.cmdID)) {
+ this.cmdInfo = 'Last command duration: ' + this._computeTime(this.startTime.get(exit.cmdID));
+ this.startTime.delete(exit.cmdID);
+ }
+
+ if (exit && exit.code !== 0) {
+ this.cmdOutput += '--- Command exited with code ' + exit.code + ' ---\n\n';
+ }
+ });
+
+ this._scrollToBottom();
+
+ // only use for debug
+ this.debugEnable = (this.cookie.get('debug_build') === '1');
+ }
+
+ ngAfterViewChecked() {
+ this._scrollToBottom();
+ }
+
+ reset() {
+ this.cmdOutput = '';
+ }
+
+ clean() {
+ this._exec(
+ this.buildForm.value.cmdClean,
+ this.buildForm.value.subpath,
+ [],
+ this.buildForm.value.envVars);
+ }
+
+ preBuild() {
+ this._exec(
+ this.buildForm.value.cmdPrebuild,
+ this.buildForm.value.subpath,
+ [],
+ this.buildForm.value.envVars);
+ }
+
+ build() {
+ this._exec(
+ this.buildForm.value.cmdBuild,
+ this.buildForm.value.subpath,
+ [],
+ this.buildForm.value.envVars
+ );
+ }
+
+ populate() {
+ this._exec(
+ this.buildForm.value.cmdPopulate,
+ this.buildForm.value.subpath,
+ [], // args
+ this.buildForm.value.envVars
+ );
+ }
+
+ execCmd() {
+ this._exec(
+ this.buildForm.value.cmdArgs,
+ this.buildForm.value.subpath,
+ [],
+ this.buildForm.value.envVars
+ );
+ }
+
+ private _exec(cmd: string, dir: string, args: string[], env: string) {
+ if (!this.curProject) {
+ this.alertSvr.warning('No active project', true);
+ }
+
+ // const prjID = this.curProject.id;
+ const prjID = this.prjSvr.getCurrent().id;
+
+ this.cmdOutput += this._outputHeader();
+
+ const sdkid = this.sdkSvr.getCurrentId();
+
+ // Detect key=value in env string to build array of string
+ const envArr = [];
+ env.split(';').forEach(v => envArr.push(v.trim()));
+
+ const t0 = performance.now();
+ this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0;
+
+ this.xdsSvr.exec(prjID, dir, cmd, sdkid, args, envArr)
+ .subscribe(res => {
+ this.startTime.set(String(res.cmdID), t0);
+ },
+ err => {
+ this.cmdInfo = 'Last command duration: ' + this._computeTime(t0);
+ this.alertSvr.error('ERROR: ' + err);
+ });
+ }
+
+ private _scrollToBottom(): void {
+ try {
+ this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
+ } catch (err) { }
+ }
+
+ private _computeTime(t0: number, t1?: number): string {
+ const enlap = Math.round((t1 || performance.now()) - t0);
+ if (enlap < 1000.0) {
+ return enlap.toFixed(2) + ' ms';
+ } else {
+ return (enlap / 1000.0).toFixed(3) + ' seconds';
+ }
+ }
+
+ private _outputHeader(): string {
+ return '--- ' + new Date().toString() + ' ---\n';
+ }
+
+ private _outputFooter(): string {
+ return '\n';
+ }
+}
diff --git a/webapp/src/app/pages/build/build.module.ts b/webapp/src/app/pages/build/build.module.ts
new file mode 100644
index 0000000..ac1dfab
--- /dev/null
+++ b/webapp/src/app/pages/build/build.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { ThemeModule } from '../../@theme/theme.module';
+
+import { BuildComponent } from './build.component';
+import { ProjectSelectDropdownComponent } from './settings/project-select-dropdown.component';
+import { SdkSelectDropdownComponent } from './settings/sdk-select-dropdown.component';
+
+@NgModule({
+ imports: [
+ ThemeModule,
+ ],
+ declarations: [
+ BuildComponent,
+ ProjectSelectDropdownComponent,
+ SdkSelectDropdownComponent,
+ ],
+ entryComponents: [
+ ],
+})
+export class BuildModule { }
diff --git a/webapp/src/app/pages/build/settings/project-select-dropdown.component.ts b/webapp/src/app/pages/build/settings/project-select-dropdown.component.ts
new file mode 100644
index 0000000..da3580a
--- /dev/null
+++ b/webapp/src/app/pages/build/settings/project-select-dropdown.component.ts
@@ -0,0 +1,40 @@
+import { Component, OnInit, Input } from '@angular/core';
+
+import { IProject, ProjectService } from '../../../@core-xds/services/project.service';
+
+@Component({
+ selector: 'xds-project-select-dropdown',
+ template: `
+ <div class="form-group">
+ <label>Project</label>
+ <select class="form-control">
+ <option *ngFor="let prj of projects" (click)="select(prj)">{{prj.label}}</option>
+ </select>
+ </div>
+ `,
+})
+export class ProjectSelectDropdownComponent implements OnInit {
+
+ projects: IProject[];
+ curPrj: IProject;
+
+ constructor(private prjSvr: ProjectService) { }
+
+ ngOnInit() {
+ this.curPrj = this.prjSvr.getCurrent();
+ this.prjSvr.Projects$.subscribe((s) => {
+ if (s) {
+ this.projects = s;
+ if (this.curPrj === null || s.indexOf(this.curPrj) === -1) {
+ this.prjSvr.setCurrent(this.curPrj = s.length ? s[0] : null);
+ }
+ }
+ });
+ }
+
+ select(s) {
+ this.prjSvr.setCurrent(this.curPrj = s);
+ }
+}
+
+
diff --git a/webapp/src/app/pages/build/settings/sdk-select-dropdown.component.ts b/webapp/src/app/pages/build/settings/sdk-select-dropdown.component.ts
new file mode 100644
index 0000000..562386d
--- /dev/null
+++ b/webapp/src/app/pages/build/settings/sdk-select-dropdown.component.ts
@@ -0,0 +1,44 @@
+import { Component, OnInit, Input } from '@angular/core';
+
+import { ISdk, SdkService } from '../../../@core-xds/services/sdk.service';
+
+@Component({
+ selector: 'xds-sdk-select-dropdown',
+ template: `
+ <div class="form-group">
+ <label>SDK</label>
+ <select class="form-control">
+ <option *ngFor="let sdk of sdks" (click)="select(sdk)">{{sdk.name}}</option>
+ </select>
+ </div>
+ `,
+})
+export class SdkSelectDropdownComponent implements OnInit {
+
+ // FIXME investigate to understand why not working with sdks as input
+ // <xds-sdk-select-dropdown [sdks]="(sdks$ | async)"></xds-sdk-select-dropdown>
+ // @Input() sdks: ISdk[];
+ sdks: ISdk[];
+
+ curSdk: ISdk;
+
+ constructor(private sdkSvr: SdkService) { }
+
+ ngOnInit() {
+ this.curSdk = this.sdkSvr.getCurrent();
+ this.sdkSvr.Sdks$.subscribe((s) => {
+ if (s) {
+ this.sdks = s;
+ if (this.curSdk === null || s.indexOf(this.curSdk) === -1) {
+ this.sdkSvr.setCurrent(this.curSdk = s.length ? s[0] : null);
+ }
+ }
+ });
+ }
+
+ select(s) {
+ this.sdkSvr.setCurrent(this.curSdk = s);
+ }
+}
+
+