diff --git a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.html b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.html similarity index 87% rename from projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.html rename to projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.html index dd9bf9ea..56288167 100644 --- a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.html +++ b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.html @@ -19,8 +19,8 @@

-                $ unzip {{launcherComponent.summary.dependencyCheck.projectName}}.zip
-                $ cd {{launcherComponent.summary.dependencyCheck.projectName}}
+                $ unzip {{dependencyCheck.projectName}}.zip
+                $ cd {{dependencyCheck.projectName}}
               
diff --git a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.less b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.less rename to projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.spec.ts b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.spec.ts similarity index 56% rename from projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.spec.ts rename to projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.spec.ts index 4d7d0ad5..168eee59 100644 --- a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.spec.ts @@ -1,62 +1,52 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { By } from '@angular/platform-browser'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { ActivateBoosterCreateappNextstepComponent } from './activate-booster-createapp-nextstep.component'; -import { LauncherComponent } from '../../launcher.component'; import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { Projectile, StepState } from '../../model/projectile.model'; +import { TargetEnvironmentSelection } from '../../model/target-environment.model'; +import { ActivateBoosterNextstepComponent } from './activate-booster-nextstep.component'; export interface TypeWizardComponent { selectedSection: string; steps: LauncherStep[]; - summary: any; summaryCompleted: boolean; addStep(step: LauncherStep): void; } -let mockWizardComponent: TypeWizardComponent = { +const mockWizardComponent: TypeWizardComponent = { selectedSection: '', steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, summaryCompleted: false, addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } this.steps.push(step); } }; describe('ActivateBoosterComponent', () => { - let component: ActivateBoosterCreateappNextstepComponent; - let fixture: ComponentFixture; + let component: ActivateBoosterNextstepComponent; + let fixture: ComponentFixture; beforeEach(async(() => { + const projectile = new Projectile(); TestBed.configureTestingModule({ imports: [ CommonModule, RouterTestingModule ], declarations: [ - ActivateBoosterCreateappNextstepComponent + ActivateBoosterNextstepComponent ], providers: [ - { - provide: LauncherComponent, useValue: mockWizardComponent - } + { provide: Projectile, useValue: projectile }, + { provide: LauncherComponent, useValue: mockWizardComponent } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(ActivateBoosterCreateappNextstepComponent); + fixture = TestBed.createComponent(ActivateBoosterNextstepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.ts b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.ts new file mode 100644 index 00000000..e9942f31 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/activate-booster-nextstep/activate-booster-nextstep.component.ts @@ -0,0 +1,27 @@ +import { + Component, + Host, + ViewEncapsulation +} from '@angular/core'; + +import { LauncherComponent } from '../../launcher.component'; +import { DependencyCheck } from '../../model/dependency-check.model'; +import { Projectile } from '../../model/projectile.model'; +import { TargetEnvironmentSelection } from '../../model/target-environment.model'; + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'f8launcher-activatebooster-nextstep', + templateUrl: './activate-booster-nextstep.component.html', + styleUrls: ['./activate-booster-nextstep.component.less'] +}) +export class ActivateBoosterNextstepComponent { + + constructor(@Host() public launcherComponent: LauncherComponent, + private projectile: Projectile) { + } + + get dependencyCheck(): DependencyCheck { + return this.projectile.sharedState.state; + } +} diff --git a/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.html b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.html new file mode 100644 index 00000000..3d4f93cd --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.html @@ -0,0 +1,43 @@ +
+
+
+ +
+

+ Selected Dependencies +

+
+
+

+ You haven't selected any additional dependencies +

+

To add additional dependencies, complete this section. Required dependencies are added for you automatically based on your mission and runtime.

+ +
+
+ +
+

+ Selected Dependencies +

+
+
+
+
+
+
+ + + {{snapshot.package}} + + +
+
+
+
+
+
+
+
diff --git a/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.ts b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.ts new file mode 100644 index 00000000..af113972 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-review.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from '../../model/projectile.model'; +import { ReviewComponent } from '../../review.component'; + +@Component({ + selector: 'f8launcher-dependency-editor-review', + templateUrl: './dependency-editor-review.component.html' +}) +export class DependencyEditorReviewComponent extends ReviewComponent { + + constructor(broadcaster: Broadcaster, projectile: Projectile) { + super(broadcaster, projectile); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.html b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.html similarity index 69% rename from projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.html rename to projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.html index 7fdb090a..f14ebf3b 100644 --- a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.html +++ b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.html @@ -20,19 +20,7 @@

-
-
-
- -
-
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.less b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.less rename to projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.spec.ts similarity index 55% rename from projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.spec.ts index a134c8d2..aa82a6ec 100644 --- a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.spec.ts @@ -1,21 +1,21 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { Observable, of} from 'rxjs'; -import { DependencyEditorModule, URLProvider, DependencyEditorTokenProvider } from 'fabric8-analytics-dependency-editor'; +import { DependencyEditorModule } from 'fabric8-analytics-dependency-editor'; import { Broadcaster } from 'ngx-base'; +import { Observable, of } from 'rxjs'; +import { DemoDependencyEditorService } from '../../../../../../src/app/service/demo-dependency-editor.service'; +import { TokenProvider } from '../../../lib/service/token-provider'; import { DependencyCheck } from '../../launcher.module'; +import { Projectile, StepState } from '../../model/projectile.model'; import { DependencyCheckService } from '../../service/dependency-check.service'; import { DependencyEditorService } from '../../service/dependency-editor.service'; -import { DependencyEditorCreateappStepComponent } from './dependency-editor-step.component'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; import { HelperService } from '../../service/helper.service'; -import { TokenProvider } from '../../../lib/service/token-provider'; -import { BroadcasterTestProvider } from '../targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; -import { DemoDependencyEditorService } from '../../../../../../src/app/service/demo-dependency-editor.service'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { BroadcasterTestProvider } from '../targetenvironment-step/target-environment-step.component.spec'; +import { DependencyEditorStepComponent } from './dependency-editor-step.component'; const mockHelperService = { getBackendUrl(): string { @@ -33,50 +33,19 @@ const mockDependencyCheckService = { groupId: 'io.openshift.booster', projectName: 'App_test_1', projectVersion: '1.0.0-SNAPSHOT', - spacePath: '/myspace' + spacePath: '/myspace', + targetEnvironment: undefined }); } }; -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - describe('DependencyEditorCreateappStepComponent', () => { - let component: DependencyEditorCreateappStepComponent; - let fixture: ComponentFixture; + let component: DependencyEditorStepComponent; + let fixture: ComponentFixture; beforeEach(async(() => { + const projectile = new Projectile(); + projectile.setState('MissionRuntime', new StepState({}, [])); TestBed.configureTestingModule({ imports: [ CommonModule, @@ -85,9 +54,11 @@ describe('DependencyEditorCreateappStepComponent', () => { RouterTestingModule ], declarations: [ - DependencyEditorCreateappStepComponent + DependencyEditorStepComponent, + ButtonNextStepComponent ], providers : [ + { provide: Projectile, useValue: projectile }, TokenProvider, { provide: DependencyCheckService, useValue: mockDependencyCheckService @@ -96,16 +67,13 @@ describe('DependencyEditorCreateappStepComponent', () => { provide: DependencyEditorService, useClass: DemoDependencyEditorService }, { provide: HelperService, useValue: mockHelperService }, - { - provide: LauncherComponent, useValue: mockWizardComponent - }, { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(DependencyEditorCreateappStepComponent); + fixture = TestBed.createComponent(DependencyEditorStepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.ts b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.ts new file mode 100644 index 00000000..38f0fe80 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/dependency-editor-step/dependency-editor-step.component.ts @@ -0,0 +1,153 @@ +import { + Component, + Host, + Input, + OnDestroy, + OnInit, + Optional, + ViewEncapsulation +} from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Subscription } from 'rxjs'; + +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { DependencyCheck } from '../../model/dependency-check.model'; +import { DependencyEditor } from '../../model/dependency-editor/dependency-editor.model'; +import { Projectile, StepState } from '../../model/projectile.model'; +import { DependencyCheckService } from '../../service/dependency-check.service'; +import { DependencyEditorService } from '../../service/dependency-editor.service'; + +import * as _ from 'lodash'; +import { BoosterState } from '../../model/booster.model'; + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'f8launcher-dependencychecker-step', + templateUrl: './dependency-editor-step.component.html', + styleUrls: ['./dependency-editor-step.component.less'] +}) +export class DependencyEditorStepComponent extends LauncherStep implements OnInit, OnDestroy { + @Input() id: string; + @Input() depEditorFlag: boolean; + + public github = ''; + public gitref = ''; + public boosterInfo: any = null; + public metadataInfo: any = null; + + public blankResponse: any = null; + + dependencyEditor = new DependencyEditor(); + dependencyCheck = new DependencyCheck(); + + private subscriptions: Subscription[] = []; + constructor( + @Host() @Optional() public launcherComponent: LauncherComponent, + public broadcaster: Broadcaster, + @Optional() private depEditorService: DependencyEditorService, + private dependencyCheckService: DependencyCheckService, + private projectile: Projectile<{ dep: DependencyEditor }> + ) { + super(projectile); + this.broadcaster.on('booster-changed').subscribe(booster => { + const artifactTS: number = Date.now(); + const artifactRuntime = booster.runtime.id.replace(/[.\-_]/g, ''); + const artifactMission = booster.mission.id.replace(/[.\-_]/g, ''); + ( this.dependencyCheck).mission = booster.mission; + this.dependencyCheck.mavenArtifact = `booster-${artifactMission}-${artifactRuntime}-${artifactTS}`; + + this.boosterInfo = _.cloneDeep(booster); + if (booster.mission.id === 'blank-mission') { + this.handleBlankMissionFlow(booster.runtime.id); + } else { + booster.mission['boosters'].forEach((b: any) => { + if (booster.mission.id === b.mission.id && booster.runtime.id === b.runtime.id) { + if (b.source && b.source.git) { + this.github = b.source.git.url; + this.gitref = b.source.git.ref; + } + } + }); + } + this.boosterInfo.runtime.version = booster.runtime.version.id; + }); + } + + ngOnDestroy() { + this.subscriptions.forEach((sub) => { + sub.unsubscribe(); + }); + } + + ngOnInit() { + const state = new StepState({ dep: this.dependencyEditor }, [ + { name: 'dependencyEditor', value: 'dep' } + ]); + this.projectile.setState(this.id, state); + + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } + this.dependencyCheckService.getDependencyCheck() + .subscribe((val) => { + this.metadataInfo = val; + this.restore(); + }); + } + + // Accessors + /** + * Returns indicator that step is completed + * + * @returns {boolean} True if step is completed + */ + get completed(): boolean { + return (this.dependencyEditor !== undefined); + } + + /** + * Navigate to step + * + * @param {string} id The step ID + */ + navToStep(event: string) { + this.broadcaster.broadcast('navigate-to', event); + } + + public pickDependencies(event: any) { + if (event) { + this.dependencyEditor['dependencySnapshot'] = event; + } + } + + public pickMetadata(event: any) { + if (event) { + this.dependencyCheck.mavenArtifact = event.artifactId; + this.dependencyCheck.groupId = event.groupId; + this.dependencyCheck.projectVersion = event.version; + + // // Update the dependency editor model + this.dependencyEditor['mavenArtifact'] = event.artifactId; + this.dependencyEditor['groupId'] = event.groupId; + this.dependencyEditor['projectVersion'] = event.version; + } + } + + private handleBlankMissionFlow(runtimeId: string): void { + if (this.depEditorService && runtimeId) { + const service = this.depEditorService.getCoreDependencies(runtimeId); + if (service) { + service.subscribe((response: any) => { + if (response) { + this.blankResponse = response; + } + }); + } + } + } + + restoreModel(model: any): void { + this.dependencyEditor = model.dependencyEditor; + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-repository.validator.ts b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-repository.validator.ts similarity index 71% rename from projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-repository.validator.ts rename to projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-repository.validator.ts index d2ad2eea..a4296fd5 100644 --- a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-repository.validator.ts +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-repository.validator.ts @@ -1,9 +1,9 @@ -import { Directive, forwardRef } from '@angular/core'; -import { NG_ASYNC_VALIDATORS, Validator, AbstractControl } from '@angular/forms'; +import { Directive, forwardRef, Input } from '@angular/core'; +import { AbstractControl, NG_ASYNC_VALIDATORS, Validator } from '@angular/forms'; import { Observable } from 'rxjs'; -import { GitProviderService } from '../../service/git-provider.service'; import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators'; +import { GitProviderService } from '../../service/git-provider.service'; @Directive({ selector: '[validateRepository]', @@ -13,6 +13,8 @@ import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators'; export class GitProviderRepositoryValidatorDirective implements Validator { private pattern = /^[a-zA-Z0-9][a-zA-Z0-9-._]{1,63}$/; + @Input('validateRepository') missing: boolean; + constructor(private gitProvider: GitProviderService) { } validate(control: AbstractControl): Observable<{ [key: string]: any }> { @@ -27,7 +29,15 @@ export class GitProviderRepositoryValidatorDirective implements Validator { resolve.next(this.createError('pattern', control.value)); } else if (org) { this.gitProvider.isGitHubRepo(org, control.value).subscribe( - duplicate => resolve.next(duplicate ? this.createError('duplicate', control.value) : {}) + duplicate => { + if (duplicate && !this.missing) { + resolve.next(this.createError('duplicate', control.value)); + } else if (!duplicate && this.missing) { + resolve.next(this.createError('notExist', control.value)); + } else { + resolve.next({}); + } + } ); } }); diff --git a/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.html b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.html new file mode 100644 index 00000000..fcbc4420 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.html @@ -0,0 +1,62 @@ +
+
+
+ +
+

+ GitHub +

+
+
+

+ Incomplete +

+

To proceed with setting up this application, this section must be completed.

+ +
+
+ +
+

+ Authorized GitHub Account +

+
+
+
+
+ +
+ +
+
+
+ +
+ {{data.organization}} +
+
+
+ +
+ {{data.repository}} +
+
+
+
+ +
+
+
+
+
diff --git a/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.ts b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.ts new file mode 100644 index 00000000..c2ba75b3 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-review.component.ts @@ -0,0 +1,14 @@ +import { Component, Input } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from '../../model/projectile.model'; +import { ReviewComponent } from '../../review.component'; + +@Component({ + selector: 'f8launcher-gitprovider-review', + templateUrl: './gitprovider-review.component.html' +}) +export class GitproviderReviewComponent extends ReviewComponent { + constructor(broadcaster: Broadcaster, projectile: Projectile) { + super(broadcaster, projectile); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.html b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.html similarity index 59% rename from projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.html rename to projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.html index f226f1ac..4dffd97b 100644 --- a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.html +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.html @@ -2,7 +2,7 @@ [ngClass]="{'hidden': hidden}" #section>
-

Authorize Git Provider

+

{{title}}

@@ -31,18 +31,18 @@

Authorized Account Information

- -
@@ -50,11 +50,11 @@

Authorized Account Information

@@ -64,15 +64,23 @@

Authorized Account Information

- + + + '{{ghRepo.value}}' does not exist as {{gitHubDetails.organization}}/{{ghRepo.value}}. + Duplicate Name: '{{ghRepo.value}}' is already in use - as {{launcherComponent.summary.gitHubDetails.organization}}/{{ghRepo.value}}. + as {{gitHubDetails.organization}}/{{ghRepo.value}}. '{{ghRepo.value}}' is not a valid name, only alphanumeric characters are allowed with "-", "_" or "." @@ -86,17 +94,7 @@

Authorized Account Information

-
-
-
- -
-
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.spec.ts similarity index 57% rename from projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.spec.ts index b616ac2f..767a63e5 100644 --- a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.spec.ts @@ -5,29 +5,15 @@ import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { Observable, of } from 'rxjs'; -import { PopoverModule } from 'ngx-bootstrap'; +import { PopoverModule, TypeaheadModule } from 'ngx-bootstrap'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; - -import { DependencyCheck } from '../../launcher.module'; -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { GitproviderCreateappStepComponent } from './gitprovider-createapp-step.component'; import { GitProviderService } from '../../service/git-provider.service'; +import { GitproviderStepComponent } from './gitprovider-step.component'; import { GitHubDetails } from '../../model/github-details.model'; - -const mockDependencyCheckService = { - getDependencyCheck(): Observable { - return of({ - mavenArtifact: 'd4-345', - groupId: 'io.openshift.booster', - projectName: 'App_test_1', - projectVersion: '1.0.0-SNAPSHOT', - spacePath: '/myspace' - }); - } -}; +import { Projectile } from '../../model/projectile.model'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { GitProviderRepositoryValidatorDirective } from './gitprovider-repository.validator'; const mockGitProviderService = { connectGitHubAccount(redirectUrl: string): void { @@ -35,7 +21,7 @@ const mockGitProviderService = { '&redirect_uri=' + encodeURIComponent(redirectUrl); }, getGitHubDetails(): Observable { - const gitHubDetails = of( { + const gitHubDetails = of( { avatar: 'https://avatars3.githubusercontent.com/u/17882357?v=4', login: 'testuser', organizations: ['fabric-ui'] @@ -52,43 +38,9 @@ const mockGitProviderService = { } }; -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - describe('GitProviderStepComponent', () => { - let component: GitproviderCreateappStepComponent; - let fixture: ComponentFixture; + let component: GitproviderStepComponent; + let fixture: ComponentFixture; let element: HTMLElement; beforeEach(async(() => { @@ -97,27 +49,25 @@ describe('GitProviderStepComponent', () => { CommonModule, FormsModule, PopoverModule.forRoot(), - RouterTestingModule + RouterTestingModule, + TypeaheadModule ], declarations: [ - GitproviderCreateappStepComponent + GitproviderStepComponent, + ButtonNextStepComponent, + GitProviderRepositoryValidatorDirective ], providers: [ - { - provide: DependencyCheckService, useValue: mockDependencyCheckService - }, + Projectile, { provide: GitProviderService, useValue: mockGitProviderService - }, - { - provide: LauncherComponent, useValue: mockWizardComponent } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(GitproviderCreateappStepComponent); + fixture = TestBed.createComponent(GitproviderStepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.ts b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.ts new file mode 100644 index 00000000..0491921b --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/gitprovider-step/gitprovider-step.component.ts @@ -0,0 +1,114 @@ +import { + AfterViewInit, + Component, + ElementRef, + Host, + Input, + OnDestroy, + OnInit, + Optional, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { NgForm } from '@angular/forms'; +import { Subscription } from 'rxjs'; + +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { GitHubDetails } from '../../model/github-details.model'; +import { Projectile, StepState } from '../../model/projectile.model'; +import { GitProviderService } from '../../service/git-provider.service'; +import { broadcast } from '../../shared/telemetry.decorator'; + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'f8launcher-gitprovider-step', + templateUrl: './gitprovider-step.component.html', + styleUrls: ['./gitprovider-step.component.less'] +}) +export class GitproviderStepComponent extends LauncherStep implements AfterViewInit, OnDestroy, OnInit { + @Input() import: boolean; + @ViewChild('form') form: NgForm; + @ViewChild('versionSelect') versionSelect: ElementRef; + + private subscriptions: Subscription[] = []; + gitHubDetails: GitHubDetails = {}; + gitHubReposSubscription: Subscription; + + constructor(@Host() @Optional() public launcherComponent: LauncherComponent, + private projectile: Projectile, + private gitProviderService: GitProviderService) { + super(projectile); + } + + ngAfterViewInit() { + if (this.gitHubDetails.login) { + setTimeout(() => { + if (this.versionSelect) { + this.versionSelect.nativeElement.focus(); + } + }, 10); + } + } + + ngOnInit() { + this.gitHubDetails.repository = this.import ? '' : this.projectile.sharedState.state.projectName; + this.gitHubDetails.repositoryList = []; + const state = new StepState(this.gitHubDetails, [ + { name: 'gitRepository', value: 'repository' }, + { name: 'gitOrganization', value: 'organization' } + ]); + this.projectile.setState(this.id, state); + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } + + this.subscriptions.push(this.gitProviderService.getGitHubDetails().subscribe((val) => { + if (val !== undefined) { + Object.assign(this.gitHubDetails, val); + this.restore(); + } + })); + } + + ngOnDestroy() { + this.subscriptions.forEach((sub) => { + sub.unsubscribe(); + }); + } + + restoreModel(model: any): void { + this.gitHubDetails.organization = model.organization; + this.gitHubDetails.repository = model.repository; + } + + // Accessors + + /** + * Returns indicator that step is completed + * + * @returns {boolean} True if step is completed + */ + get completed(): boolean { + return this.form.valid; + } + + // Steps + + /** + * Authorize GitHub account + */ + connectAccount(): void { + this.gitProviderService.connectGitHubAccount(this.projectile.redirectUrl); + } + + getGitHubRepos(): void { + if (this.import) { + if (this.gitHubReposSubscription) { + this.gitHubReposSubscription.unsubscribe(); + } + this.gitHubReposSubscription = this.gitProviderService.getGitHubRepoList(this.gitHubDetails.organization) + .subscribe(list => this.gitHubDetails.repositoryList = list); + } + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.html b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.html similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.html rename to projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.html diff --git a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.spec.ts similarity index 83% rename from projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.spec.ts index 269eade9..c5ac61d8 100644 --- a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.spec.ts @@ -1,13 +1,13 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { LinkAccountsCreateappStepComponent } from './link-accounts-createapp-step.component'; -import { LauncherComponent } from '../../launcher.component'; +import { of } from 'rxjs'; import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; import { TokenService } from '../../launcher.module'; -import { of } from 'rxjs'; +import { LinkAccountsStepComponent } from './link-accounts-step.component'; export interface TypeWizardComponent { selectedSection: string; @@ -41,8 +41,8 @@ const mockTokenService: TokenService = { }; describe('ActivateBoosterComponent', () => { - let component: LinkAccountsCreateappStepComponent; - let fixture: ComponentFixture; + let component: LinkAccountsStepComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -52,7 +52,7 @@ describe('ActivateBoosterComponent', () => { RouterTestingModule ], declarations: [ - LinkAccountsCreateappStepComponent + LinkAccountsStepComponent ], providers: [ { provide: LauncherComponent, useValue: mockWizardComponent }, @@ -62,7 +62,7 @@ describe('ActivateBoosterComponent', () => { })); beforeEach(() => { - fixture = TestBed.createComponent(LinkAccountsCreateappStepComponent); + fixture = TestBed.createComponent(LinkAccountsStepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.ts b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.ts similarity index 80% rename from projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.ts rename to projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.ts index 5686caf3..b12a174a 100644 --- a/projects/ngx-launcher/src/lib/create-app/link-accounts-createapp-step/link-accounts-createapp-step.component.ts +++ b/projects/ngx-launcher/src/lib/components/link-accounts-step/link-accounts-step.component.ts @@ -4,11 +4,11 @@ import { Cluster } from '../../model/cluster.model'; import { TokenService } from '../../service/token.service'; @Component({ - selector: 'f8launcher-link-accounts-createapp-step', - templateUrl: './link-accounts-createapp-step.component.html', - styleUrls: ['./link-accounts-createapp-step.component.less'] + selector: 'f8launcher-link-accounts-step', + templateUrl: './link-accounts-step.component.html', + styleUrls: ['./link-accounts-step.component.less'] }) -export class LinkAccountsCreateappStepComponent { +export class LinkAccountsStepComponent { @Output() select = new EventEmitter(true); private _clusters: Cluster[] = []; diff --git a/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.html b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.html new file mode 100644 index 00000000..6d52fe52 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.html @@ -0,0 +1,75 @@ +
+
+
+ +
+

+ Mission +

+
+
+

+ Incomplete +

+

To proceed with setting up this application, this section must be completed.

+ +
+
+ +
+

+ Mission +

+
+
+
+ {{data?.mission?.name}} +

{{data?.mission?.description}}

+
+
+
+
+
+
+
+
+ +
+

+ Runtime +

+
+
+

+ Incomplete +

+

To proceed with setting up this application, this section must be completed.

+ +
+
+ +
+

+ Runtime +

+
+
+
+
+ {{data?.runtime?.name}} {{data?.runtime?.version?.name}} +
+
+ +
+

{{data?.runtime?.description}}

+
+
+
+
+
diff --git a/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.ts b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.ts new file mode 100644 index 00000000..4c6edaff --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-review.component.ts @@ -0,0 +1,16 @@ +import { Component, Input } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from '../../model/projectile.model'; +import { ReviewComponent } from '../../review.component'; + +@Component({ + selector: 'f8launcher-mission-runtime-review', + templateUrl: './mission-runtime-review.component.html' +}) +export class MissionRuntimeReviewComponent extends ReviewComponent { + + constructor(public _DomSanitizer: DomSanitizer, broadcaster: Broadcaster, projectile: Projectile) { + super(broadcaster, projectile); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.html b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.html similarity index 94% rename from projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.html rename to projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.html index a80d003f..fc656aa8 100644 --- a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.html +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.html @@ -2,9 +2,7 @@ [ngClass]="{'hidden': hidden}" #section>
-

- Select Mission & Runtime -

+

{{title}}

Choose a mission and runtime to create a booster, or sample application. You set up a booster to generate @@ -44,7 +42,7 @@

'community': mission.community}" *ngFor="let mission of (missions | sortArray: 'suggested': true | sortArray: 'shrinked': true)">
+ [ngClass]="{'disabled': mission.disabled, 'selected-list-item': booster.mission.id === mission.id}">
@@ -142,7 +140,7 @@

'contribute': runtime.disabled}" *ngFor="let runtime of runtimes; let i = index">
+ [ngClass]="{'disabled': runtime.disabled, 'selected-list-item': booster.runtime.id === runtime.id}">
@@ -201,7 +199,7 @@

{{runtime.name}} -
-
-
-
- -
-
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.spec.ts similarity index 80% rename from projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.spec.ts index e4b91954..24b4d439 100644 --- a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.spec.ts @@ -8,16 +8,16 @@ import { Broadcaster } from 'ngx-base'; import { BsDropdownModule, PopoverModule } from 'ngx-bootstrap'; import { SortArrayPipeModule, TruncatePipeModule } from 'patternfly-ng/pipe'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { MissionRuntimeCreateappStepComponent } from './mission-runtime-createapp-step.component'; -import { MissionRuntimeService } from '../../service/mission-runtime.service'; +import { Observable, of } from 'rxjs'; +import { Catalog } from '../../model/catalog.model'; import { Mission } from '../../model/mission.model'; +import { Projectile } from '../../model/projectile.model'; import { Runtime } from '../../model/runtime.model'; +import { MissionRuntimeService } from '../../service/mission-runtime.service'; import { createBooster, createMission, createRuntime } from '../../service/mission-runtime.service.spec'; -import { BroadcasterTestProvider } from '../targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; -import { Observable, of } from 'rxjs'; -import { Catalog } from '../../model/catalog.model'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { BroadcasterTestProvider } from '../targetenvironment-step/target-environment-step.component.spec'; +import { MissionRuntimeStepComponent } from './mission-runtime-step.component'; const longDescription = `An innovative approach to packaging and running Java EE applications, @@ -47,44 +47,9 @@ class TestMissionRuntimeService extends MissionRuntimeService { } } - -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - describe('MissionRuntimeStepComponent', () => { - let component: MissionRuntimeCreateappStepComponent; - let fixture: ComponentFixture; + let component: MissionRuntimeStepComponent; + let fixture: ComponentFixture; let element: HTMLElement; function getMissionsSection(): Element { @@ -104,7 +69,7 @@ describe('MissionRuntimeStepComponent', () => { } function selectItem(item: Element) { - const radioBtn = item.querySelector('input[type="radio"]'); + const radioBtn = item.querySelector('input[type="radio"]'); radioBtn.click(); tick(); fixture.detectChanges(); @@ -127,24 +92,22 @@ describe('MissionRuntimeStepComponent', () => { TruncatePipeModule ], declarations: [ - MissionRuntimeCreateappStepComponent + MissionRuntimeStepComponent, + ButtonNextStepComponent ], providers: [ + Projectile, { provide: MissionRuntimeService, useClass: TestMissionRuntimeService }, - { - provide: LauncherComponent, useValue: mockWizardComponent - }, { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(MissionRuntimeCreateappStepComponent); + fixture = TestBed.createComponent(MissionRuntimeStepComponent); component = fixture.componentInstance; - // component.ngOnInit(); fixture.detectChanges(); element = fixture.nativeElement; }); @@ -174,10 +137,10 @@ describe('MissionRuntimeStepComponent', () => { it('should select the mission in launcher component summary', fakeAsync(() => { fixture.detectChanges(); selectItem(getMissionItem(0)); - expect(component.launcherComponent.summary.mission).toBe(component.missions[0] as Mission); + expect(component.booster.mission.id).toBe((component.missions[0] as Mission).id); selectItem(getMissionItem(1)); - expect(component.launcherComponent.summary.mission).toBe(component.missions[1] as Mission); + expect(component.booster.mission.id).toBe((component.missions[1] as Mission).id); })); it('should have the suggested missions tag when mission.suggested field is true', () => { @@ -206,7 +169,7 @@ describe('MissionRuntimeStepComponent', () => { const missionHead = missionsSection.querySelectorAll('.list-group-item-heading'); const missions = component.missions, len = missions.length; for (let i = 0; i < len; ++ i) { - expect((missionHead[i]).innerText.trim()).toBe(missions[i].name); + expect(( missionHead[i]).innerText.trim()).toBe(missions[i].name); } }); @@ -215,7 +178,7 @@ describe('MissionRuntimeStepComponent', () => { const missionText = missionsSection.querySelectorAll('.list-group-item-text'); const missions = component.missions, len = missions.length; for (let i = 0; i < len; ++ i) { - expect((missionText[i].children[0]).innerText.trim()).toBe(missions[i].description); + expect(( missionText[i].children[0]).innerText.trim()).toBe(missions[i].description); } }); @@ -228,7 +191,8 @@ describe('MissionRuntimeStepComponent', () => { const missionText = missionsSection.querySelectorAll('.list-group-item-text'); const missions = component.missions, len = missions.length; for (let i = 0; i < len; ++ i) { - expect((missionText[i].children[0]).innerText.trim()).toBe(longDescription.substr(0, 65) + '...'); + expect(( missionText[i].children[0]).innerText.trim()) + .toBe(longDescription.substr(0, 65) + '...'); } })); @@ -239,7 +203,7 @@ describe('MissionRuntimeStepComponent', () => { const missionItem1 = getMissionItem(0); expect(missionItem1.querySelector('.description.truncated')).toBeTruthy(); expect(missionItem1.querySelector('.description.full')).toBeFalsy(); - const showMore = missionItem1.querySelector('.description-more a'); + const showMore = missionItem1.querySelector('.description-more a'); expect(showMore.innerText.trim()).toBe('More'); showMore.click(); tick(); @@ -274,10 +238,10 @@ describe('MissionRuntimeStepComponent', () => { it('should select the runtime in launcher component summary', fakeAsync(() => { fixture.detectChanges(); selectItem(getRuntimeItem(0)); - expect(component.launcherComponent.summary.runtime).toBe(component.runtimes[0] as Runtime); + expect(component.booster.runtime.id).toBe((component.runtimes[0] as Runtime).id); selectItem(getRuntimeItem(1)); - expect(component.launcherComponent.summary.runtime).toBe(component.runtimes[1] as Runtime); + expect(component.booster.runtime.id).toBe((component.runtimes[1] as Runtime).id); })); @@ -307,7 +271,7 @@ describe('MissionRuntimeStepComponent', () => { const head = runtimeSection.querySelectorAll('.list-group-item-heading'); const runtimes = component.runtimes, len = runtimes.length; for (let i = 0; i < len; ++ i) { - expect((head[i]).innerText.trim()).toBe(runtimes[i].name); + expect(( head[i]).innerText.trim()).toBe(runtimes[i].name); } }); @@ -316,7 +280,7 @@ describe('MissionRuntimeStepComponent', () => { const text = runtimeSection.querySelectorAll('.list-group-item-text'); const runtimes = component.runtimes, len = runtimes.length; for (let i = 0; i < len; ++ i) { - expect((text[i].children[0]).innerText.trim()).toBe(runtimes[i].description); + expect(( text[i].children[0]).innerText.trim()).toBe(runtimes[i].description); } }); @@ -328,7 +292,7 @@ describe('MissionRuntimeStepComponent', () => { const runtimeSection = getRuntimesSection(); const text = runtimeSection.querySelectorAll('.list-group-item-text'); for (let i = 0; i < component.runtimes.length; ++ i) { - expect((text[i].children[0]).innerText.trim()).toBe(longDescription.substr(0, 65) + '...'); + expect(( text[i].children[0]).innerText.trim()).toBe(longDescription.substr(0, 65) + '...'); } })); @@ -339,7 +303,7 @@ describe('MissionRuntimeStepComponent', () => { const item1 = getRuntimeItem(0); expect(item1.querySelector('.description.truncated')).toBeTruthy(); expect(item1.querySelector('.description.full')).toBeFalsy(); - const showMore = item1.querySelector('.description-more a'); + const showMore = item1.querySelector('.description-more a'); expect(showMore.innerText.trim()).toBe('More'); showMore.click(); tick(); @@ -403,26 +367,26 @@ describe('MissionRuntimeStepComponent', () => { it(`should select version when clicking on versions dropdown`, fakeAsync(() => { component.canChangeVersion = true; fixture.detectChanges(); - expect(component.versionId).toBeFalsy(); + expect(component.booster.runtime.version.id).toBeFalsy(); selectItem(getMissionItem(0)); - expect(component.versionId).toBeFalsy(); + expect(component.booster.runtime.version.id).toBeFalsy(); selectItem(getRuntimeItem(0)); - expect(component.versionId).toBe('community'); + expect(component.booster.runtime.version.id).toBe('community'); const item1 = getRuntimeItem(0); - const versionDropdownButton = item1.querySelector('.dropdown button.dropdown-toggle'); + const versionDropdownButton = item1.querySelector('.dropdown button.dropdown-toggle'); expect(versionDropdownButton).toBeTruthy(); versionDropdownButton.click(); tick(); fixture.detectChanges(); - const redhatVersion = item1.querySelectorAll('.dropdown ul.dropdown-menu li a')[1]; + const redhatVersion = item1.querySelectorAll('.dropdown ul.dropdown-menu li a')[1]; expect(redhatVersion).toBeTruthy(); redhatVersion.click(); tick(); fixture.detectChanges(); - expect(component.versionId).toBe('redhat'); + expect(component.booster.runtime.version.id).toBe('redhat'); // Should auto rest to compatible version selectItem(getMissionItem(1)); - expect(component.versionId).toBe('community'); + expect(component.booster.runtime.version.id).toBe('community'); })); }); diff --git a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.ts b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.ts similarity index 50% rename from projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.ts rename to projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.ts index c965cf2f..6af32c9a 100644 --- a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component.ts +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.component.ts @@ -1,63 +1,76 @@ -import { Component, Host, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; -import * as _ from 'lodash'; +import { Component, Host, Input, OnDestroy, OnInit, Optional, ViewEncapsulation } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; -import { Subscription } from 'rxjs'; +import * as _ from 'lodash'; import { Broadcaster } from 'ngx-base'; +import { Subscription } from 'rxjs'; +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { Booster, BoosterState, BoosterVersion } from '../../model/booster.model'; +import { Cluster } from '../../model/cluster.model'; import { Mission } from '../../model/mission.model'; -import { Runtime } from '../../model/runtime.model'; +import { Projectile, StepState } from '../../model/projectile.model'; import { EmptyReason, MissionRuntimeService } from '../../service/mission-runtime.service'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { Booster, BoosterVersion } from '../../model/booster.model'; -import { Selection } from '../../model/selection.model'; +import { broadcast } from '../../shared/telemetry.decorator'; import { createViewMissions, createViewRuntimes, ViewMission, ViewRuntime -} from './mission-runtime-createapp-step.model'; -import { broadcast } from '../../shared/telemetry.decorator'; +} from './mission-runtime-step.model'; @Component({ encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-missionruntime-createapp-step', - templateUrl: './mission-runtime-createapp-step.component.html', - styleUrls: ['./mission-runtime-createapp-step.component.less'] + selector: 'f8launcher-missionruntime-step', + templateUrl: './mission-runtime-step.component.html', + styleUrls: ['./mission-runtime-step.component.less'] }) -export class MissionRuntimeCreateappStepComponent extends LauncherStep implements OnInit, OnDestroy { - public missionId: string; - public runtimeId: string; - public canChangeVersion: boolean; +export class MissionRuntimeStepComponent extends LauncherStep implements OnInit, OnDestroy { + booster: BoosterState = { mission: new Mission(), runtime: { id: undefined, name: undefined, + version: {id: undefined, name: undefined} } }; - versionId: string; + @Input() + public canChangeVersion: boolean; disabledReason = EmptyReason; private _missions: ViewMission[] = []; private _runtimes: ViewRuntime[] = []; private _boosters: Booster[] = null; - private _cluster: string; + private _cluster: Cluster; private subscriptions: Subscription[] = []; - constructor(@Host() public launcherComponent: LauncherComponent, + constructor(@Host() @Optional() public launcherComponent: LauncherComponent, private missionRuntimeService: MissionRuntimeService, public _DomSanitizer: DomSanitizer, + private projectile: Projectile, private broadcaster: Broadcaster) { - super(launcherComponent); - this.canChangeVersion = this.launcherComponent.flow === 'launch'; + super(projectile); } ngOnInit() { - this.launcherComponent.addStep(this); + const state = new StepState(this.booster, + [ + {name: 'mission', value: 'mission.id', restorePath: 'missions.id'}, + {name: 'runtime', value: 'runtime.id', restorePath: 'runtimes.id'}, + {name: 'runtimeVersion', value: 'runtime.version.id', restorePath: 'runtimes.versions.id'} + ] + ); + this.projectile.setState(this.id, state); + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } this.subscriptions.push(this.missionRuntimeService.getBoosters() .subscribe(boosters => { this._boosters = boosters; this.initBoosters(); - this.restoreFromSummary(); + this.restore(this); })); - this.subscriptions.push(this.broadcaster.on('cluster').subscribe(() => this.initBoosters())); + this.subscriptions.push(this.broadcaster.on('cluster').subscribe(cluster => { + this._cluster = cluster; + this.initBoosters(); + })); } ngOnDestroy() { @@ -93,7 +106,7 @@ export class MissionRuntimeCreateappStepComponent extends LauncherStep implement } get cluster(): string { - return this._cluster; + return this._cluster ? this._cluster.type : ''; } /** @@ -102,8 +115,8 @@ export class MissionRuntimeCreateappStepComponent extends LauncherStep implement * @returns {boolean} True at least one selection has been made */ get selectionAvailable(): boolean { - return (this.launcherComponent.summary.mission !== undefined - || this.launcherComponent.summary.runtime !== undefined); + return (this.booster.mission !== undefined + || this.booster.runtime !== undefined); } /** @@ -112,26 +125,13 @@ export class MissionRuntimeCreateappStepComponent extends LauncherStep implement * @returns {boolean} True if step is completed */ get completed(): boolean { - return (this.launcherComponent.summary.mission !== undefined - && this.launcherComponent.summary.runtime !== undefined - && this.launcherComponent.summary.runtime.version !== undefined); + return (this.booster.mission.id !== undefined + && this.booster.runtime.id !== undefined + && this.booster.runtime.version.id !== undefined); } // Steps - /** - * Navigate to next step - */ - @broadcast('completeMissionRuntimeStep', { - 'launcherComponent.summary': { - mission: 'mission.name', - runtime: 'runtime.name' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('MissionRuntime'); - } - /** * Reset current selections */ @@ -143,90 +143,60 @@ export class MissionRuntimeCreateappStepComponent extends LauncherStep implement selectBooster(mission?: ViewMission, runtime?: ViewRuntime, version?: BoosterVersion): void { if (mission && !mission.disabled) { - this.missionId = mission.id; - this.launcherComponent.summary.mission = mission; + Object.assign(this.booster.mission, mission); } if (runtime && !runtime.disabled) { - this.runtimeId = runtime.id; - const newVersion = version ? version : runtime.selectedVersion; - this.versionId = newVersion.id; - this.launcherComponent.summary.runtime = runtime; - this.launcherComponent.summary.runtime.version = newVersion; - // FIXME: use a booster change event listener to do this - // set maven artifact - if (this.launcherComponent.flow === 'osio' && this.completed) { - this.launcherComponent.summary.dependencyCheck.mavenArtifact = this.createMavenArtifact(); + Object.assign(this.booster.runtime, runtime); + const newVersion = version ? version : runtime.selectedVersion; + Object.assign(this.booster.runtime.version, newVersion); + if (this.completed) { + this.broadcaster.broadcast('booster-changed', this.booster); } this.broadcaster.broadcast('runtime-changed', runtime); } + this.handleBlankMissionFlow(); this.updateBoosterViewStatus(); } handleBlankMissionFlow(): void { - if (this.launcherComponent.summary.mission && this.launcherComponent.summary.runtime && - this.launcherComponent.summary.mission.id === 'blank-mission') { - const runtimeSp: any = this.launcherComponent.summary.runtime; + if (this.booster.mission && this.booster.runtime && + this.booster.mission.id === 'blank-mission') { + const runtimeSp: any = this.booster.runtime; if (runtimeSp && runtimeSp.boosters && runtimeSp.boosters.length > 0) { const supportedMission: any = runtimeSp.boosters[0]; - this.launcherComponent.summary.mission.meta = supportedMission.mission.id; + this.booster.mission.meta = supportedMission.mission.id; } } } - // Private - - private createMavenArtifact(): string { - const artifactTS: number = Date.now(); - const artifactRuntime = this.launcherComponent.summary.runtime.id.replace(/[.\-_]/g, ''); - const artifactMission = this.launcherComponent.summary.mission.id.replace(/[.\-_]/g, ''); - return `booster-${artifactMission}-${artifactRuntime}-${artifactTS}`; - } - - private restoreFromSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (!selection) { - return; - } - const mission = this.missions.find(m => m.id === selection.missionId); - const runtime = this.runtimes.find(r => r.id === selection.runtimeId); - this.selectBooster(mission, runtime, selection.runtimeVersion); - } - - private getSelectedCluster(): string { - if (this.launcherComponent.summary.targetEnvironment === 'os') { - return _.get(this.launcherComponent.summary, 'cluster.type'); - } - return null; - } - private updateBoosterViewStatus(): void { - this._cluster = this.getSelectedCluster(); + const cluster = this.cluster; this._missions.forEach(mission => { let availableBoosters = MissionRuntimeService.getAvailableBoosters(mission.boosters, - this._cluster, mission.id); + cluster, mission.id); if (availableBoosters.empty) { mission.shrinked = true; } else { availableBoosters = MissionRuntimeService.getAvailableBoosters(mission.boosters, - this._cluster, mission.id, this.runtimeId); + cluster, mission.id, this.booster.runtime ? this.booster.runtime.id : undefined); } mission.disabled = availableBoosters.empty; mission.disabledReason = availableBoosters.emptyReason; - mission.community = this.launcherComponent.flow === 'osio' && !mission.disabled && this.versionId === 'community'; - if (this.missionId === mission.id && availableBoosters.empty) { + mission.community = this.canChangeVersion && !mission.disabled && this.booster.runtime.version.id === 'community'; + if (this.booster.mission && this.booster.mission.id === mission.id && availableBoosters.empty) { this.clearMission(); } }); this._runtimes.forEach(runtime => { const availableBoosters = MissionRuntimeService.getAvailableBoosters(runtime.boosters, - this._cluster, this.missionId, runtime.id); + cluster, this.booster.mission ? this.booster.mission.id : undefined, runtime.id); const versions = _.chain(availableBoosters.boosters) .map(b => b.version) .uniq() .value() .sort(MissionRuntimeService.compareVersions); - if (this.runtimeId === runtime.id && availableBoosters.empty) { + if (this.booster.runtime && this.booster.runtime.id === runtime.id && availableBoosters.empty) { this.clearRuntime(); } runtime.disabled = availableBoosters.empty; @@ -237,27 +207,25 @@ export class MissionRuntimeCreateappStepComponent extends LauncherStep implement } private getRuntimeSelectedVersion(runtimeId: string, versions: BoosterVersion[]): BoosterVersion { - if (this.runtimeId === runtimeId && this.versionId) { - const selectedVersion = versions.find(v => v.id === this.versionId); + if (this.booster.runtime && this.booster.runtime.id === runtimeId && this.booster.runtime.version.id) { + const selectedVersion = versions.find(v => v.id === this.booster.runtime.version.id); if (selectedVersion) { return selectedVersion; } // If the current selected version is not compatible, auto select the first available version const autoSelectedVersion = _.first(versions); - this.versionId = autoSelectedVersion.id; + this.booster.runtime.version.id = autoSelectedVersion.id; return autoSelectedVersion; } return _.first(versions); } private clearRuntime(): void { - this.runtimeId = undefined; - this.versionId = undefined; - this.launcherComponent.summary.runtime = undefined; + this.booster.runtime = { id: undefined, name: undefined, + version: {id: undefined, name: undefined} }; } private clearMission(): void { - this.missionId = undefined; - this.launcherComponent.summary.mission = undefined; + this.booster.mission = new Mission(); } } diff --git a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.model.ts b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.model.ts similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.model.ts rename to projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.model.ts index b1d42525..9a3d9822 100644 --- a/projects/ngx-launcher/src/lib/create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.model.ts +++ b/projects/ngx-launcher/src/lib/components/mission-runtime-step/mission-runtime-step.model.ts @@ -1,8 +1,8 @@ import * as _ from 'lodash'; +import { Booster, BoosterVersion } from '../../model/booster.model'; import { Mission } from '../../model/mission.model'; import { Runtime } from '../../model/runtime.model'; -import { Booster, BoosterVersion } from '../../model/booster.model'; import { EmptyReason } from '../../service/mission-runtime.service'; export class ViewMission extends Mission { diff --git a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.html b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.html similarity index 87% rename from projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.html rename to projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.html index 2fea7e45..d0a914d7 100644 --- a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.html +++ b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.html @@ -42,7 +42,7 @@

-
+
@@ -72,7 +72,7 @@

-
+
@@ -152,23 +152,10 @@

Next Steps: Update your booster using Continuous Delivery

-
+
- - - View Pipeline - - +
diff --git a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.less b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.less rename to projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.spec.ts b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.spec.ts similarity index 66% rename from projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.spec.ts rename to projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.spec.ts index 02a5cd74..8f67562a 100644 --- a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.spec.ts @@ -1,20 +1,17 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; -import { Observable, of, Subject} from 'rxjs'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { Observable, of, Subject } from 'rxjs'; -import { ProjectProgressCreateappNextstepComponent } from './project-progress-createapp-nextstep.component'; -import { ProjectProgressService } from '../../service/project-progress.service'; -import { Progress } from '../../model/progress.model'; +import { Broadcaster } from 'ngx-base'; import { LauncherComponent } from '../../launcher.component'; +import { Progress } from '../../model/progress.model'; +import { Projectile } from '../../model/projectile.model'; +import { ProjectProgressService } from '../../service/project-progress.service'; import { ProjectSummaryService } from '../../service/project-summary.service'; -import { Broadcaster } from 'ngx-base'; -import { BroadcasterTestProvider } from '../targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; - -import { CheService } from '../../service/che.service'; -import { WorkSpacesService } from '../../service/workSpaces.service'; -import { Che } from './../../model/che.model'; -import { WorkspaceLinks } from './../../model/workspace.model'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { BroadcasterTestProvider } from '../targetenvironment-step/target-environment-step.component.spec'; +import { ProjectProgressNextstepComponent } from './project-progress-nextstep.component'; const progressSubject: Subject = new Subject(); const mockProjectProgressService = { @@ -23,20 +20,6 @@ const mockProjectProgressService = { } }; -const workSpaceSubject: Subject = new Subject(); -const mockWorkSpacesService = { - createWorkSpace(): Observable { - return workSpaceSubject.asObservable(); - } -}; - -const cheSubject: Subject = new Subject(); -const mockCheService = { - createWorkSpace(): Observable { - return cheSubject.asObservable(); - } -}; - export interface TypeWizardComponent { completed(): any; } @@ -54,8 +37,8 @@ const mockProjectSummaryService = { }; describe('ProjectProgressComponent', () => { - let component: ProjectProgressCreateappNextstepComponent; - let fixture: ComponentFixture; + let component: ProjectProgressNextstepComponent; + let fixture: ComponentFixture; let launcherComponent: LauncherComponent; beforeEach(async(() => { @@ -65,9 +48,11 @@ describe('ProjectProgressComponent', () => { RouterTestingModule ], declarations: [ - ProjectProgressCreateappNextstepComponent + ProjectProgressNextstepComponent, + ButtonNextStepComponent ], providers: [ + Projectile, { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, { provide: LauncherComponent, useValue: mockWizardComponent @@ -77,19 +62,13 @@ describe('ProjectProgressComponent', () => { }, { provide: ProjectProgressService, useValue: mockProjectProgressService - }, - { - provide: CheService, useValue: mockCheService - }, - { - provide: WorkSpacesService, useValue: mockWorkSpacesService } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(ProjectProgressCreateappNextstepComponent); + fixture = TestBed.createComponent(ProjectProgressNextstepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.ts b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.ts similarity index 66% rename from projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.ts rename to projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.ts index 8f5d9104..bb5a7b13 100644 --- a/projects/ngx-launcher/src/lib/create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component.ts +++ b/projects/ngx-launcher/src/lib/components/project-progress-nextstep/project-progress-nextstep.component.ts @@ -1,23 +1,30 @@ -import { Component, Host, Input, OnChanges, OnDestroy, SimpleChanges, ViewEncapsulation, Optional } from '@angular/core'; +import { + Component, + Host, + Input, + OnChanges, + OnDestroy, + Optional, + SimpleChanges, + ViewEncapsulation +} from '@angular/core'; +import { Broadcaster } from 'ngx-base'; import { map, switchMap } from 'rxjs/operators'; +import { LauncherComponent } from '../../launcher.component'; import { Progress } from '../../model/progress.model'; +import { Projectile } from '../../model/projectile.model'; import { ProjectProgressService } from '../../service/project-progress.service'; -import { LauncherComponent } from '../../launcher.component'; import { ProjectSummaryService } from '../../service/project-summary.service'; -import { Broadcaster } from 'ngx-base'; -import { WorkSpacesService } from '../../service/workSpaces.service'; -import { CheService } from '../../service/che.service'; -import { Router } from '@angular/router'; -import { broadcast } from '../../shared/telemetry.decorator'; @Component({ encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-projectprogress-createapp-nextstep', - templateUrl: './project-progress-createapp-nextstep.component.html', - styleUrls: ['./project-progress-createapp-nextstep.component.less'] + selector: 'f8launcher-projectprogress-nextstep', + templateUrl: './project-progress-nextstep.component.html', + styleUrls: ['./project-progress-nextstep.component.less'] }) -export class ProjectProgressCreateappNextstepComponent implements OnChanges, OnDestroy { +export class ProjectProgressNextstepComponent implements OnChanges, OnDestroy { + @Input() gettingStartedInfo: boolean; @Input() statusLink: string; errorMessage: string; codeBaseCreated = false; @@ -25,14 +32,12 @@ export class ProjectProgressCreateappNextstepComponent implements OnChanges, OnD private _progress: Progress[]; private socket: WebSocket; - constructor(@Host() public launcherComponent: LauncherComponent, + constructor(@Host() @Optional() public launcherComponent: LauncherComponent, private projectProgressService: ProjectProgressService, private projectSummaryService: ProjectSummaryService, - private broadcaster: Broadcaster, - @Optional() private workSpaceService: WorkSpacesService, - @Optional() private cheService: CheService, - private router: Router) { - this.broadcaster.on('progressEvents').subscribe((events: Progress[]) => { + broadcaster: Broadcaster, + private projectile: Projectile) { + broadcaster.on('progressEvents').subscribe(events => { console.log('got the event list', events); this._progress = events; }); @@ -91,7 +96,7 @@ export class ProjectProgressCreateappNextstepComponent implements OnChanges, OnD retry() { const failedStep = this.lastCompleted; this.projectSummaryService.setup( - this.launcherComponent.summary, failedStep).subscribe(val => { + this.projectile, failedStep).subscribe(val => { this.errorMessage = null; if (!val || !val['uuid_link']) { this.errorMessage = 'Invalid response from server!'; @@ -103,28 +108,6 @@ export class ProjectProgressCreateappNextstepComponent implements OnChanges, OnD }); } - @broadcast('CreateFlowOpenInIDEButtonClicked', {}) - createWorkSpace() { - this.cheService.getState().pipe(switchMap(che => { - if (!che.clusterFull) { - return this.workSpaceService.createWorkSpace(this.codebaseId) - .pipe(map(workSpaceLinks => { - window.open(workSpaceLinks.links.open, '_blank'); - })); - } - })).subscribe(); - } - - addQuery() { - const query = '{\"application\":[\"' + this.launcherComponent.currentSelection.projectName + '\"]}'; - return { - q: query - }; - } - - @broadcast('CreateFlowViewPipelineButtonClicked', {}) - viewPipeline() {} - // Accessors get allCompleted(): boolean { diff --git a/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.html b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.html new file mode 100644 index 00000000..fb4a4673 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.html @@ -0,0 +1,23 @@ +
+ +
+
+

{{title}}

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.spec.ts similarity index 56% rename from projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.spec.ts index d4e153b3..6696e523 100644 --- a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.spec.ts @@ -1,21 +1,23 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; import { Component, - Input} from '@angular/core'; -import { CommonModule } from '@angular/common'; + Input } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { Observable, of } from 'rxjs'; -import { DependencyCheck } from '../../launcher.module'; +import { Broadcaster } from 'ngx-base'; +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { DependencyCheck } from '../../model/dependency-check.model'; +import { Projectile } from '../../model/projectile.model'; import { DependencyCheckService } from '../../service/dependency-check.service'; -import { ProjectSummaryCreateappStepComponent } from './project-summary-createapp-step.component'; import { ProjectSummaryService } from '../../service/project-summary.service'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { Broadcaster } from 'ngx-base'; -import { BroadcasterTestProvider } from '../targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { BroadcasterTestProvider } from '../targetenvironment-step/target-environment-step.component.spec'; +import { ProjectSummaryStepComponent } from './project-summary-step.component'; @Component({ selector: 'fab-toast-notification', @@ -44,48 +46,15 @@ const mockDependencyCheckService = { groupId: 'io.openshift.booster', projectName: 'App_test_1', projectVersion: '1.0.0-SNAPSHOT', - spacePath: '/myspace' + spacePath: '/myspace', + targetEnvironment: undefined }); } }; -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - describe('ProjectSummaryStepComponent', () => { - let component: ProjectSummaryCreateappStepComponent; - let fixture: ComponentFixture; + let component: ProjectSummaryStepComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -95,26 +64,25 @@ describe('ProjectSummaryStepComponent', () => { RouterTestingModule ], declarations: [ - ProjectSummaryCreateappStepComponent, - FakeToastNotificationComponent + ProjectSummaryStepComponent, + FakeToastNotificationComponent, + ButtonNextStepComponent ], providers : [ + Projectile, { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, { provide: ProjectSummaryService, useValue: mockProjectSummaryService }, { provide: DependencyCheckService, useValue: mockDependencyCheckService - }, - { - provide: LauncherComponent, useValue: mockWizardComponent } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(ProjectSummaryCreateappStepComponent); + fixture = TestBed.createComponent(ProjectSummaryStepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.ts b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.ts new file mode 100644 index 00000000..5322e72c --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/project-summary-step/project-summary-step.component.ts @@ -0,0 +1,129 @@ +import { Component, Host, Input, OnDestroy, OnInit, Optional, ViewChild, ViewEncapsulation } from '@angular/core'; +import { NgForm } from '@angular/forms'; +import { DomSanitizer } from '@angular/platform-browser'; +import { Broadcaster } from 'ngx-base'; +import { Subscription } from 'rxjs'; + +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { Projectile } from '../../model/projectile.model'; +import { DependencyCheckService } from '../../service/dependency-check.service'; +import { ProjectSummaryService } from '../../service/project-summary.service'; +import { broadcast } from '../../shared/telemetry.decorator'; + +import * as _ from 'lodash'; + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'f8launcher-projectsummary-step', + templateUrl: './project-summary-step.component.html', + styleUrls: ['./project-summary-step.component.less'] +}) +export class ProjectSummaryStepComponent extends LauncherStep implements OnDestroy, OnInit { + @Input() submitButtonText = 'Set Up Application'; + @ViewChild('form') form: NgForm; + + public setUpErrResponse: Array = []; + public setupInProgress = false; + private subscriptions: Subscription[] = []; + + constructor(@Host() @Optional() private launcherComponent: LauncherComponent, + private projectSummaryService: ProjectSummaryService, + private dependencyCheckService: DependencyCheckService, + private broadcaster: Broadcaster, + public _DomSanitizer: DomSanitizer, + private projectile: Projectile) { + super(projectile); + } + + ngOnInit() { + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } + this.subscriptions.push( + this.dependencyCheckService.getDependencyCheck() + .subscribe((val) => { + _.defaults(this.projectile.sharedState.state, val); + }) + ); + } + + ngOnDestroy() { + this.subscriptions.forEach((sub) => { + sub.unsubscribe(); + }); + } + + // Accessors + + /** + * Returns indicator that step is completed + * + * @returns {boolean} True if step is completed + */ + get completed(): boolean { + if (this.form.invalid) { + return false; + } + if (this.launcherComponent) { + for (let i = 0; i < this.launcherComponent.steps.length - 1; i++) { + const step = this.launcherComponent.steps[i]; + if (!step.hidden && !(step.optional || step.completed)) { + return false; + } + } + } + return true; + } + + /** + * Set up this application + */ + @broadcast('completeSummaryStep_Create', { + 'launcherComponent.summary': { + location: 'gitHubDetails.organization', + mission: 'mission.name', + pipeline: 'pipeline.name', + projectName: 'dependencyCheck.projectName', + repository: 'gitHubDetails.repository', + runtime: 'runtime.name', + spacePath: 'dependencyCheck.spacePath', + username: 'gitHubDetails.login' + } + }) + setup(): void { + this.setupInProgress = true; + this.subscriptions.push( + this.projectSummaryService + .setup(this.projectile) + .subscribe((val: any) => { + if (!val || !val['uuid_link']) { + this.displaySetUpErrorResponse('Invalid response from server!'); + } + + this.launcherComponent.statusLink = val['uuid_link']; + this.broadcaster.broadcast('progressEvents', val.events); + this.launcherComponent.completed(); + }, (error) => { + this.setupInProgress = false; + if (error) { + this.displaySetUpErrorResponse(error); + } + console.log('error in setup: Create', error); + }) + ); + } + + /** + * displaySetUpErrorResponse - takes a message string and returns nothing + * Displays the response received from the setup in case of error + */ + displaySetUpErrorResponse(err: any): void { + const notification = { + iconClass: 'pficon-error-circle-o', + alertClass: 'alert-danger', + text: err + }; + this.setUpErrResponse.push(notification); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/pipelines.fixture.spec.ts b/projects/ngx-launcher/src/lib/components/release-strategy-step/pipelines.fixture.spec.ts similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/pipelines.fixture.spec.ts rename to projects/ngx-launcher/src/lib/components/release-strategy-step/pipelines.fixture.spec.ts index 2e8b5f8b..75ff4951 100644 --- a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/pipelines.fixture.spec.ts +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/pipelines.fixture.spec.ts @@ -1,6 +1,6 @@ +import { Observable, of } from 'rxjs'; import { Pipeline } from '../../model/pipeline.model'; import { PipelineService } from '../../service/pipeline.service'; -import { Observable, of } from 'rxjs'; export class StubbedPipelineService implements PipelineService { getPipelines(filterByRuntime?: string): Observable { diff --git a/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.html b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.html new file mode 100644 index 00000000..37296adf --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.html @@ -0,0 +1,85 @@ +
+
+
+ +
+

+ Pipeline +

+
+
+

+ Incomplete +

+

To proceed with setting up this application, this section must be completed.

+ +
+
+ +
+

+ Pipeline +

+
+
+
+
+
+ + +
+
+
+
+ + + + {{stage.name || stage}} + + + + +
+
+
+
+ + Red Hat Suggests + + + Tech Preview + +
+
+
+
+
+
+ + {{stage.description}} +
+
+
+
+
+
+
+
+
diff --git a/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.ts b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.ts new file mode 100644 index 00000000..6876ff96 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-review.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from '../../model/projectile.model'; +import { ReviewComponent } from '../../review.component'; + +@Component({ + selector: 'f8launcher-release-strategy-review', + templateUrl: './release-strategy-review.component.html' +}) +export class ReleaseStrategyReviewComponent extends ReviewComponent { + constructor(broadcaster: Broadcaster, projectile: Projectile) { + super(broadcaster, projectile); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.html b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.html similarity index 70% rename from projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.html rename to projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.html index d1bc596e..e4dd1b55 100644 --- a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.html +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.html @@ -4,7 +4,7 @@

Select Pipeline

- Pipelines define how your application is deployed. Each pipeline has multiple stages with a varying set of capabilities. + Pipelines define how your application is deployed. Each pipeline has multiple stages with a varying set of capabilities.

@@ -21,50 +21,50 @@

-
+ [ngClass]="{'suggested': pipe.suggested || pipe.techPreview}" + *ngFor="let pipe of (pipelines | sortArray: 'suggested': true)"> +
+ [ngClass]="{'fa-angle-down': pipe.expanded, + 'fa-angle-right': pipe.expanded !== true}" + (click)="toggleExpanded(pipe)">
+ [(ngModel)]="pipeline.id" + [value]="pipe.id" + (ngModelChange)="updatePipelineSelection(pipe)">
+ (click)="updatePipelineSelection(pipe)">
- + {{stage.name || stage}} + *ngIf="i !== pipe.stages.length - 1">
-
+
+ *ngIf="pipe.suggested"> Red Hat Suggests + *ngIf="pipe.techPreview"> Tech Preview
@@ -73,11 +73,11 @@

+ (click)="updatePipelineSelection(pipe)" + *ngIf="pipe.expanded">
-
+
@@ -94,19 +94,7 @@

-
-
-
- -
-
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.less similarity index 93% rename from projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.less index 80d38bc4..3ea96931 100644 --- a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.less +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.less @@ -1,4 +1,5 @@ @import (reference) '../../../assets/stylesheets/shared/main.less'; +@import '../../../assets/stylesheets/shared/_labels.less'; .f8launcher-section-release-strategy { .control-label { diff --git a/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.spec.ts new file mode 100644 index 00000000..2a558c56 --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.spec.ts @@ -0,0 +1,93 @@ +import { async, ComponentFixture, TestBed, tick } from '@angular/core/testing'; + +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { SortArrayPipeModule } from 'patternfly-ng/pipe'; + +import { Projectile } from '../../model/projectile.model'; +import { PipelineService } from '../../service/pipeline.service'; +import { ReleaseStrategyStepComponent } from './release-strategy-step.component'; + +import { Broadcaster } from 'ngx-base'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { ViewRuntime } from '../mission-runtime-step/mission-runtime-step.model'; +import { BroadcasterTestProvider } from '../targetenvironment-step/target-environment-step.component.spec'; +import { mavenReleasePipeline, StubbedPipelineService } from './pipelines.fixture.spec'; + +describe('ReleaseStrategyStepComponent', () => { + let releaseStrategyComponent: ReleaseStrategyStepComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CommonModule, + FormsModule, + RouterTestingModule, + SortArrayPipeModule + ], + declarations: [ + ReleaseStrategyStepComponent, + ButtonNextStepComponent + ], + providers : [ + Projectile, + { provide: PipelineService, useClass: StubbedPipelineService }, + { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster } + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ReleaseStrategyStepComponent); + releaseStrategyComponent = fixture.componentInstance; + element = fixture.nativeElement; + fixture.detectChanges(); + }); + + describe('pipeline selection', () => { + + it('should change pipeline selection to node when runtime event change', () => { + // given + let pipelines = releaseStrategyComponent.pipelines; + expect(pipelines.length).toBe(0); + BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'node'} as ViewRuntime); + + // when + fixture.detectChanges(); + pipelines = releaseStrategyComponent.pipelines; + + // then + expect(pipelines.length).toBe(2); + expect(pipelines.map(value => value.id)) + .toContain('node-releaseandstage', 'node-releasestageapproveandpromote'); + }); + + it('should reset pipeline selection when runtime changes from maven to node', () => { + // given + BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'maven'} as ViewRuntime); + let pipelines = releaseStrategyComponent.pipelines; + expect(pipelines.length).toBe(3); + + // when + releaseStrategyComponent.updatePipelineSelection(mavenReleasePipeline); + BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'node'} as ViewRuntime); + fixture.detectChanges(); + pipelines = releaseStrategyComponent.pipelines; + + // then + expect(pipelines.length).toBe(2); + expect(pipelines.map(value => value.id)) + .toContain('node-releaseandstage', 'node-releasestageapproveandpromote'); + }); + + it('should not show pipelines when runtime not selected', () => { + expect(releaseStrategyComponent.pipelines.length).toBe(0); + }); + + }); + +}); diff --git a/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.ts b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.ts new file mode 100644 index 00000000..739e6d1d --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/release-strategy-step/release-strategy-step.component.ts @@ -0,0 +1,102 @@ +import { + Component, + Host, + OnDestroy, + OnInit, + Optional, + ViewEncapsulation } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Subscription } from 'rxjs'; +import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; +import { Pipeline } from '../../model/pipeline.model'; +import { Projectile, StepState } from '../../model/projectile.model'; +import { Runtime } from '../../model/runtime.model'; +import { PipelineService } from '../../service/pipeline.service'; +import { broadcast } from '../../shared/telemetry.decorator'; + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'f8launcher-releasestrategy-step', + templateUrl: './release-strategy-step.component.html', + styleUrls: ['./release-strategy-step.component.less'] +}) +export class ReleaseStrategyStepComponent extends LauncherStep implements OnInit, OnDestroy { + private _pipelines: Pipeline[] = []; + private _allPipelines: Pipeline[] = []; + public pipeline: Pipeline = new Pipeline(); + + private subscriptions: Subscription[] = []; + + constructor(@Host() @Optional() public launcherComponent: LauncherComponent, + private pipelineService: PipelineService, + private projectile: Projectile, + private broadcaster: Broadcaster) { + super(projectile); + } + + ngOnInit() { + const state = new StepState(this.pipeline, [ + { name: 'pipelineId', value: 'id' } + ]); + this.projectile.setState(this.id, state); + + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } + this.subscriptions.push(this.pipelineService.getPipelines().subscribe((result: Array) => { + this._allPipelines = result; + this.restore(); + })); + this.subscriptions.push(this.broadcaster.on('runtime-changed').subscribe(runtime => { + this.filterPipelines(runtime.pipelinePlatform); + if (this.pipeline.platform !== runtime.pipelinePlatform) { + this.updatePipelineSelection(new Pipeline()); + } + })); + } + + ngOnDestroy() { + this.subscriptions.forEach((sub) => { + sub.unsubscribe(); + }); + } + + // Accessors + + /** + * Returns a list of pipelines to display + * + * @returns {Pipeline[]} The list of pipelines + */ + get pipelines(): Pipeline[] { + return this._pipelines; + } + + /** + * Returns indicator that step is completed + * + * @returns {boolean} True if step is completed + */ + get completed(): boolean { + return this.pipeline.id !== undefined; + } + + updatePipelineSelection(pipeline: Pipeline): void { + Object.assign(this.pipeline, pipeline); + } + + restoreModel(model: any): void { + this.updatePipelineSelection(this._allPipelines.find(p => p.id === model.pipelineId)); + this.filterPipelines(this.pipeline.platform); + } + + toggleExpanded(pipeline: Pipeline) { + pipeline.expanded = !pipeline.expanded; + } + + private filterPipelines(selectedPlatform: string) { + this._pipelines = this._allPipelines + .filter(({ platform }) => selectedPlatform ? platform === selectedPlatform : true); + } +} diff --git a/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.html b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.html new file mode 100644 index 00000000..c2c18a2a --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.html @@ -0,0 +1,92 @@ +
+
+
+

+ Application Information +

+
+ +
+
+
+
+ +
+ +
+
+ + Please enter a valid Application Name. + + + Application name is already used. Please enter a new one. + +
+
+
+ +
+ +
+
+ + Please enter a valid Maven Artifact. + +
+
+
+ +
+ +
+
+ + Please enter a valid Version. + +
+
+
+ +
+ +
+
+ + Please enter a valid Group ID. + +
+
+
+ +
+ {{data.spacePath}} +
+
+
+ +
+ +
+ +
+
+ +
+ {{data.targetEnvironment === 'os' ? 'OpenShift' : '.Zip File'}} +
+
+
+
+
+
+
+
diff --git a/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.ts b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.ts new file mode 100644 index 00000000..ab3331fb --- /dev/null +++ b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-review.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from '../../model/projectile.model'; +import { ReviewComponent } from '../../review.component'; + +@Component({ + selector: 'f8launcher-target-environment-review', + templateUrl: './target-environment-review.component.html' +}) +export class TargetEnvironmentReviewComponent extends ReviewComponent implements OnInit { + constructor(broadcaster: Broadcaster, projectile: Projectile) { + super(broadcaster, projectile); + } +} diff --git a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.html b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.html similarity index 61% rename from projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.html rename to projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.html index 6b5f4bcb..985f9845 100644 --- a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.html +++ b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.html @@ -14,13 +14,12 @@

-
+ (click)="selection.dependencyCheck.targetEnvironment = targetEnv.id; updateTargetEnvSelection(targetEnv)"> +

{{targetEnv.header}}

@@ -32,11 +31,11 @@

{{targetEnv.header}}

-
- + - +
-
-
-
- -
-
+
+
diff --git a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.less b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.less similarity index 100% rename from projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.less rename to projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.less diff --git a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.spec.ts similarity index 63% rename from projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec.ts rename to projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.spec.ts index 0e6ee8f1..6bcaab23 100644 --- a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec.ts +++ b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.spec.ts @@ -2,20 +2,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Observable, of } from 'rxjs'; +import { RouterTestingModule } from '@angular/router/testing'; import { Broadcaster } from 'ngx-base'; +import { Observable, of } from 'rxjs'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { TargetEnvironmentCreateappStepComponent } from './target-environment-createapp-step.component'; +import { Catalog } from '../../model/catalog.model'; +import { Projectile } from '../../model/projectile.model'; import { TargetEnvironment } from '../../model/target-environment.model'; +import { MissionRuntimeService } from '../../service/mission-runtime.service'; import { TargetEnvironmentService } from '../../service/target-environment.service'; import { TokenService } from '../../service/token.service'; -import { LinkAccountsCreateappStepComponent } from '../link-accounts-createapp-step/link-accounts-createapp-step.component'; -import { MissionRuntimeService } from '../../service/mission-runtime.service'; -import { Catalog } from '../../model/catalog.model'; +import { ButtonNextStepComponent } from '../../shared/button-next-step.component'; +import { LinkAccountsStepComponent } from '../link-accounts-step/link-accounts-step.component'; +import { TargetEnvironmentStepComponent } from './target-environment-step.component'; export class BroadcasterTestProvider { static broadcaster = new Broadcaster(); @@ -23,7 +23,7 @@ export class BroadcasterTestProvider { const mockTargetEnvironmentService = { getTargetEnvironments(): Observable { - const targetEnvironments = of( [{ + const targetEnvironments = of([{ /* tslint:disable */ description: 'Here is a brief description of what OpenShift Online is. ' + 'There is a distinction between what OpenShift Online does compared to OpenShift.io.', @@ -43,39 +43,6 @@ const mockTargetEnvironmentService = { return targetEnvironments; } }; -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; const mockTokenService: TokenService = { clusters: of([]), @@ -88,8 +55,8 @@ class MockMissionRuntimeService extends MissionRuntimeService { } describe('TargetEnvironmentStepComponent', () => { - let component: TargetEnvironmentCreateappStepComponent; - let fixture: ComponentFixture; + let component: TargetEnvironmentStepComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -100,16 +67,15 @@ describe('TargetEnvironmentStepComponent', () => { NoopAnimationsModule ], declarations: [ - TargetEnvironmentCreateappStepComponent, - LinkAccountsCreateappStepComponent + TargetEnvironmentStepComponent, + LinkAccountsStepComponent, + ButtonNextStepComponent ], providers: [ + Projectile, { provide: TargetEnvironmentService, useValue: mockTargetEnvironmentService }, - { - provide: LauncherComponent, useValue: mockWizardComponent - }, { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, { provide: MissionRuntimeService, useClass: MockMissionRuntimeService @@ -120,7 +86,7 @@ describe('TargetEnvironmentStepComponent', () => { })); beforeEach(() => { - fixture = TestBed.createComponent(TargetEnvironmentCreateappStepComponent); + fixture = TestBed.createComponent(TargetEnvironmentStepComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.ts b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.ts similarity index 52% rename from projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.ts rename to projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.ts index 7b5bde65..ca8769db 100644 --- a/projects/ngx-launcher/src/lib/create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.ts +++ b/projects/ngx-launcher/src/lib/components/targetenvironment-step/target-environment-step.component.ts @@ -1,41 +1,43 @@ import { Component, Host, - Input, OnDestroy, OnInit, Optional, ViewEncapsulation } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; -import { Subscription } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; import { Broadcaster } from 'ngx-base'; +import { Subscription } from 'rxjs'; -import { Selection } from '../../model/selection.model'; -import { TargetEnvironment } from '../../model/target-environment.model'; -import { TargetEnvironmentService } from '../../service/target-environment.service'; -import { LauncherComponent } from '../../launcher.component'; import { LauncherStep } from '../../launcher-step'; +import { LauncherComponent } from '../../launcher.component'; import { Cluster } from '../../model/cluster.model'; +import { Projectile, StepState } from '../../model/projectile.model'; +import { TargetEnvironment, TargetEnvironmentSelection } from '../../model/target-environment.model'; +import { TargetEnvironmentService } from '../../service/target-environment.service'; import { TokenService } from '../../service/token.service'; +import * as _ from 'lodash'; + @Component({ encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-targetenvironment-createapp-step', - templateUrl: './target-environment-createapp-step.component.html', - styleUrls: ['./target-environment-createapp-step.component.less'] + selector: 'f8launcher-targetenvironment-step', + templateUrl: './target-environment-step.component.html', + styleUrls: ['./target-environment-step.component.less'] }) -export class TargetEnvironmentCreateappStepComponent extends LauncherStep implements OnDestroy, OnInit { - @Input() id: string; - +export class TargetEnvironmentStepComponent extends LauncherStep implements OnDestroy, OnInit { private subscriptions: Subscription[] = []; private _targetEnvironments: TargetEnvironment[]; private _clusters: Cluster[] = []; - constructor(@Host() public launcherComponent: LauncherComponent, + selection: TargetEnvironmentSelection = new TargetEnvironmentSelection(); + constructor(@Host() @Optional() public launcherComponent: LauncherComponent, private targetEnvironmentService: TargetEnvironmentService, @Optional() private tokenService: TokenService, private broadcaster: Broadcaster, + private projectile: Projectile, public _DomSanitizer: DomSanitizer) { - super(launcherComponent); + super(projectile); } ngOnDestroy() { @@ -45,13 +47,23 @@ export class TargetEnvironmentCreateappStepComponent extends LauncherStep implem } ngOnInit() { - this.launcherComponent.addStep(this); - setTimeout(() => { - this.restoreSummary(); - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError + this.selection.dependencyCheck = this.projectile.sharedState.state; + _.merge(this.projectile.sharedState.state, { + mavenArtifact: 'booster', + groupId: 'io.openshift.booster', + projectVersion: '1.0.0-SNAPSHOT' + }); + const state = new StepState(this.selection, [ + { name: 'clusterId', value: 'cluster.id', restorePath: 'clusters.id' } + ]); + this.projectile.setState(this.id, state); + if (this.launcherComponent) { + this.launcherComponent.addStep(this); + } if (this.tokenService) { this.subscriptions.push(this.tokenService.clusters.subscribe(clusters => { this._clusters = clusters.sort(this.clusterSortFn); + this.restore(this); })); } this.subscriptions.push(this.targetEnvironmentService.getTargetEnvironments().subscribe((val) => { @@ -59,6 +71,19 @@ export class TargetEnvironmentCreateappStepComponent extends LauncherStep implem this._targetEnvironments = val; } })); + this.subscriptions.push(this.broadcaster.on('booster-changed').subscribe(booster => { + if (booster.runtime.id !== 'nodejs') { + const artifactRuntime = booster.runtime.id.replace(/[.\-_]/g, ''); + const artifactMission = booster.mission.id.replace(/[.\-_]/g, ''); + this.selection.dependencyCheck.mavenArtifact = `booster-${artifactMission}-${artifactRuntime}`; + this.selection.dependencyCheck.groupId = 'io.openshift.booster'; + this.selection.dependencyCheck.projectVersion = '1.0.0-SNAPSHOT'; + } else { + this.selection.dependencyCheck.mavenArtifact = undefined; + this.selection.dependencyCheck.groupId = undefined; + this.selection.dependencyCheck.projectVersion = '0.0.1'; + } + })); } // Accessors @@ -69,8 +94,8 @@ export class TargetEnvironmentCreateappStepComponent extends LauncherStep implem * @returns {boolean} True if step is completed */ get completed(): boolean { - return this.launcherComponent.summary.targetEnvironment - && (this.launcherComponent.summary.targetEnvironment === 'zip' || !!this.launcherComponent.summary.cluster); + return this.selection.dependencyCheck.targetEnvironment + && (this.selection.dependencyCheck.targetEnvironment === 'zip' || !!this.selection.cluster); } /** @@ -93,12 +118,8 @@ export class TargetEnvironmentCreateappStepComponent extends LauncherStep implem // Steps - navToNextStep(): void { - this.launcherComponent.navToNextStep('TargetEnvironment'); - } - selectCluster(cluster?: Cluster): void { - this.launcherComponent.summary.cluster = cluster; + this.selection.cluster = cluster; this.broadcaster.broadcast('cluster', cluster); } @@ -108,17 +129,6 @@ export class TargetEnvironmentCreateappStepComponent extends LauncherStep implem } } - // Private - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection !== undefined) { - this.launcherComponent.summary.targetEnvironment = selection.targetEnvironment; - this.launcherComponent.summary.cluster = selection.cluster; - } - } - private clusterSortFn(a: Cluster, b: Cluster): number { if (a.connected) { return -1; diff --git a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.ts b/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.ts deleted file mode 100644 index 0dada0db..00000000 --- a/projects/ngx-launcher/src/lib/create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - Component, - Host, - ViewEncapsulation -} from '@angular/core'; - -import { LauncherComponent } from '../../launcher.component'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-activatebooster-createapp-nextstep', - templateUrl: './activate-booster-createapp-nextstep.component.html', - styleUrls: ['./activate-booster-createapp-nextstep.component.less'] -}) -export class ActivateBoosterCreateappNextstepComponent { - - constructor(@Host() public launcherComponent: LauncherComponent) { - } -} diff --git a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.ts b/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.ts deleted file mode 100644 index a3051682..00000000 --- a/projects/ngx-launcher/src/lib/create-app/dependency-editor-step/dependency-editor-step.component.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { - Component, - DoCheck, - Host, - Input, - KeyValueDiffers, - OnDestroy, - OnInit, - Optional, - ViewEncapsulation -} from '@angular/core'; -import { Subscription } from 'rxjs'; -import { Broadcaster } from 'ngx-base'; - -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { DependencyEditorService } from '../../service/dependency-editor.service'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { DependencyEditor } from '../../model/dependency-editor/dependency-editor.model'; -import { broadcast } from '../../shared/telemetry.decorator'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-dependencychecker-createapp-step', - templateUrl: './dependency-editor-step.component.html', - styleUrls: ['./dependency-editor-step.component.less'] -}) -export class DependencyEditorCreateappStepComponent extends LauncherStep implements OnInit, OnDestroy, DoCheck { - @Input() id: string; - @Input() depEditorFlag: boolean; - - public github = ''; - public gitref = ''; - public boosterInfo: any = null; - public metadataInfo: any = null; - - public blankResponse: any = null; - - private cacheInfo: any = {}; - private changes: any = {}; - - private subscriptions: Subscription[] = []; - constructor( - @Host() public launcherComponent: LauncherComponent, - public broadcaster: Broadcaster, - @Optional() private depEditorService: DependencyEditorService, - private dependencyCheckService: DependencyCheckService, - private keyValueDiffers: KeyValueDiffers - ) { - super(launcherComponent); - if (this.launcherComponent.summary) { - this.launcherComponent.summary['dependencyEditor'] = new DependencyEditor(); - } - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - - ngOnInit() { - this.changes = this.keyValueDiffers.find(this.launcherComponent.summary).create(); - this.launcherComponent.addStep(this); - this.dependencyCheckService.getDependencyCheck() - .subscribe((val) => { - this.metadataInfo = val; - }); - } - - ngDoCheck() { - const updates: any = this.changes.diff(this.launcherComponent.summary); - if (updates) { - updates.forEachChangedItem((r: any) => { - this.listenForChanges(r); - }); - updates.forEachAddedItem((r: any) => { - this.listenForChanges(r); - }); - updates.forEachRemovedItem((r: any) => { - this.listenForChanges(r); - }); - } - } - - // Accessors - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - return (this.launcherComponent.summary.dependencyEditor !== undefined); - } - - /** - * Returns target environments to display - * - * @returns {TargetEnvironment[]} The target environments to display - */ - // Steps - @broadcast('completeDependencyEditorStep', { - 'launcherComponent.summary.dependencyEditor': { - dependencySnapshot: 'dependencySnapshot' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('SelectDependencies'); - } - - /** - * Navigate to step - * - * @param {string} id The step ID - */ - navToStep(event: string) { - this.launcherComponent.stepIndicator.navToStep(event); - } - - public pickDependencies(event: any) { - if (event) { - this.launcherComponent.summary.dependencyEditor['dependencySnapshot'] = event; - } - } - - public pickMetadata(event: any) { - if (event) { - this.launcherComponent.summary.dependencyCheck.mavenArtifact = event.artifactId; - this.launcherComponent.summary.dependencyCheck.groupId = event.groupId; - this.launcherComponent.summary.dependencyCheck.projectVersion = event.version; - - // Update the dependency editor model - this.launcherComponent.summary.dependencyEditor['mavenArtifact'] = event.artifactId; - this.launcherComponent.summary.dependencyEditor['groupId'] = event.groupId; - this.launcherComponent.summary.dependencyEditor['projectVersion'] = event.version; - } - } - - private listenForChanges(change: any): void { - let flag = false; - const current = change.currentValue; - if (!current) { - return; - } - if (change && change.key === 'runtime') { - if ( - !this.cacheInfo || - ( - this.cacheInfo && this.cacheInfo.id !== current.id - ) - ) { - // Changes in any of them: name or version.id or version.name - this.cacheInfo['runtime'] = { - name: current.name, - id: current.id, - missions: current.missions, - version: current.version ? current.version.id : null - }; - flag = true; - } - } else if (change && change.key === 'mission') { - this.cacheInfo['mission'] = { - id: current.id - }; - - // If runtime is selected first, version of runtime will be null. This updates that. - const missionsArrFromRuntime: Array = this.cacheInfo['runtime'] && this.cacheInfo['runtime']['missions']; - if (missionsArrFromRuntime && missionsArrFromRuntime.length) { - const filteredMission = - missionsArrFromRuntime.filter((mission) => mission.id === this.cacheInfo['mission']['id'])[0]; - this.cacheInfo['runtime']['version'] = - filteredMission && filteredMission.versions && filteredMission.versions[0] - && filteredMission.versions[0].id || null; - } - flag = true; - } - - if (flag) { - if (this.cacheInfo['mission'] && this.cacheInfo['runtime']) { - // this.cacheInfo = JSON.parse(this.cacheInfo); - this.boosterInfo = this.cacheInfo; - if (this.cacheInfo['mission'].id === 'blank-mission') { - this.handleBlankMissionFlow(this.cacheInfo['runtime'].id); - return; - } - this.blankResponse = null; - const mission: string = this.cacheInfo['mission'].id; - const runtime: string = this.cacheInfo['runtime'].id; - this.boosterInfo = this.cacheInfo; - const missionObj = this.launcherComponent.summary.mission; - if (missionObj && missionObj['boosters'] && missionObj['boosters'].length) { - missionObj['boosters'].forEach((booster: any) => { - if (mission === booster.mission.id && runtime === booster.runtime.id) { - this.github = booster.source.git.url; - this.gitref = booster.source.git.ref; - } - }); - } - } - } - } - - private handleBlankMissionFlow(runtimeId: string): void { - if (this.depEditorService && runtimeId) { - const service = this.depEditorService.getCoreDependencies(runtimeId); - if (service) { - service.subscribe((response: any) => { - if (response) { - this.blankResponse = response; - } - }); - } - } - } - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection !== undefined) { - this.launcherComponent.summary.targetEnvironment = selection.targetEnvironment; - this.launcherComponent.summary.dependencyCheck = selection.dependencyCheck; - this.launcherComponent.summary.dependencyEditor = selection.dependencyEditor; - } - } -} diff --git a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.ts b/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.ts deleted file mode 100644 index db990c7a..00000000 --- a/projects/ngx-launcher/src/lib/create-app/gitprovider-createapp-step/gitprovider-createapp-step.component.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - AfterViewInit, - Component, - ElementRef, - Host, - OnDestroy, - OnInit, - ViewChild, - ViewEncapsulation -} from '@angular/core'; -import { NgForm } from '@angular/forms'; -import { Subscription } from 'rxjs'; - -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { GitProviderService } from '../../service/git-provider.service'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { broadcast } from '../../shared/telemetry.decorator'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-gitprovider-createapp-step', - templateUrl: './gitprovider-createapp-step.component.html', - styleUrls: ['./gitprovider-createapp-step.component.less'] -}) -export class GitproviderCreateappStepComponent extends LauncherStep implements AfterViewInit, OnDestroy, OnInit { - @ViewChild('form') form: NgForm; - @ViewChild('versionSelect') versionSelect: ElementRef; - - private subscriptions: Subscription[] = []; - - constructor(@Host() public launcherComponent: LauncherComponent, - private dependencyCheckService: DependencyCheckService, - private gitProviderService: GitProviderService) { - super(launcherComponent); - } - - ngAfterViewInit() { - if (this.launcherComponent.summary.gitHubDetails.login) { - setTimeout(() => { - if (this.versionSelect) { - this.versionSelect.nativeElement.focus(); - } - }, 10); - } - } - - ngOnInit() { - this.launcherComponent.addStep(this); - - this.subscriptions.push(this.gitProviderService.getGitHubDetails().subscribe((val) => { - if (val !== undefined) { - this.launcherComponent.summary.gitHubDetails = val; - this.getGitHubRepos(); - } - })); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - // Accessors - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - return this.form.valid; - } - - // Steps - - /** - * Navigate to next step - */ - @broadcast('completeGitProviderStep_Create', { - 'launcherComponent.summary.gitHubDetails': { - location: 'organization', - repository: 'repository', - username: 'login' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('GitProvider'); - const summary = this.launcherComponent.summary; - } - - /** - * Authorize GitHub account - * - * @param {MouseEvent} $event - */ - connectAccount($event: MouseEvent): void { - const url = window.location.href + this.getParams(this.launcherComponent.currentSelection); - this.gitProviderService.connectGitHubAccount(url); - } - - /** - * get all repos List for the selected organization - */ - getGitHubRepos(): void { - if (this.launcherComponent && this.launcherComponent.summary && - this.launcherComponent.summary.gitHubDetails) { - this.launcherComponent.summary.gitHubDetails.repository = - this.launcherComponent.summary.dependencyCheck ? - this.launcherComponent.summary.dependencyCheck.projectName : ''; - } - } - - // Private - - private getParams(selection: Selection) { - if (selection === undefined) { - return ''; - } - return '?selection=' + encodeURI(JSON.stringify(selection)); - } -} diff --git a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.html b/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.html deleted file mode 100644 index be95a74d..00000000 --- a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.html +++ /dev/null @@ -1,399 +0,0 @@ -
- -
-
-

Confirm Application Summary & Setup

-
-
-
-
-
-
-
-
- -
-

- Mission -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Mission -

-
-
-
- {{summary?.mission?.name}} -

{{summary?.mission?.description}}

-
-
-
-
-
-
-
-
- -
-

- Runtime -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Runtime -

-
-
-
-
- {{summary?.runtime?.name}} {{summary?.runtime?.version?.name}} -
-
- -
-

{{summary?.runtime?.description}}

-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-

- Selected Dependencies -

-
-
-

- You haven't selected any additional dependencies -

-

To add additional dependencies, complete this section. Required dependencies are added for you automatically based on your mission and runtime.

- -
-
- -
-

- Selected Dependencies -

-
-
-
-
-
-
- - - {{snapshot.package}} - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-

- Pipeline -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Pipeline -

-
-
-
-
-
- - -
-
-
-
- - - - {{stage.name || stage}} - - - - -
-
-
-
- - Red Hat Suggests - - - Tech Preview - -
-
-
-
-
-
- - {{stage.description}} -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

- Application Information -

-
-
-
-
-
- -
- -
-
- - Please enter a valid Application Name. - - - Application name is already used. Please enter a new one. - -
-
-
- -
- -
-
- - Please enter a valid Maven Artifact. - -
-
-
- -
- -
-
- - Please enter a valid Version. - -
-
-
- -
- -
-
- - Please enter a valid Group ID. - -
-
-
- -
- {{summary?.dependencyCheck?.spacePath}} -
-
-
- -
- -
- -
-
- -
- {{summary?.targetEnvironment === 'os' ? 'OpenShift' : '.Zip File'}} -
-
-
-
-
-
-
-
-
-
-
- -
-

- GitHub -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Authorized GitHub Account -

-
-
-
-
- -
- -
-
-
- -
- {{summary?.gitHubDetails?.organization}} -
-
-
- -
- {{summary?.gitHubDetails?.repository}} -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
diff --git a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.ts b/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.ts deleted file mode 100644 index 3a5b6b1b..00000000 --- a/projects/ngx-launcher/src/lib/create-app/project-summary-createapp-step/project-summary-createapp-step.component.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { - Component, - Host, - Input, - OnDestroy, - OnInit, - ViewEncapsulation, - ViewChild -} from '@angular/core'; -import { Subscription } from 'rxjs'; -import { DomSanitizer } from '@angular/platform-browser'; - -import * as _ from 'lodash'; - -import { Pipeline } from '../../model/pipeline.model'; -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { ProjectSummaryService } from '../../service/project-summary.service'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { DependencyCheck } from '../../model/dependency-check.model'; -import { Summary } from '../../model/summary.model'; -import { broadcast } from '../../shared/telemetry.decorator'; -import { Broadcaster } from 'ngx-base'; -import { NgForm } from '@angular/forms'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-projectsummary-createapp-step', - templateUrl: './project-summary-createapp-step.component.html', - styleUrls: ['./project-summary-createapp-step.component.less'] -}) -export class ProjectSummaryCreateappStepComponent extends LauncherStep implements OnDestroy, OnInit { - @ViewChild('form') form: NgForm; - @Input() id: string; - @Input() depEditorFlag: boolean; - - public setUpErrResponse: Array = []; - public setupInProgress = false; - private subscriptions: Subscription[] = []; - - constructor(@Host() public launcherComponent: LauncherComponent, - private dependencyCheckService: DependencyCheckService, - private projectSummaryService: ProjectSummaryService, - private broadcaster: Broadcaster, - public _DomSanitizer: DomSanitizer) { - super(launcherComponent); - } - - ngOnInit() { - this.launcherComponent.addStep(this); - this.restoreSummary(); - - this.subscriptions.push( - this.dependencyCheckService.getDependencyCheck() - .subscribe((val) => { - // Don't override user's application name - _.defaults(this.launcherComponent.summary.dependencyCheck, val); - })); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - // Accessors - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - if (this.form.invalid) { - return false; - } - for (let i = 0; i < this.launcherComponent.steps.length - 1; i++) { - const step = this.launcherComponent.steps[i]; - if (!step.hidden && !(step.optional || step.completed)) { - return false; - } - } - return true; - } - - // Steps - - /** - * Navigate to next step - */ - navToNextStep(): void { - this.launcherComponent.navToNextStep('ProjectSummary'); - } - - /** - * Navigate to step - * - * @param {string} id The step ID - */ - navToStep(id: string) { - this.launcherComponent.stepIndicator.navToStep(id); - } - - /** - * Set up this application - */ - @broadcast('completeSummaryStep_Create', { - 'launcherComponent.summary': { - location: 'gitHubDetails.organization', - mission: 'mission.name', - pipeline: 'pipeline.name', - projectName: 'dependencyCheck.projectName', - repository: 'gitHubDetails.repository', - runtime: 'runtime.name', - spacePath: 'dependencyCheck.spacePath', - username: 'gitHubDetails.login' - } - }) - setup(): void { - this.setupInProgress = true; - this.subscriptions.push( - this.projectSummaryService - .setup(this.launcherComponent.summary) - .subscribe((val: any) => { - if (!val || !val['uuid_link']) { - this.displaySetUpErrorResponse('Invalid response from server!'); - } - - this.launcherComponent.statusLink = val['uuid_link']; - this.broadcaster.broadcast('progressEvents', val.events); - this.navToNextStep(); - }, (error) => { - this.setupInProgress = false; - if (error) { - this.displaySetUpErrorResponse(error); - } - console.log('error in setup: Create', error); - }) - ); - } - - get dependencyCheck(): DependencyCheck { - return this.launcherComponent.summary.dependencyCheck; - } - - get summary(): Summary { - return this.launcherComponent.summary; - } - - // Private - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection === undefined) { - return; - } - this.launcherComponent.summary.dependencyCheck.groupId = selection.groupId; - this.launcherComponent.summary.dependencyCheck.projectName = selection.projectName; - this.launcherComponent.summary.dependencyCheck.projectVersion = selection.projectVersion; - this.launcherComponent.summary.dependencyCheck.spacePath = selection.spacePath; - } - - toggleExpanded(pipeline: Pipeline) { - pipeline.expanded = (pipeline.expanded !== undefined) ? !pipeline.expanded : true; - } - - /** - * displaySetUpErrorResponse - takes a message string and returns nothing - * Displays the response received from the setup in case of error - */ - displaySetUpErrorResponse(err: any): void { - const notification = { - iconClass: 'pficon-error-circle-o', - alertClass: 'alert-danger', - text: err - }; - this.setUpErrResponse.push(notification); - } -} diff --git a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.spec.ts deleted file mode 100644 index d860f9c3..00000000 --- a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.spec.ts +++ /dev/null @@ -1,149 +0,0 @@ -import {async, ComponentFixture, TestBed, tick} from '@angular/core/testing'; - -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { SortArrayPipeModule } from 'patternfly-ng/pipe'; - -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { PipelineService } from '../../service/pipeline.service'; -import { ReleaseStrategyCreateappStepComponent } from './release-strategy-createapp-step.component'; -import { Selection } from '../../model/selection.model'; -import { Summary } from '../../model/summary.model'; - -import { BroadcasterTestProvider } from '../targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; -import { Broadcaster } from 'ngx-base'; -import { mavenReleasePipeline, StubbedPipelineService } from './pipelines.fixture.spec'; -import { ViewRuntime } from '../mission-runtime-createapp-step/mission-runtime-createapp-step.model'; - -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - currentSelection(): any; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - get currentSelection(): any { - const summaryVar = new Summary(); - return { - groupId: (summaryVar.dependencyCheck !== undefined) ? summaryVar.dependencyCheck.groupId : undefined, - missionId: (summaryVar.mission !== undefined) ? summaryVar.mission.id : undefined, - pipelineId: (summaryVar.pipeline !== undefined) ? this.summaryVar.pipeline.id : undefined, - projectName: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.projectName : undefined, - projectVersion: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.projectVersion : undefined, - runtimeId: (summaryVar.runtime !== undefined) ? summaryVar.runtime.id : undefined, - runtimeVersion: (summaryVar.runtime !== undefined) ? summaryVar.runtime.version : undefined, - platform: (summaryVar.runtime !== undefined) ? summaryVar.runtime.pipelinePlatform : 'maven', - spacePath: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.spacePath : undefined, - targetEnvironment: summaryVar.targetEnvironment, - dependencyCheck: (summaryVar.dependencyCheck !== undefined) ? summaryVar.dependencyCheck : undefined, - dependencyEditor: (summaryVar.dependencyEditor !== undefined) ? summaryVar.dependencyEditor : undefined - } as Selection; - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - -describe('ReleaseStrategyStepComponent', () => { - let releaseStrategyComponent: ReleaseStrategyCreateappStepComponent; - let fixture: ComponentFixture; - let element: HTMLElement; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CommonModule, - FormsModule, - RouterTestingModule, - SortArrayPipeModule - ], - declarations: [ - ReleaseStrategyCreateappStepComponent - ], - providers : [ - { provide: PipelineService, useClass: StubbedPipelineService }, - { provide: LauncherComponent, useValue: mockWizardComponent }, - { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ReleaseStrategyCreateappStepComponent); - releaseStrategyComponent = fixture.componentInstance; - element = fixture.nativeElement; - fixture.detectChanges(); - }); - - describe('pipeline selection', () => { - - it('should change pipeline selection to node when runtime event change', () => { - // given - let pipelines = releaseStrategyComponent.pipelines; - expect(pipelines.length).toBe(0); - BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'node'} as ViewRuntime); - - // when - fixture.detectChanges(); - pipelines = releaseStrategyComponent.pipelines; - - // then - expect(pipelines.length).toBe(2); - expect(pipelines.map(value => value.id)) - .toContain( 'node-releaseandstage', 'node-releasestageapproveandpromote' ); - }); - - it('should reset pipeline selection when runtime changes from maven to node', () => { - // given - BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'maven'} as ViewRuntime); - let pipelines = releaseStrategyComponent.pipelines; - expect(pipelines.length).toBe(3); - - // when - releaseStrategyComponent.updatePipelineSelection(mavenReleasePipeline); - BroadcasterTestProvider.broadcaster.broadcast('runtime-changed', {pipelinePlatform: 'node'} as ViewRuntime); - fixture.detectChanges(); - pipelines = releaseStrategyComponent.pipelines; - - // then - expect(pipelines.length).toBe(2); - expect(pipelines.map(value => value.id)) - .toContain( 'node-releaseandstage', 'node-releasestageapproveandpromote' ); - }); - - it('should not show pipelines when runtime not selected', () => { - expect(releaseStrategyComponent.pipelines.length).toBe(0); - }); - - }); - -}); diff --git a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.ts b/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.ts deleted file mode 100644 index ff9a2888..00000000 --- a/projects/ngx-launcher/src/lib/create-app/release-strategy-createapp-step/release-strategy-createapp-step.component.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { - Component, - Host, - Input, - OnDestroy, - OnInit, - ViewEncapsulation } from '@angular/core'; - -import { PipelineService } from '../../service/pipeline.service'; -import { Pipeline } from '../../model/pipeline.model'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { broadcast } from '../../shared/telemetry.decorator'; -import { Broadcaster} from 'ngx-base'; -import { Runtime } from '../../model/runtime.model'; -import { Subscription } from 'rxjs'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-releasestrategy-createapp-step', - templateUrl: './release-strategy-createapp-step.component.html', - styleUrls: ['./release-strategy-createapp-step.component.less'] -}) -export class ReleaseStrategyCreateappStepComponent extends LauncherStep implements OnInit, OnDestroy { - @Input() id: string; - - private _pipelines: Pipeline[] = []; - private _allPipelines: Pipeline[] = []; - private _pipelineId: string; - - private subscriptions: Subscription[] = []; - - constructor(@Host() public launcherComponent: LauncherComponent, - private pipelineService: PipelineService, - private broadcaster: Broadcaster) { - super(launcherComponent); - } - - ngOnInit() { - this.launcherComponent.addStep(this); - this.subscriptions.push(this.pipelineService.getPipelines().subscribe((result: Array) => { - this._allPipelines = result; - this.restoreSummary(); - })); - this.subscriptions.push(this.broadcaster.on('runtime-changed').subscribe((runtime: Runtime) => { - this._pipelines = this._allPipelines.filter(({platform}) => platform === runtime.pipelinePlatform); - if ((this.launcherComponent.summary.pipeline || {} as Pipeline).platform !== runtime.pipelinePlatform) { - this.updatePipelineSelection(undefined); - } - })); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - // Accessors - - /** - * Returns a list of pipelines to display - * - * @returns {Pipeline[]} The list of pipelines - */ - get pipelines(): Pipeline[] { - return this._pipelines; - } - - /** - * Returns pipeline ID - * - * @returns {string} The pipeline ID - */ - get pipelineId(): string { - return this._pipelineId; - } - - /** - * Set the pipeline ID - * - * @param {string} val The pipeline ID - */ - set pipelineId(val: string) { - this._pipelineId = val; - } - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - return (this.launcherComponent.summary.pipeline !== undefined); - } - - // Steps - @broadcast('completePipelineStep_Create', { - 'launcherComponent.summary.pipeline': { - pipeline: 'name' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('ReleaseStrategy'); - } - - updatePipelineSelection(pipeline: Pipeline): void { - this.launcherComponent.summary.pipeline = pipeline; - } - - // Private - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection === undefined) { - return; - } - this.pipelineId = selection.pipelineId; - for (let i = 0; i < this.pipelines.length; i++) { - if (this.pipelineId === this.pipelines[i].id) { - this.launcherComponent.summary.pipeline = this.pipelines[i]; - } - } - } - - toggleExpanded(pipeline: Pipeline) { - pipeline.expanded = (pipeline.expanded !== undefined) ? !pipeline.expanded : true; - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.html b/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.html deleted file mode 100644 index 42f3c69f..00000000 --- a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.html +++ /dev/null @@ -1,100 +0,0 @@ -
-
-
-

Authorize Git Provider

-
-
-
-
-
-
-

GitHub

-
-

- OpenShift uses GitHub access to perform the following actions on your behalf: -

-
    -
  • - Create new repositories in your GitHub namespace -
  • -
  • - Build and deploy your code on each push to a repository’s master branch -
  • -
-
-
-
-
-

Authorized Account Information

-
-
- -
- - - - None - - -
-
-
- -
- -
-
-
- -
- - - '{{ghRepo.value}}' does not exist as {{launcherComponent.summary.gitHubDetails.organization}}/{{ghRepo.value}}. - -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
diff --git a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.less b/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.less deleted file mode 100644 index 33389383..00000000 --- a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.less +++ /dev/null @@ -1,50 +0,0 @@ -@import (reference) '../../../assets/stylesheets/shared/main.less'; - -.f8launcher { - &-provider-card { - background-color: @color-pf-white; - min-height: 300px; - padding-left: 0; - padding-right: 0; - box-shadow: .5px 1px 0 rgba(0, 0, 0, .3), 0 -.5px 1px 0 rgba(0, 0, 0, .3); - &-icon { - min-height: 300px; - border-right: 1px solid; - margin: 10px 0; - border-right-color: @color-pf-black-400; - h3 { - font-weight: 600; - } - i { - padding: 25px; - } - } - &-info { - text-align: left; - } - &-information { - padding-left: 15px; - padding-right: 15px; - min-height: 300px; - margin: 10px 0; - h3 { - font-weight: 600; - } - &-authorize { - .f8launcher { - &-username { - vertical-align: bottom; - font-style: italic; - font-size: 1.4em; - } - &-authorize-account { - float: right; - } - } - } - } - } - ul.dropdown-menu { - max-height: 400px; - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.spec.ts deleted file mode 100644 index 7c88af99..00000000 --- a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.spec.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { async, fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Observable, of } from 'rxjs'; -import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; - -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { DependencyCheck } from '../../launcher.module'; -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { GitproviderImportappStepComponent } from './gitprovider-importapp-step.component'; -import { GitProviderService } from '../../service/git-provider.service'; -import { GitHubDetails } from '../../model/github-details.model'; -import { ExistingRepositoryValidatorDirective } from '../gitprovider-importapp-step/repository.validator'; - -const mockDependencyCheckService = { - getDependencyCheck(): Observable { - return of({ - mavenArtifact: 'd4-345', - groupId: 'io.openshift.booster', - projectName: 'App_test_1', - projectVersion: '1.0.0-SNAPSHOT', - spacePath: '/myspace' - }); - } -}; - -const mockGitProviderService = { - connectGitHubAccount(redirectUrl: string): void { - const url = 'https://github.com/login/oauth/authorize?client_id=' + this.clientId + - '&redirect_uri=' + encodeURIComponent(redirectUrl); - }, - getGitHubDetails(): Observable { - const gitHubDetails = of( { - avatar: 'https://avatars3.githubusercontent.com/u/17882357?v=4', - login: 'testuser', - organizations: ['fabric-ui'] - }); - return gitHubDetails; - }, - isGitHubRepo(org: string, repoName: string): Observable { - const gitHubRepo = of(true); - return gitHubRepo; - }, - getGitHubRepoList(org: string): Observable { - const repoList = ['fabric-ui', 'fabric-uxd']; - return of(repoList); - } -}; - -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - -describe('Import GitProviderStepComponent', () => { - let component: GitproviderImportappStepComponent; - let fixture: ComponentFixture; - let element: HTMLElement; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CommonModule, - FormsModule, - TypeaheadModule.forRoot(), - RouterTestingModule - ], - declarations: [ - GitproviderImportappStepComponent, - ExistingRepositoryValidatorDirective - ], - providers: [ - { - provide: DependencyCheckService, useValue: mockDependencyCheckService - }, - { - provide: GitProviderService, useValue: mockGitProviderService - }, - { - provide: LauncherComponent, useValue: mockWizardComponent - } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(GitproviderImportappStepComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should render users git avatar', () => { - fixture.detectChanges(); - element = fixture.nativeElement; - const userGitAvatar = element.querySelector('.f8launcher-provider-card-information-authorize>img'); - expect(userGitAvatar.getAttribute('src')).toContain('https://avatars3.githubusercontent.com/u/17882357?v=4'); - }); - - it('should show users login', () => { - fixture.detectChanges(); - element = fixture.nativeElement; - const userGitLogin = element. - querySelector('.f8launcher-provider-card-information-authorize .f8launcher-username-login'); - expect(userGitLogin.innerHTML).toContain('testuser'); - }); - - it('should disable logIn button', () => { - fixture.detectChanges(); - element = fixture.nativeElement; - const userGitLoginBtn = element. - querySelector('.f8launcher-provider-card-information-authorize .f8launcher-authorize-account'); - expect(userGitLoginBtn.hasAttribute('disabled')); - }); - -}); diff --git a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.ts b/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.ts deleted file mode 100644 index b27f0a4f..00000000 --- a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/gitprovider-importapp-step.component.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { - AfterViewInit, - Component, - ElementRef, - Host, - OnDestroy, - OnInit, - ViewChild, - ViewEncapsulation -} from '@angular/core'; -import { NgForm } from '@angular/forms'; -import { Subscription } from 'rxjs'; - -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { GitProviderService } from '../../service/git-provider.service'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { broadcast } from '../../shared/telemetry.decorator'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-gitprovider-importapp-step', - templateUrl: './gitprovider-importapp-step.component.html', - styleUrls: ['./gitprovider-importapp-step.component.less'] -}) -export class GitproviderImportappStepComponent extends LauncherStep implements AfterViewInit, OnDestroy, OnInit { - @ViewChild('form') form: NgForm; - @ViewChild('versionSelect') versionSelect: ElementRef; - - private subscriptions: Subscription[] = []; - private gitHubReposSubscription: Subscription; - - constructor(@Host() public launcherComponent: LauncherComponent, - private dependencyCheckService: DependencyCheckService, - private gitProviderService: GitProviderService) { - super(launcherComponent); - } - - ngAfterViewInit() { - if (this.launcherComponent.summary.gitHubDetails.login) { - setTimeout(() => { - if (this.versionSelect) { - this.versionSelect.nativeElement.focus(); - } - }, 10); - } - } - - ngOnInit() { - this.launcherComponent.addStep(this); - - this.subscriptions.push(this.gitProviderService.getGitHubDetails().subscribe((val) => { - if (val !== undefined) { - this.launcherComponent.summary.gitHubDetails = val; - this.getGitHubRepos(); - } - })); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - if (this.gitHubReposSubscription !== undefined) { - this.gitHubReposSubscription.unsubscribe(); - } - } - - // Accessors - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - return this.form.valid; - } - - // Steps - - /** - * Navigate to next step - */ - @broadcast('completeGitProviderStep_Import', { - 'launcherComponent.summary.gitHubDetails': { - location: 'organization', - repository: 'repository', - username: 'login' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('GitProvider'); - } - - /** - * Authorize GitHub account - * - * @param {MouseEvent} $event - */ - connectAccount($event: MouseEvent): void { - let url = window.location.href + this.getParams(this.launcherComponent.currentSelection); - this.gitProviderService.connectGitHubAccount(url); - } - - /** - * Ensure repo name is available for the selected organization - */ - getGitHubRepos(): void { - let org = ''; - if (this.launcherComponent && this.launcherComponent.summary && - this.launcherComponent.summary.gitHubDetails) { - org = this.launcherComponent.summary.gitHubDetails.organization; - this.launcherComponent.summary.gitHubDetails.repository = ''; - this.launcherComponent.summary.gitHubDetails.repositoryList = []; - } - - if (this.gitHubReposSubscription !== undefined) { - this.gitHubReposSubscription.unsubscribe(); - } - this.gitHubReposSubscription = this.gitProviderService.getGitHubRepoList(org).subscribe((val) => { - if (val !== undefined && this.launcherComponent && this.launcherComponent.summary && - this.launcherComponent.summary.gitHubDetails) { - this.launcherComponent.summary.gitHubDetails.repositoryList = val; - } - }); - } - - // Private - - private getParams(selection: Selection) { - if (selection === undefined) { - return ''; - } - return '?selection=' + JSON.stringify(selection); - } - - /** - * Helper to retrieve request parameters - * - * @param name The request parameter to retrieve - * @returns {any} The request parameter value or null - */ - private getRequestParam(name: string): string { - const search = (window.location.search !== undefined && window.location.search.length > 0) - ? window.location.search : window.location.href; - const param = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(search); - if (param !== null) { - return decodeURIComponent(param[1]); - } - return null; - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/repository.validator.ts b/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/repository.validator.ts deleted file mode 100644 index 44e16299..00000000 --- a/projects/ngx-launcher/src/lib/import-app/gitprovider-importapp-step/repository.validator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ValidatorFn, AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms'; -import { Directive, Input } from '@angular/core'; - -@Directive({ - selector: '[existingRepository]', - providers: [{provide: NG_VALIDATORS, useExisting: ExistingRepositoryValidatorDirective, multi: true}] -}) -export class ExistingRepositoryValidatorDirective implements Validator { - @Input('existingRepository') repoList: string[]; - - validate(control: AbstractControl): {[key: string]: any} | null { - return this.repoList ? repositoryValidator(this.repoList)(control) : null; - } -} - -export function repositoryValidator(repoList: string[]): ValidatorFn { - return (control: AbstractControl): { [key: string]: any } | null => { - const existingRepo = repoList.indexOf(control.value) !== -1; - return existingRepo ? null : { 'notExist': { value: control.value } }; - }; -} diff --git a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.html b/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.html deleted file mode 100644 index 11d17049..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.html +++ /dev/null @@ -1,93 +0,0 @@ -
-
-
-

Next Steps: Import Application

-

- Once setup is complete, you’re ready to start working. Your new application contains a sample codebase to get you started, as well as a README.adoc file that contains instructions on how to run and interact with your application. -

-
-
-
-
-
-
- - Set Up Incomplete There were some problems. -
-
-
-
- What happened ? -
-
- {{ errorMessage }} -
-
-
-
-
-
-
-
-

- - Working Through Setup - - - Your Application is Ready - - - Set Up Incomplete - -

-
-
-
-
-
-
-
-
- - -
-
-
- {{item?.message}} -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - View Pipeline - -
-
-
-
diff --git a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.less b/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.less deleted file mode 100644 index cc80c3e6..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.less +++ /dev/null @@ -1,39 +0,0 @@ -@import (reference) '../../../assets/stylesheets/shared/main.less'; - -.f8launcher { - &-section-project-progress { - .f8launcher-grid(); - grid-column-gap: 15px; - grid-auto-rows: auto; - grid-template-areas: 'main'; - grid-template-columns: 1fr; - width: 100vw; - .card-pf-title-project-progress { - /* stylelint-disable-next-line declaration-no-important */ - display: block !important; - text-align: center; - } - .pfng-list-content { - display: flex; - flex: 1; - } - .item-in-progress { - opacity: .4; - } - .icon-clear { - &:before { - color: transparent; - } - } - .alert-box { - .alert-danger { - margin-bottom: 0; - } - .alert-detail { - border-color: #c00; - border-top: none; - color: #363636; - } - } - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.spec.ts b/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.spec.ts deleted file mode 100644 index 91379821..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { CommonModule } from '@angular/common'; -import { Observable, Subject } from 'rxjs'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { ProjectProgressImportappNextstepComponent } from './project-progress-importapp-nextstep.component'; -import { ProjectProgressService } from '../../service/project-progress.service'; - -import { Progress } from '../../model/progress.model'; -import { LauncherComponent } from '../../launcher.component'; -import { Broadcaster } from 'ngx-base'; -import { BroadcasterTestProvider } from - '../../create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; - -const progressSubject: Subject = new Subject(); -const mockProjectProgressService = { - getProgress(): Observable { - return progressSubject.asObservable(); - } -}; - -export interface TypeWizardComponent { - completed(): any; -} - -const mockWizardComponent: TypeWizardComponent = { - completed() { - // this.onComplete.emit(); - } -}; - -describe('Import ProjectProgressComponent', () => { - let component: ProjectProgressImportappNextstepComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CommonModule, - RouterTestingModule - ], - declarations: [ - ProjectProgressImportappNextstepComponent - ], - providers: [ - { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, - { - provide: LauncherComponent, useValue: mockWizardComponent - }, - { - provide: ProjectProgressService, useValue: mockProjectProgressService - } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ProjectProgressImportappNextstepComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should test ngOnChanges', () => { - const input: any = { - statusLink: { - currentValue: 'currentValue' - } - }; - spyOn(component, 'ngOnChanges'); - component.ngOnChanges(input); - expect(component.ngOnChanges).toHaveBeenCalledWith(input); - }); - - it('View pipeline button should not be visible if nextbuttons value is false', () => { - fixture.detectChanges(); - const viewPipelineButton: HTMLElement = fixture.nativeElement.querySelector('.f8launcher-viewpipeline'); - expect(viewPipelineButton).toBeFalsy(); - }); -}); diff --git a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.ts b/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.ts deleted file mode 100644 index 59a65a50..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Component, Host, Input, OnChanges, OnDestroy, SimpleChanges, ViewEncapsulation } from '@angular/core'; - -import { Progress } from '../../model/progress.model'; -import { ProjectProgressService } from '../../service/project-progress.service'; -import { LauncherComponent } from '../../launcher.component'; -import { Broadcaster } from 'ngx-base'; -import { Router } from '@angular/router'; -import { broadcast } from '../../shared/telemetry.decorator'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-projectprogress-importapp-nextstep', - templateUrl: './project-progress-importapp-nextstep.component.html', - styleUrls: ['./project-progress-importapp-nextstep.component.less'] -}) -export class ProjectProgressImportappNextstepComponent implements OnChanges, OnDestroy { - @Input() statusLink: string; - errorMessage = ''; - private _progress: Progress[]; - private socket: WebSocket; - - constructor(@Host() public launcherComponent: LauncherComponent, - private broadcaster: Broadcaster, - private projectProgressService: ProjectProgressService, - private router: Router) { - this.broadcaster.on('progressEvents').subscribe((events: Progress[]) => this._progress = events); - } - - ngOnChanges(changes: SimpleChanges) { - const statusLink = changes['statusLink']['currentValue']; - if (statusLink) { - this.socket = this.projectProgressService.getProgress(statusLink); - this.socket.onmessage = this.handleMessage; - this.socket.onerror = (error: ErrorEvent) => { - console.log('error in fetching messages in progress Component: Import', error); - }; - this.socket.onclose = () => { - console.log('socket call closed in progress component in Import'); - }; - } - } - - private handleMessage = (event: MessageEvent) => { - const message = JSON.parse(event.data); - console.log('data from ws', message); - const data = message.data || {}; - if (data && data.error) { - console.log(message.data.error); - this.errorMessage = data.error; - for (const step of this._progress.filter((s) => !s.completed)) { - step.error = true; - } - this.socket.close(); - return; - } - const status = this._progress.find((p) => p.name === message.statusMessage); - if (status) { - status.completed = true; - if (data.location != null) { - status.hyperText = data.location; - } - } - } - - ngOnDestroy() { - this.closeConnections(); - } - - addQuery() { - const query = '{\"application\":[\"' + this.launcherComponent.currentSelection.projectName + '\"]}'; - return { - q: query - }; - } - - @broadcast('ImportFlowViewPipelineButtonClicked', {}) - viewPipeline() {} - - // Accessors - - get allCompleted(): boolean { - if (this._progress === undefined) { - return false; - } - let result = true; - for (let i = 0; i < this._progress.length; i++) { - if (this._progress[i].completed !== true) { - result = false; - break; - } - } - return result; - } - - get isError(): boolean { - return !!this.errorMessage; - } - - get progress(): Progress[] { - return this._progress; - } - - private closeConnections() { - if (this.socket) { - this.socket.close(); - } - } - - private reset() { - this.errorMessage = ''; - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.html b/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.html deleted file mode 100644 index 5321f5ae..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.html +++ /dev/null @@ -1,272 +0,0 @@ -
- -
-
-

Confirm Application Summary & Setup

-
-
-
-
-
-
-
-
- -
-

- Pipeline -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Pipeline -

-
-
-
-
-
- - -
-
-
-
- - - - {{stage.name || stage}} - - - - -
-
-
-
- - Red Hat Suggests - - - Tech Preview - -
-
-
-
-
-
- - {{stage.description}} -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

- Application Information -

-
-
-
-
-
- -
- -
-
- - Please enter a valid Application Name. - - - Application name is already used. Please enter a new one. - -
-
-
- -
- -
-
- - Please enter a valid Maven Artifact. - -
-
-
- -
- -
-
- - Please enter a valid Version. - -
-
-
- -
- -
-
- - Please enter a valid Group ID. - -
-
-
- -
- {{summary?.dependencyCheck?.spacePath}} -
-
-
- -
- -
- -
-
- -
- {{summary?.targetEnvironment === 'os' ? 'OpenShift' : '.Zip File'}} -
-
-
-
-
-
-
-
-
-
-
- -
-

- GitHub -

-
-
-

- Incomplete -

-

To proceed with setting up this application, this section must be completed.

- -
-
- -
-

- Authorized GitHub Account -

-
-
-
-
-
- - -
-
- -
- {{summary?.gitHubDetails?.organization}} -
-
-
- -
- {{summary?.gitHubDetails?.repository}} -
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
diff --git a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.less b/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.less deleted file mode 100644 index bb9f0a90..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.less +++ /dev/null @@ -1,91 +0,0 @@ -@import (reference) '../../../assets/stylesheets/shared/main.less'; - -.f8launcher { - &-section-project-summary { - .control-label { - text-align: left; - } - .f8launcher-pipeline-stages { - margin-left: 0; - } - .list-group-item { - padding-top: 0; - padding-bottom: 0; - .group { - flex: 1; - flex-direction: column; - - &.with-tag { - padding-bottom: 20px; - position: relative; - } - - } - } - .list-group-item-header { - cursor: default; - margin-left: 16px; - margin-right: -16px; - margin-top: -11px; - padding: 0; - } - } - &-project-summary-data { - &-form-group { - label { - text-align: left; - } - } - &-field { - padding-top: 3px; - &:hover { - &:after { - color: @color-pf-black-900; - } - } - input { - &::-webkit-input-placeholder, - &::-moz-placeholder, - &::-ms-input-placeholder, - &::-moz-placeholder { - color: @color-pf-black-900; - } - } - &-account { - margin-top: -6px; - padding-bottom: 6px; - display: inline-flex; - align-items: baseline; - &-username { - padding-left: 10px; - } - } - &_input { - width: 85%; - margin-left: 0; - font-size: @font-size-base; - color: @color-pf-black-900; - } - } - &-unavailable { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: 75%; - height: 30%; - margin: auto !important; /* stylelint-disable-line declaration-no-important */ - text-align: center; - .fa-ban { - font-size: 60px; - } - } - } - &-continue { - .btn-xlarge { - font-size: 18px !important; /* stylelint-disable-line declaration-no-important */ - padding: 4px 16px; - } - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.spec.ts deleted file mode 100644 index fb95ff0b..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.spec.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { - Component, - Input -} from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Observable, of } from 'rxjs'; - -import { DependencyCheck } from '../../launcher.module'; -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { ProjectSummaryImportappStepComponent } from './project-summary-importapp-step.component'; -import { ProjectSummaryService } from '../../service/project-summary.service'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { Summary } from '../../launcher.module'; -import { Broadcaster } from 'ngx-base'; -import { BroadcasterTestProvider } from '../../create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; - -@Component({ - selector: 'fab-toast-notification', - template: '' -}) -export class FakeToastNotificationComponent { - @Input() notifications: any; -} - -const mockProjectSummaryService = { - setup(summary: Summary): Observable { - return of(true); - }, - verify(summary: Summary): Observable { - return of(true); - }, - getCurrentContext(): Observable { - return of({}); - } -}; - -const mockDependencyCheckService = { - getDependencyCheck(): Observable { - return of({ - mavenArtifact: 'd4-345', - groupId: 'io.openshift.booster', - projectName: 'App_test_1', - projectVersion: '1.0.0-SNAPSHOT', - spacePath: '/myspace' - }); - } -}; - -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - -describe('Import ProjectSummaryStepComponent', () => { - let component: ProjectSummaryImportappStepComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CommonModule, - FormsModule, - RouterTestingModule - ], - declarations: [ - ProjectSummaryImportappStepComponent, - FakeToastNotificationComponent - ], - providers : [ - { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, - { - provide: ProjectSummaryService, useValue: mockProjectSummaryService - }, - { - provide: DependencyCheckService, useValue: mockDependencyCheckService - }, - { - provide: LauncherComponent, useValue: mockWizardComponent - } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ProjectSummaryImportappStepComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.ts b/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.ts deleted file mode 100644 index 5a27f2b2..00000000 --- a/projects/ngx-launcher/src/lib/import-app/project-summary-importapp-step/project-summary-importapp-step.component.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { - Component, - Host, - Input, - OnDestroy, - OnInit, - ViewEncapsulation, - ViewChild -} from '@angular/core'; -import { Subscription } from 'rxjs'; -import { DomSanitizer } from '@angular/platform-browser'; -import { defaults } from 'lodash'; - -import { Pipeline } from '../../model/pipeline.model'; -import { DependencyCheckService } from '../../service/dependency-check.service'; -import { ProjectSummaryService } from '../../service/project-summary.service'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { DependencyCheck } from '../../model/dependency-check.model'; -import { Summary } from '../../model/summary.model'; -import { broadcast } from '../../shared/telemetry.decorator'; -import { Broadcaster } from 'ngx-base'; -import { NgForm } from '@angular/forms'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-projectsummary-importapp-step', - templateUrl: './project-summary-importapp-step.component.html', - styleUrls: ['./project-summary-importapp-step.component.less'] -}) -export class ProjectSummaryImportappStepComponent extends LauncherStep implements OnDestroy, OnInit { - @ViewChild('form') form: NgForm; - @Input() id: string; - - public setUpErrResponse: Array = []; - public setupInProgress = false; - private subscriptions: Subscription[] = []; - private spaceId: string; - private spaceName: string; - - constructor(@Host() public launcherComponent: LauncherComponent, - private dependencyCheckService: DependencyCheckService, - private projectSummaryService: ProjectSummaryService, - private broadcaster: Broadcaster, - public _DomSanitizer: DomSanitizer) { - super(launcherComponent); - } - - ngOnInit() { - this.launcherComponent.addStep(this); - this.restoreSummary(); - - this.subscriptions.push( - this.dependencyCheckService.getDependencyCheck() - .subscribe((val) => { - // Don't override user's application name - defaults(this.launcherComponent.summary.dependencyCheck, val); - }) - ); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - // Accessors - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - if (this.form.invalid) { - return false; - } - for (let i = 0; i < this.launcherComponent.steps.length - 1; i++) { - const step = this.launcherComponent.steps[i]; - if (!step.hidden && !(step.optional || step.completed)) { - return false; - } - } - return true; - } - - // Steps - - /** - * Navigate to next step - */ - navToNextStep(): void { - this.launcherComponent.navToNextStep('ProjectSummary'); - } - - /** - * Navigate to step - * - * @param {string} id The step ID - */ - navToStep(id: string) { - this.launcherComponent.stepIndicator.navToStep(id); - } - - /** - * Set up this application - */ - @broadcast('completeSummaryStep_Import', { - 'launcherComponent.summary': { - location: 'gitHubDetails.organization', - pipeline: 'pipeline.name', - projectName: 'dependencyCheck.projectName', - repository: 'gitHubDetails.repository', - spacePath: 'dependencyCheck.spacePath', - username: 'gitHubDetails.login' - } - }) - setup(): void { - this.setupInProgress = true; - this.subscriptions.push( - this.projectSummaryService - .setup(this.launcherComponent.summary) - .subscribe((val: any) => { - if (!val || !val['uuid_link']) { - this.displaySetUpErrorResponse('Invalid response from server!'); - } - - this.launcherComponent.statusLink = val['uuid_link']; - this.broadcaster.broadcast('progressEvents', val.events); - this.navToNextStep(); - }, (error) => { - this.setupInProgress = false; - if (error) { - this.displaySetUpErrorResponse(error); - } - console.log('error in setup: Import', error); - }) - ); - } - - get dependencyCheck(): DependencyCheck { - return this.launcherComponent.summary.dependencyCheck; - } - - get summary(): Summary { - return this.launcherComponent.summary; - } - - // Private - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection === undefined) { - return; - } - this.launcherComponent.summary.dependencyCheck.groupId = selection.groupId; - this.launcherComponent.summary.dependencyCheck.projectName = selection.projectName; - this.launcherComponent.summary.dependencyCheck.projectVersion = selection.projectVersion; - this.launcherComponent.summary.dependencyCheck.spacePath = selection.spacePath; - } - - toggleExpanded(pipeline: Pipeline) { - pipeline.expanded = (pipeline.expanded !== undefined) ? !pipeline.expanded : true; - } - - /** - * displaySetUpErrorResponse - takes a message string and returns nothing - * Displays the response received from the setup in case of error - */ - private displaySetUpErrorResponse(err: any): void { - const notification = { - iconClass: 'pficon-error-circle-o', - alertClass: 'alert-danger', - text: err - }; - this.setUpErrResponse.push(notification); - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.html b/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.html deleted file mode 100644 index 3030742f..00000000 --- a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.html +++ /dev/null @@ -1,109 +0,0 @@ -
-
-
-

Select Pipeline

-

- Pipelines define how your application is deployed. Each pipeline has multiple stages with a varying set of capabilities. -

-
-
-
-
-
-
-
-
-

- Pipeline -

-
-
-
-
-
-
- - -
-
- -
-
-
-
- - - - {{stage.name || stage}} - - - - -
-
-
-
- - Red Hat Suggests - - - Tech Preview - -
-
-
-
-
-
- - {{stage.description}} -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
diff --git a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.less b/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.less deleted file mode 100644 index fe81ca42..00000000 --- a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.less +++ /dev/null @@ -1,58 +0,0 @@ -@import (reference) '../../../assets/stylesheets/shared/main.less'; -@import '../../../assets/stylesheets/shared/_labels.less'; - -.f8launcher { - &-section-release-strategy { - .control-label { - text-align: left; - } - .card-pf { - &-heading { - display: inline-flex; - margin-bottom: 0; - border: none; - .card-pf-title { - margin-bottom: 0; - } - } - &-body { - margin-top: -31px; - } - } - &-toolbar { - .toolbar-pf-actions { - display: inline-flex; - justify-content: flex-end; - } - } - .list-group-item { - .group { - flex: 1; - flex-direction: column; - - &.with-tag { - padding-bottom: 20px; - position: relative; - } - - } - } - .list-group-item-header { - cursor: default; - margin-left: 16px; - margin-right: -16px; - margin-top: -1px; - padding: 0; - } - .list-group-item-container, - .list-view-pf-main-info { - cursor: pointer; - } - .list-view-pf-expand { - margin-right: 7px; - .fa-angle-down { - padding-right: 6px; - } - } - } -} diff --git a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.spec.ts b/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.spec.ts deleted file mode 100644 index 2fa0b710..00000000 --- a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.spec.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { - Component, - EventEmitter, - Input, - Output -} from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Observable, of } from 'rxjs'; - -import { FilterEvent } from 'patternfly-ng/filter'; -import { SortArrayPipeModule } from 'patternfly-ng/pipe'; -import { SortEvent } from 'patternfly-ng/sort'; - -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { PipelineService } from '../../service/pipeline.service'; -import { Pipeline, Stage } from '../../model/pipeline.model'; -import { ReleaseStrategyImportappStepComponent } from './release-strategy-importapp-step.component'; -import { Selection } from '../../model/selection.model'; -import { Summary } from '../../model/summary.model'; - -// @ts-ignore -@Component({ - selector: 'f8launcher-pfng-toolbar', - template: '' -}) -export class FakePfngToolbarComponent { - @Input() config: any; - @Output() onFilterChange = new EventEmitter(); - @Output() onSortChange = new EventEmitter(); -} - -const mockPipelineService = { - getPipelines(): Observable { - const stage = { - description: 'description...', - name: 'Stage Name' - } as Stage; - const pipelines = of([{ - 'id': 'Pipeline1', - 'suggested': true, - 'name': 'Release', - 'description': 'A slightly longer description of this pipeline\'s capabilities and usage.', - 'stages': [stage, stage, stage], - 'platform': 'maven' - } as Pipeline]); - return pipelines; - } -}; - -export interface TypeWizardComponent { - selectedSection: string; - steps: LauncherStep[]; - summary: any; - summaryCompleted: boolean; - addStep(step: LauncherStep): void; - currentSelection(): any; - onInViewportChange($event: any, id: string): any; -} - -const mockWizardComponent: TypeWizardComponent = { - selectedSection: '', - steps: [], - summary: { - dependencyCheck: {}, - gitHubDetails: {} - }, - summaryCompleted: false, - addStep(step: LauncherStep) { - for (let i = 0; i < this.steps.length; i++) { - if (step.id === this.steps[i].id) { - return; - } - } - this.steps.push(step); - }, - get currentSelection(): any { - const summaryVar = new Summary(); - return { - groupId: (summaryVar.dependencyCheck !== undefined) ? summaryVar.dependencyCheck.groupId : undefined, - missionId: (summaryVar.mission !== undefined) ? summaryVar.mission.id : undefined, - pipelineId: (summaryVar.pipeline !== undefined) ? this.summaryVar.pipeline.id : undefined, - projectName: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.projectName : undefined, - projectVersion: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.projectVersion : undefined, - runtimeId: (summaryVar.runtime !== undefined) ? summaryVar.runtime.id : undefined, - runtimeVersion: (summaryVar.runtime !== undefined) ? summaryVar.runtime.version : undefined, - platform: (summaryVar.runtime !== undefined) ? summaryVar.runtime.pipelinePlatform : 'maven', - spacePath: (summaryVar.dependencyCheck !== undefined) - ? summaryVar.dependencyCheck.spacePath : undefined, - targetEnvironment: summaryVar.targetEnvironment, - dependencyCheck: (summaryVar.dependencyCheck !== undefined) ? summaryVar.dependencyCheck : undefined, - dependencyEditor: (summaryVar.dependencyEditor !== undefined) ? summaryVar.dependencyEditor : undefined - } as Selection; - }, - onInViewportChange($event: any, id: string) { - if ($event) { - setTimeout(() => { - this.selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - } -}; - -describe('Import ReleaseStrategyStepComponent', () => { - let component: ReleaseStrategyImportappStepComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CommonModule, - FormsModule, - RouterTestingModule, - SortArrayPipeModule - ], - declarations: [ - ReleaseStrategyImportappStepComponent, - FakePfngToolbarComponent - ], - providers : [ - { - provide: PipelineService, useValue: mockPipelineService - }, - { - provide: LauncherComponent, useValue: mockWizardComponent - } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ReleaseStrategyImportappStepComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.ts b/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.ts deleted file mode 100644 index 0fb10e2f..00000000 --- a/projects/ngx-launcher/src/lib/import-app/release-strategy-importapp-step/release-strategy-importapp-step.component.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { - Component, - Host, - Input, - OnDestroy, - OnInit, - ViewEncapsulation } from '@angular/core'; -import { Subscription } from 'rxjs'; - -import { - Filter, - FilterConfig, - FilterField, - FilterEvent, - FilterType -} from 'patternfly-ng/filter'; - -import { - SortConfig, - SortField, - SortEvent -} from 'patternfly-ng/sort'; - -import { ToolbarConfig } from 'patternfly-ng/toolbar'; - -import { PipelineService } from '../../service/pipeline.service'; -import { Pipeline } from '../../model/pipeline.model'; -import { Selection } from '../../model/selection.model'; -import { LauncherComponent } from '../../launcher.component'; -import { LauncherStep } from '../../launcher-step'; -import { broadcast } from '../../shared/telemetry.decorator'; - -@Component({ - encapsulation: ViewEncapsulation.None, - selector: 'f8launcher-releasestrategy-importapp-step', - templateUrl: './release-strategy-importapp-step.component.html', - styleUrls: ['./release-strategy-importapp-step.component.less'] -}) -export class ReleaseStrategyImportappStepComponent extends LauncherStep implements OnInit, OnDestroy { - @Input() id: string; - @Input() optional = false; - - toolbarConfig: ToolbarConfig; - - private allPipelines: Pipeline[]; - private filterConfig: FilterConfig; - private isAscendingSort = true; - private _pipelines: Pipeline[]; - private _pipelineId: string; - private sortConfig: SortConfig; - private currentSortField: SortField; - - private subscriptions: Subscription[] = []; - - constructor(@Host() public launcherComponent: LauncherComponent, - private pipelineService: PipelineService) { - super(launcherComponent); - } - - ngOnInit() { - this.filterConfig = { - fields: [{ - id: 'name', - title: 'Name', - placeholder: 'Filter by Name...', - type: FilterType.TEXT - }] as FilterField[], - appliedFilters: [] - } as FilterConfig; - - this.sortConfig = { - fields: [{ - id: 'name', - title: 'Name', - sortType: 'alpha' - }], - isAscending: this.isAscendingSort - } as SortConfig; - - this.toolbarConfig = { - filterConfig: this.filterConfig, - sortConfig: this.sortConfig - } as ToolbarConfig; - - this.launcherComponent.addStep(this); - - this.subscriptions.push(this.pipelineService.getPipelines().subscribe((result: Array) => { - this._pipelines = result; - this.restoreSummary(); - })); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - } - - // Accessors - - /** - * Returns a list of pipelines to display - * - * @returns {Pipeline[]} The list of pipelines - */ - get pipelines(): Pipeline[] { - return this._pipelines; - } - - /** - * Returns pipeline ID - * - * @returns {string} The pipeline ID - */ - get pipelineId(): string { - return this._pipelineId; - } - - /** - * Set the pipeline ID - * - * @param {string} val The pipeline ID - */ - set pipelineId(val: string) { - this._pipelineId = val; - } - - /** - * Returns indicator that step is completed - * - * @returns {boolean} True if step is completed - */ - get completed(): boolean { - return (this.launcherComponent.summary.pipeline !== undefined); - } - - // Filter - - applyFilters(filters: Filter[]): void { - this._pipelines = []; - if (filters && filters.length > 0) { - this.allPipelines.forEach((pipeline) => { - if (this.matchesFilters(pipeline, filters)) { - this._pipelines.push(pipeline); - } - }); - } else { - this._pipelines = this.allPipelines; - } - } - - // Handle filter changes - filterChanged($event: FilterEvent): void { - this.applyFilters($event.appliedFilters); - } - - matchesFilter(item: any, filter: Filter): boolean { - let match = true; - if (filter.field.id === 'name') { - match = item.name.match(filter.value) !== null; - } - return match; - } - - matchesFilters(item: any, filters: Filter[]): boolean { - let matches = true; - filters.forEach((filter) => { - if (!this.matchesFilter(item, filter)) { - matches = false; - return matches; - } - }); - return matches; - } - - // Sort - - compare(item1: any, item2: any): number { - let compValue = 0; - if (this.currentSortField.id === 'name') { - compValue = item1.name.localeCompare(item2.name); - } - if (!this.isAscendingSort) { - compValue = compValue * -1; - } - return compValue; - } - - // Handle sort changes - sortChanged($event: SortEvent): void { - this.currentSortField = $event.field; - this.isAscendingSort = $event.isAscending; - this._pipelines.sort((item1: any, item2: any) => this.compare(item1, item2)); - } - - // Steps - @broadcast('completePipelineStep_Import', { - 'launcherComponent.summary.pipeline': { - pipeline: 'name' - } - }) - navToNextStep(): void { - this.launcherComponent.navToNextStep('ReleaseStrategy'); - } - - updatePipelineSelection(pipeline: Pipeline): void { - this.launcherComponent.summary.pipeline = pipeline; - } - - // Private - - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection === undefined) { - return; - } - this.pipelineId = selection.pipelineId; - for (let i = 0; i < this.pipelines.length; i++) { - if (this.pipelineId === this.pipelines[i].id) { - this.launcherComponent.summary.pipeline = this.pipelines[i]; - } - } - } - - toggleExpanded(pipeline: Pipeline) { - pipeline.expanded = (pipeline.expanded !== undefined) ? !pipeline.expanded : false; - } -} diff --git a/projects/ngx-launcher/src/lib/launcher-step.ts b/projects/ngx-launcher/src/lib/launcher-step.ts index cca56398..e69a1ba5 100644 --- a/projects/ngx-launcher/src/lib/launcher-step.ts +++ b/projects/ngx-launcher/src/lib/launcher-step.ts @@ -1,7 +1,7 @@ -import { Input, ViewChild, ElementRef, OnDestroy } from '@angular/core'; -import { LauncherComponent } from './launcher.component'; -import { fromEvent, Observable, Subscription } from 'rxjs'; +import { ElementRef, Input, OnDestroy, Type, ViewChild } from '@angular/core'; +import { fromEvent, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; +import { Projectile } from './model/projectile.model'; export abstract class LauncherStep implements OnDestroy { /** @@ -17,12 +17,12 @@ export abstract class LauncherStep implements OnDestroy { /** * Flag indicating step is hidden */ - @Input() hidden: boolean = false; + @Input() hidden: boolean; /** * Flag indicating step is optional */ - @Input() optional: boolean = false; + @Input() optional: boolean; /** * Style class for the step container @@ -36,13 +36,10 @@ export abstract class LauncherStep implements OnDestroy { @ViewChild('section') element: ElementRef; - protected _launcherComponent: LauncherComponent; + private scrollEvents: Subscription = fromEvent(window, 'scroll') + .pipe(debounceTime(100)).subscribe(() => this.isInView()); - private scrollEvents: Subscription = fromEvent(window, 'scroll').pipe(debounceTime(100)).subscribe(() => this.isInView()); - - constructor(launcherComponent: LauncherComponent) { - this._launcherComponent = launcherComponent; - } + constructor(private _projectile: Projectile) {} ngOnDestroy(): void { this.scrollEvents.unsubscribe(); @@ -58,8 +55,24 @@ export abstract class LauncherStep implements OnDestroy { const inView = elementBottom !== 0 && elementTop <= viewportTop; if (inView) { - this._launcherComponent.onInViewportChange(this.id); + this._projectile.selectedSection = this.id; + } + } + } + + restore(context?): void { + if (context) { + this._projectile.restore(this.id, context); + } else { + if (!this.restoreModel) { + throw new Error('can not call restore without context and not implement restoreModel function'); + } + const state = this._projectile.getSavedState(this.id); + if (state) { + this.restoreModel(state); } } } + + restoreModel?(model: any): void; } diff --git a/projects/ngx-launcher/src/lib/launcher.component.html b/projects/ngx-launcher/src/lib/launcher.component.html index d119d020..0396e2b8 100644 --- a/projects/ngx-launcher/src/lib/launcher.component.html +++ b/projects/ngx-launcher/src/lib/launcher.component.html @@ -1,104 +1,21 @@
-
- - -
- - -
- -
-
- - - - - - - - - - - - - -
-
-
- -
-
-
- - - - - -
- - -
- -
- -
-
-
- - - - - - -
-
-
- -
-
-
- - - +
+ + + + + + + +
+
+ +
+
diff --git a/projects/ngx-launcher/src/lib/launcher.component.spec.ts b/projects/ngx-launcher/src/lib/launcher.component.spec.ts index a10653fb..350c62b3 100644 --- a/projects/ngx-launcher/src/lib/launcher.component.spec.ts +++ b/projects/ngx-launcher/src/lib/launcher.component.spec.ts @@ -1,194 +1,60 @@ import { Component, - Input + Host, + OnInit, + ViewChild } from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { CancelOverlayComponent } from './cancel-overlay/cancel-overlay.component'; import { LauncherComponent } from './launcher.component'; - -import { ActivateBoosterCreateappNextstepComponent } - from './create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component'; -import { ProjectProgressCreateappNextstepComponent } - from './create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component'; -import { ProjectProgressImportappNextstepComponent } - from './import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component'; - -import { HelperService } from './service/helper.service'; -import { TokenProvider } from '../lib/service/token-provider'; -import { Subject, Observable } from 'rxjs'; -import { Progress } from './model/progress.model'; -import { ProjectProgressService } from './service/project-progress.service'; -import { Broadcaster } from 'ngx-base'; -import { BroadcasterTestProvider } from './create-app/targetenvironment-createapp-step/target-environment-createapp-step.component.spec'; -import { DependencyCheckService } from './service/dependency-check.service'; -import { DemoDependencyCheckService } from '../../../../src/app/service/demo-dependency-check.service'; -import { ProjectSummaryService } from './service/project-summary.service'; -import { DemoProjectSummaryService } from '../../../../src/app/service/demo-project-summary.service'; import { DependencyEditorModule } from 'fabric8-analytics-dependency-editor'; -import { CheService } from './service/che.service'; -import { WorkSpacesService } from './service/workSpaces.service'; -import { Che } from './model/che.model'; -import { WorkspaceLinks } from './model/workspace.model'; - -// @ts-ignore -@Component({ - selector: 'f8launcher-step-indicator', - template: '' -}) -export class Fakef8launcherStepIndicator { - @Input() inProgress: boolean; -} - -@Component({ - selector: 'f8launcher-missionruntime-createapp-step', - template: '' -}) -export class Fakef8launcherMissionruntimeCreateappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; -} - -@Component({ - selector: 'f8launcher-dependencychecker-createapp-step', - template: '' -}) -export class Fakef8launcherDependencyCheckeerCreatesppStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; - @Input() depEditorFlag = false; -} - -@Component({ - selector: 'f8launcher-targetenvironment-createapp-step', - template: '' -}) -export class Fakef8launcherTargetEnvironmentCreateappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; -} - -@Component({ - selector: 'f8launcher-releasestrategy-createapp-step', - template: '' -}) -export class Fakef8launcherReleaseStrategyCreateappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; -} - -@Component({ - selector: 'f8launcher-gitprovider-createapp-step', - template: '' -}) -export class Fakef8launcherGitproviderCreateappStep { - @Input() id: string; - @Input() completed: boolean = false; - @Input() hidden: boolean = false; - @Input() styleClass: string; - @Input() title: string; -} - -@Component({ - selector: 'f8launcher-projectsummary-createapp-step', - template: '' -}) -export class Fakef8launcherProjectSummaryCreateappStep { - @Input() id: string; - @Input() completed: boolean = false; - @Input() hidden: boolean = false; - @Input() styleClass: string; - @Input() title: string; - @Input() depEditorFlag: boolean = false; -} - -@Component({ - selector: 'f8launcher-releasestrategy-importapp-step', - template: '' -}) -export class Fakef8launcherReleaseStrategyImportappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; - @Input() optional = false; -} +import { Broadcaster } from 'ngx-base'; +import { CancelOverlayComponent } from './cancel-overlay/cancel-overlay.component'; +import { + ActivateBoosterNextstepComponent +} from './components/activate-booster-nextstep/activate-booster-nextstep.component'; +import { + ProjectProgressNextstepComponent +} from './components/project-progress-nextstep/project-progress-nextstep.component'; +import { BroadcasterTestProvider } from './components/targetenvironment-step/target-environment-step.component.spec'; +import { LauncherStep } from './launcher-step'; +import { Projectile } from './model/projectile.model'; @Component({ - selector: 'f8launcher-gitprovider-importapp-step', - template: '' + template: ` + + + + ` }) -export class Fakef8launcherGitproviderImportappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; +export class ParentComponent { + @ViewChild('launcher') launcherComponent: LauncherComponent; } @Component({ - selector: 'f8launcher-projectsummary-importapp-step', + selector: 'f8launcher-fake-step', template: '' }) -export class Fakef8launcherProjectSummaryImportappStep { - @Input() id: string; - @Input() completed = false; - @Input() hidden = false; - @Input() styleClass: string; - @Input() title: string; -} - -const mockHelperService = { - getBackendUrl(): string { - return 'https://backend.url/'; - }, - getOrigin(): string { - return 'origin'; +export class Fakef8StepComponent extends LauncherStep implements OnInit { + completed: boolean; + constructor(@Host() private launcherComponent: LauncherComponent, projectile: Projectile) { + super(projectile); } -}; - -const progressSubject: Subject = new Subject(); -const mockProjectProgressService = { - getProgress(): Observable { - return progressSubject.asObservable(); + ngOnInit(): void { + this.launcherComponent.addStep(this); } -}; - -const workSpaceSubject: Subject = new Subject(); -const mockWorkSpacesService = { - createWorkSpace(): Observable { - return workSpaceSubject.asObservable(); + restoreModel(model: any): void { } -}; - -const cheSubject: Subject = new Subject(); -const mockCheService = { - createWorkSpace(): Observable { - return cheSubject.asObservable(); - } -}; +} describe('LauncherComponent', () => { - let component: LauncherComponent; - let fixture: ComponentFixture; + let component: ParentComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -199,42 +65,27 @@ describe('LauncherComponent', () => { RouterTestingModule ], declarations: [ - ActivateBoosterCreateappNextstepComponent, CancelOverlayComponent, - Fakef8launcherDependencyCheckeerCreatesppStep, - Fakef8launcherGitproviderCreateappStep, - Fakef8launcherGitproviderImportappStep, - Fakef8launcherMissionruntimeCreateappStep, - Fakef8launcherProjectSummaryCreateappStep, - Fakef8launcherProjectSummaryImportappStep, - Fakef8launcherReleaseStrategyCreateappStep, - Fakef8launcherReleaseStrategyImportappStep, - Fakef8launcherTargetEnvironmentCreateappStep, - Fakef8launcherStepIndicator, + ActivateBoosterNextstepComponent, + ProjectProgressNextstepComponent, + Fakef8StepComponent, LauncherComponent, - ProjectProgressCreateappNextstepComponent, - ProjectProgressImportappNextstepComponent + ParentComponent ], providers: [ - TokenProvider, - { provide: DependencyCheckService, useClass: DemoDependencyCheckService }, - { provide: HelperService, useValue: mockHelperService }, - { provide: ProjectProgressService, useValue: mockProjectProgressService }, - { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster }, - { provide: ProjectSummaryService, useClass: DemoProjectSummaryService }, - { provide: CheService, useValue: mockCheService }, - { provide: WorkSpacesService, useValue: mockWorkSpacesService } + Projectile, + { provide: Broadcaster, useValue: BroadcasterTestProvider.broadcaster } ] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(LauncherComponent); + fixture = TestBed.createComponent(ParentComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { - expect(component).toBeTruthy(); + expect(component.launcherComponent).toBeTruthy(); }); }); diff --git a/projects/ngx-launcher/src/lib/launcher.component.ts b/projects/ngx-launcher/src/lib/launcher.component.ts index d49ba84d..690b20d4 100644 --- a/projects/ngx-launcher/src/lib/launcher.component.ts +++ b/projects/ngx-launcher/src/lib/launcher.component.ts @@ -3,20 +3,14 @@ import { Component, EventEmitter, Input, - OnInit, Output, - ViewChild, - ViewEncapsulation + ViewEncapsulation, + OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Selection } from './model/selection.model'; -import { Summary } from './model/summary.model'; -import { StepIndicatorComponent } from './step-indicator/step-indicator.component'; -import { LauncherStep } from './launcher-step'; -import { ProjectSummaryService } from './service/project-summary.service'; -import { broadcast } from './shared/telemetry.decorator'; import { Broadcaster } from 'ngx-base'; +import { LauncherStep } from './launcher-step'; +import { Projectile } from './model/projectile.model'; @Component({ encapsulation: ViewEncapsulation.None, @@ -24,125 +18,38 @@ import { Broadcaster } from 'ngx-base'; templateUrl: './launcher.component.html', styleUrls: ['./launcher.component.less'] }) -export class LauncherComponent implements AfterViewInit, OnInit { +export class LauncherComponent implements AfterViewInit, OnDestroy { /** - * Flag indicating to show the import application work flow. Defaults to the create new application work flow. + * Flag indicating to show the getting started info after the process is completed. * * @type {boolean} */ - @Input() importApp = false; - - /** - * Setting the flow to 'launch' will skip the pipeline step and show a cluster dropdown. Defaults to 'osio'. - */ - @Input() flow = 'osio'; - - /** - * Setting the flag to show dependency editor as internal feature - */ - @Input() depEditorFlag = false; + @Input() gettingStartedInfo = false; /** - * Setting the flag to show or hide the View pipeline and Open IDE button - */ - @Input() nextButtons = false; /** * The event emitted when an cancel has been selected */ @Output('onCancel') onCancel = new EventEmitter(); - /** - * The event emitted after setup has completed - */ - @Output('onComplete') onComplete = new EventEmitter(); - - @ViewChild('stepIndicator') stepIndicator: StepIndicatorComponent; - public statusLink: string; - private _selectedSection: string; private _showCancelOverlay = false; private _steps: LauncherStep[] = []; - private _summary: Summary; private summaryCompleted = false; - constructor(private route: ActivatedRoute, - private broad: Broadcaster, - private router: Router, - private projectSummaryService: ProjectSummaryService) { + constructor(private broadcaster: Broadcaster, public projectile: Projectile) { } ngAfterViewInit() { + const id = this.projectile.selectedSection || this.firstNonHiddenStep.id; setTimeout(() => { - const params = this.selectionParams; - const id = (this.selectionParams !== undefined) ? 'GitProvider' : this.firstNonHiddenStep.id; - this.stepIndicator.navToStep(id); - }, 300); - } - - ngOnInit() { - const projectName = this.route.snapshot.params['projectName']; - this._summary = { - targetEnvironment: this.flow === 'osio' ? 'os' : undefined, - dependencyCheck: { - projectName: (projectName !== undefined && projectName.length > 0) ? projectName : undefined - }, - gitHubDetails: {} - } as Summary; - } - - onInViewportChange(id: string) { - setTimeout(() => { - this._selectedSection = id; - }, 10); // Avoids ExpressionChangedAfterItHasBeenCheckedError - } - - // Accessors - /** - * Returns the current step ID - * - * @returns {string} The current step ID - */ - get selectedSection(): string { - return this._selectedSection; - } - - /** - * Returns current selection needed to restore upon a redirect - * - * @returns {Selection} The current selection - */ - get currentSelection(): Selection { - const selection = { - groupId: (this._summary.dependencyCheck !== undefined) ? this._summary.dependencyCheck.groupId : undefined, - missionId: (this._summary.mission !== undefined) ? this._summary.mission.id : undefined, - pipelineId: (this._summary.pipeline !== undefined) ? this._summary.pipeline.id : undefined, - projectName: (this._summary.dependencyCheck !== undefined) - ? this._summary.dependencyCheck.projectName : undefined, - projectVersion: (this._summary.dependencyCheck !== undefined) - ? this._summary.dependencyCheck.projectVersion : undefined, - runtimeId: (this._summary.runtime !== undefined) ? this._summary.runtime.id : undefined, - runtimeVersion: (this._summary.runtime !== undefined) ? this._summary.runtime.version : undefined, - spacePath: (this._summary.dependencyCheck !== undefined) ? this._summary.dependencyCheck.spacePath : undefined, - targetEnvironment: this._summary.targetEnvironment, - cluster: this._summary.cluster, - dependencyEditor: this._summary.dependencyEditor - } as Selection; - return selection; + this.broadcaster.broadcast('navigate-to', id); + }, 2000); } - /** - * Returns current selection parameters, if any - * - * @returns {Selection} Current selection parameters or undefined - */ - get selectionParams(): Selection { - let userSelection: Selection; - const selection = this.getRequestParam('selection'); - if (selection !== null) { - userSelection = JSON.parse(selection); - } - return userSelection; + ngOnDestroy(): void { + this.projectile.selectedSection = ''; } /** @@ -172,24 +79,6 @@ export class LauncherComponent implements AfterViewInit, OnInit { return this._steps; } - /** - * Returns summary, including full Mission and Runtime objects - * - * @returns {Summary} The current user summary - */ - get summary(): Summary { - return this._summary; - } - - /** - * Set user summary - * - * @param {Summary} val The current user summary - */ - set summary(summary: Summary) { - this._summary = summary; - } - // Steps /** * Add step @@ -227,14 +116,6 @@ export class LauncherComponent implements AfterViewInit, OnInit { this.onCancel.emit(); } - /** - * Setup has completed - */ - @broadcast('viewApplicationButtonClicked', {}) - completed() { - this.onComplete.emit(); - } - /** * Get step for the given ID * @@ -256,34 +137,12 @@ export class LauncherComponent implements AfterViewInit, OnInit { /** * Navigate to next step */ - navToNextStep(fromStepId: string = this.selectedSection): void { - if (fromStepId === 'ProjectSummary') { - this.summaryCompleted = true; - return; - } - setTimeout(() => { - this.stepIndicator.navToNextStep(fromStepId); - }, 10); + completed(): void { + this.summaryCompleted = true; } // Private private get firstNonHiddenStep(): LauncherStep { return this._steps.find(step => !step.hidden); } - - /** - * Helper to retrieve request parameters - * - * @param name The request parameter to retrieve - * @returns {any} The request parameter value or null - */ - private getRequestParam(name: string): string { - const search = (window.location.search !== undefined && window.location.search.length > 0) - ? window.location.search : window.location.href; - const param = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(search); - if (param !== null) { - return decodeURIComponent(param[1]); - } - return null; - } } diff --git a/projects/ngx-launcher/src/lib/launcher.module.ts b/projects/ngx-launcher/src/lib/launcher.module.ts index 083c211d..58a2b442 100644 --- a/projects/ngx-launcher/src/lib/launcher.module.ts +++ b/projects/ngx-launcher/src/lib/launcher.module.ts @@ -1,5 +1,5 @@ -import { NgModule, Provider } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { ModalModule } from 'ngx-modal'; @@ -15,49 +15,45 @@ import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; import { SortArrayPipeModule, TruncatePipeModule } from 'patternfly-ng/pipe'; import { ToolbarModule } from 'patternfly-ng/toolbar'; +import { CancelOverlayComponent } from './cancel-overlay/cancel-overlay.component'; // Note: This has to be imported first import { StepIndicatorComponent } from './step-indicator/step-indicator.component'; -import { CancelOverlayComponent } from './cancel-overlay/cancel-overlay.component'; -import { ActivateBoosterCreateappNextstepComponent } - from './create-app/activate-booster-createapp-nextstep/activate-booster-createapp-nextstep.component'; -import { DependencyEditorCreateappStepComponent } - from './create-app/dependency-editor-step/dependency-editor-step.component'; -import { GitproviderCreateappStepComponent } - from './create-app/gitprovider-createapp-step/gitprovider-createapp-step.component'; -import { GitProviderRepositoryValidatorDirective } - from './create-app/gitprovider-createapp-step/gitprovider-repository.validator'; -import { ExistingRepositoryValidatorDirective } from './import-app/gitprovider-importapp-step/repository.validator'; +import { + ActivateBoosterNextstepComponent +} from './components/activate-booster-nextstep/activate-booster-nextstep.component'; +import { DependencyEditorStepComponent } from './components/dependency-editor-step/dependency-editor-step.component'; +import { + GitProviderRepositoryValidatorDirective +} from './components/gitprovider-step/gitprovider-repository.validator'; +import { GitproviderStepComponent } from './components/gitprovider-step/gitprovider-step.component'; +import { LinkAccountsStepComponent } from './components/link-accounts-step/link-accounts-step.component'; +import { MissionRuntimeStepComponent } from './components/mission-runtime-step/mission-runtime-step.component'; +import { + ProjectProgressNextstepComponent +} from './components/project-progress-nextstep/project-progress-nextstep.component'; +import { ProjectSummaryStepComponent } from './components/project-summary-step/project-summary-step.component'; +import { ReleaseStrategyStepComponent } from './components/release-strategy-step/release-strategy-step.component'; +import { TargetEnvironmentStepComponent } from './components/targetenvironment-step/target-environment-step.component'; import { LowerCaseDirective } from './shared/lowercase.directive'; import { ProjectNameValidatorDirective } from './shared/project-name.validator'; -import { MissionRuntimeCreateappStepComponent } - from './create-app/mission-runtime-createapp-step/mission-runtime-createapp-step.component'; -import { ProjectProgressCreateappNextstepComponent } - from './create-app/project-progress-createapp-nextstep/project-progress-createapp-nextstep.component'; -import { ProjectSummaryCreateappStepComponent } - from './create-app/project-summary-createapp-step/project-summary-createapp-step.component'; -import { ReleaseStrategyCreateappStepComponent } - from './create-app/release-strategy-createapp-step/release-strategy-createapp-step.component'; -import { TargetEnvironmentCreateappStepComponent } - from './create-app/targetenvironment-createapp-step/target-environment-createapp-step.component'; -import { LinkAccountsCreateappStepComponent } - from './create-app/link-accounts-createapp-step/link-accounts-createapp-step.component'; -import { GitproviderImportappStepComponent } - from './import-app/gitprovider-importapp-step/gitprovider-importapp-step.component'; -import { ProjectProgressImportappNextstepComponent } - from './import-app/project-progress-importapp-nextstep/project-progress-importapp-nextstep.component'; -import { ProjectSummaryImportappStepComponent } - from './import-app/project-summary-importapp-step/project-summary-importapp-step.component'; -import { ReleaseStrategyImportappStepComponent } - from './import-app/release-strategy-importapp-step/release-strategy-importapp-step.component'; import { ToastNotificationComponent } from './toast-notification/toast-notification.component'; -import { MissionRuntimeService } from './service/mission-runtime.service'; -import { ProjectProgressService } from './service/project-progress.service'; +import { GitproviderReviewComponent } from './components/gitprovider-step/gitprovider-review.component'; +import { MissionRuntimeReviewComponent } from './components/mission-runtime-step/mission-runtime-review.component'; -import { LauncherComponent } from './launcher.component'; import { Broadcaster } from 'ngx-base'; +import { + DependencyEditorReviewComponent +} from './components/dependency-editor-step/dependency-editor-review.component'; +import { ReleaseStrategyReviewComponent } from './components/release-strategy-step/release-strategy-review.component'; +import { + TargetEnvironmentReviewComponent +} from './components/targetenvironment-step/target-environment-review.component'; +import { LauncherComponent } from './launcher.component'; +import { Projectile } from './model/projectile.model'; +import { ButtonNextStepComponent } from './shared/button-next-step.component'; @NgModule({ imports: [ @@ -74,38 +70,52 @@ import { Broadcaster } from 'ngx-base'; TypeaheadModule.forRoot() ], exports: [ - LauncherComponent + LauncherComponent, + StepIndicatorComponent, + TargetEnvironmentStepComponent, + MissionRuntimeStepComponent, + GitproviderStepComponent, + ProjectSummaryStepComponent, + TargetEnvironmentReviewComponent, + GitproviderReviewComponent, + ReleaseStrategyStepComponent, + ReleaseStrategyReviewComponent, + DependencyEditorStepComponent, + DependencyEditorReviewComponent, + MissionRuntimeReviewComponent ], declarations: [ - ActivateBoosterCreateappNextstepComponent, + ButtonNextStepComponent, + ActivateBoosterNextstepComponent, CancelOverlayComponent, - DependencyEditorCreateappStepComponent, - GitproviderCreateappStepComponent, + DependencyEditorStepComponent, + DependencyEditorReviewComponent, + GitproviderStepComponent, LowerCaseDirective, ProjectNameValidatorDirective, GitProviderRepositoryValidatorDirective, - ExistingRepositoryValidatorDirective, - GitproviderImportappStepComponent, - MissionRuntimeCreateappStepComponent, - ProjectProgressCreateappNextstepComponent, - ProjectProgressImportappNextstepComponent, - ProjectSummaryCreateappStepComponent, - ProjectSummaryImportappStepComponent, - ReleaseStrategyCreateappStepComponent, - ReleaseStrategyImportappStepComponent, - TargetEnvironmentCreateappStepComponent, - LinkAccountsCreateappStepComponent, + GitproviderReviewComponent, + MissionRuntimeReviewComponent, + MissionRuntimeStepComponent, + ProjectProgressNextstepComponent, + ProjectSummaryStepComponent, + ReleaseStrategyStepComponent, + ReleaseStrategyReviewComponent, + TargetEnvironmentStepComponent, + TargetEnvironmentReviewComponent, + LinkAccountsStepComponent, StepIndicatorComponent, ToastNotificationComponent, LauncherComponent ], providers: [ BsDropdownConfig, - Broadcaster + Broadcaster, + Projectile, + LauncherComponent ] }) export class LauncherModule { - } // Models @@ -116,7 +126,7 @@ export { Mission } from './model/mission.model'; export { Pipeline } from './model/pipeline.model'; export { Progress } from './model/progress.model'; export { Runtime } from './model/runtime.model'; -export { Summary } from './model/summary.model'; +export { Projectile } from './model/projectile.model'; export { TargetEnvironment } from './model/target-environment.model'; // Services @@ -130,10 +140,8 @@ export { ProjectProgressService } from './service/project-progress.service'; export { ProjectSummaryService } from './service/project-summary.service'; export { TargetEnvironmentService } from './service/target-environment.service'; export { TokenService } from './service/token.service'; -export { CheService } from './service/che.service'; -export { WorkSpacesService } from './service/workSpaces.service'; // Utility Service export { HelperService } from './service/helper.service'; -export { DependencyEditorModule, URLProvider, DependencyEditorTokenProvider }; +export { DependencyEditorModule, URLProvider, DependencyEditorTokenProvider }; diff --git a/projects/ngx-launcher/src/lib/model/booster.model.ts b/projects/ngx-launcher/src/lib/model/booster.model.ts index 0d95ef77..154f6f25 100644 --- a/projects/ngx-launcher/src/lib/model/booster.model.ts +++ b/projects/ngx-launcher/src/lib/model/booster.model.ts @@ -1,3 +1,6 @@ +import { Mission } from './mission.model'; +import { Runtime } from './runtime.model'; + export class BoosterVersion { id: string; name: string; @@ -27,3 +30,8 @@ export class Booster { runtime: BoosterRuntime; version: BoosterVersion; } + +export class BoosterState { + mission: Mission; + runtime: Runtime; +} diff --git a/projects/ngx-launcher/src/lib/model/che.model.ts b/projects/ngx-launcher/src/lib/model/che.model.ts deleted file mode 100644 index 5324f3ba..00000000 --- a/projects/ngx-launcher/src/lib/model/che.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class Che { - clusterFull: boolean; - running: boolean; - multiTenant: boolean; -} diff --git a/projects/ngx-launcher/src/lib/model/dependency-check.model.ts b/projects/ngx-launcher/src/lib/model/dependency-check.model.ts index 0fac8d13..f902daba 100644 --- a/projects/ngx-launcher/src/lib/model/dependency-check.model.ts +++ b/projects/ngx-launcher/src/lib/model/dependency-check.model.ts @@ -4,4 +4,5 @@ export class DependencyCheck { projectName: string; projectVersion: string; spacePath: string; + targetEnvironment?: string; } diff --git a/projects/ngx-launcher/src/lib/model/projectile.model.spec.ts b/projects/ngx-launcher/src/lib/model/projectile.model.spec.ts new file mode 100644 index 00000000..c808af11 --- /dev/null +++ b/projects/ngx-launcher/src/lib/model/projectile.model.spec.ts @@ -0,0 +1,65 @@ +import { HttpParams } from '@angular/common/http'; +import { GitHubDetails } from './github-details.model'; +import { Mission } from './mission.model'; +import { Projectile, StepState } from './projectile.model'; + +describe('State saving and restoring', () => { + class TestableProjectile extends Projectile { + protected searchParams() { + return new URLSearchParams(this.toUrl()); + } + } + + it('should save the state in an url', () => { + const projectile = new TestableProjectile(); + const gitHubDetails = new GitHubDetails(); + const state = new StepState(gitHubDetails, [ + { name: 'repository', value: 'repository' }, + { name: 'organization', value: 'organization' } + ]); + + gitHubDetails.repository = 'repo'; + gitHubDetails.organization = 'org'; + gitHubDetails.login = 'ignored'; + + projectile.setState('myId', state); + + expect(projectile.toUrl()) + .toBe('?selectedSection=&myId=%7B%22repository%22%3A%22repo%22%2C%22organization%22%3A%22org%22%7D'); + expect(projectile.getSavedState('myId')).toEqual({ repository: 'repo', organization: 'org' }); + }); + + it('should create HttpParams of the state', () => { + const projectile = new Projectile(); + projectile.setState('1', new StepState({ 'param1': 'value1' }, [{ name: 'p1', value: 'param1' }])); + projectile.setState('2', new StepState({ 'param2': 'value2' }, [{ name: 'p2', value: 'param2' }])); + + const http = new HttpParams() + .append('p1', 'value1') + .append('p2', 'value2'); + + expect(projectile.toHttpPayload().toString()).toEqual(http.toString()); + }); + + it('should restore state from an url', () => { + const projectile = new TestableProjectile<{mission: Mission}>(); + const mission = new Mission(); + const state = new StepState({mission: mission}, [ + { name: 'missionId', value: 'mission.id' } + ]); + const id = 'health-check'; + const description = 'some description that will not be saved'; + + const testStateId = 'myId'; + + mission.id = id; + + const missions = { mission: [{ id: 'rest', description: 'rest endpoint' }, + { id: id, description: description }, { id: 'other', description: 'some more' }]}; + + projectile.setState(testStateId, state); + + const restoredMission = projectile.restore(testStateId, missions); + expect(restoredMission.state.mission.description).toEqual(description); + }); +}); diff --git a/projects/ngx-launcher/src/lib/model/projectile.model.ts b/projects/ngx-launcher/src/lib/model/projectile.model.ts new file mode 100644 index 00000000..29c90e10 --- /dev/null +++ b/projects/ngx-launcher/src/lib/model/projectile.model.ts @@ -0,0 +1,157 @@ +import { HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; + +import * as _ from 'lodash'; + +import { DependencyCheck } from './dependency-check.model'; + +@Injectable() +export class Projectile { + private _state = {}; + private _selectedSection = ''; + + get selectedSection(): string { + if (!this._selectedSection) { + this._selectedSection = this.searchParams().get('selectedSection'); + } + return this._selectedSection; + } + + set selectedSection(selectedSection: string) { + this._selectedSection = selectedSection; + } + + get sharedState(): StepState { + let state = this._state['shared']; + if (!state) { + const dependencyCheck = this.getSavedState('shared') || new DependencyCheck(); + state = new StepState(dependencyCheck, [ + { name: 'projectName', value: 'projectName' }, + { name: 'projectVersion', value: 'projectVersion' }, + { name: 'groupId', value: 'groupId' }, + { name: 'artifactId', value: 'artifactId' }, + { name: 'spacePath', value: 'spacePath' }, + { name: 'targetEnvironment', value: 'targetEnvironment' } + ]); + this.setState('shared', state); + } + return state; + } + + setState(stepId: string, state: StepState) { + this._state[stepId] = state; + } + + getState(stepId: string): StepState { + return this._state[stepId]; + } + + getSavedState(stepId: string): any { + const state = this.searchParams().get(stepId); + return JSON.parse(state); + } + + restore(stepId: string, state: any): StepState { + const model = this.getSavedState(stepId); + this._state[stepId].restore(state, model); + return this._state[stepId]; + } + + get redirectUrl(): string { + return '/' + window.location.hash + this.toUrl(); + } + + toUrl(): string { + return `?selectedSection=${encodeURIComponent(this._selectedSection)}&` + + Object.keys(this._state).map(k => + `${encodeURIComponent(k)}=${encodeURIComponent('{' + + this._state[k].save().map(o => this.stateToJsonPart(o)) + + '}')}` + ).join('&'); + } + + toHttpPayload(): HttpParams { + const params: {[param: string]: string} = {}; + Object.keys(this._state).map(k => { + this._state[k].save().map(f => params[f.name] = f.value); + }); + return new HttpParams({fromObject: params}); + } + + private stateToJsonPart(o: any) { + return `"${o.name}":"${o.value}"`; + } + + /** + * Angular doesn't use the searchParams part of the url, but appends the query string on the hash + * this function converts to a URL object and uses that to create URLSearchParams. + */ + protected searchParams(): URLSearchParams { + const href = window.location.href; + return new URL(href.substr(href.indexOf('?')), 'http://dummy').searchParams; + } +} + +export class StepState { + constructor(private _state: T, private _filters: Filter[]) { } + + save(): any { + return this.filters.map(f => ({ name: f.name, value: _.get(this.state, f.value) })); + } + + restore(collection, state) { + this.filters.map(f => _.map( + this.get(collection, this.basePath(f.restorePath ? f.restorePath : f.value)), e => { + if (this.keyValue(e, f.value) === _.get(state, f.name)) { + const basePath = this.basePath(f.value); + if (basePath.length) { + _.set(this.state, basePath, e); + } else { + _.merge(this.state, e); + } + } + })); + } + + /** + * Specialised get that also gets things from collections + * @example + * this.get({ bla: [{ test: [{ mission: 'ha' }, { mission: 'ga' }] }] }, 'bla.test.mission'); + * // returns ["ha", "ga"] + */ + private get(object: any, path: string | string[]) { + if (typeof path === 'string') { + path = path.split('.'); + } + path.map(p => { + if (_.isArray(object)) { + object = _.flatten(_.map(object, p)); + } else { + object = _.get(object, p); + } + }); + return object; + } + + private keyValue(element: any, path: string) { + return _.get(element, path.split('.').pop()); + } + + private basePath(path: string) { + const basePath = path.split('.'); + basePath.pop(); + return basePath; + } + + get state(): T { + return this._state; + } + + get filters(): Filter[] { + return this._filters; + } +} + +export class Filter { + constructor(public name: string, public value: string, public restorePath?: string) { } +} diff --git a/projects/ngx-launcher/src/lib/model/selection.model.ts b/projects/ngx-launcher/src/lib/model/selection.model.ts deleted file mode 100644 index cf997981..00000000 --- a/projects/ngx-launcher/src/lib/model/selection.model.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Cluster } from './cluster.model'; -import { DependencyCheck } from './dependency-check.model'; -import { DependencyEditor } from './dependency-editor/dependency-editor.model'; -export class Selection { - groupId?: string; - missionId?: string; - pipelineId?: string; - projectName?: string; - projectVersion?: string; - runtimeId?: string; - runtimeVersion?: { - id: string; - name: string; - }; - spacePath?: string; - targetEnvironment?: string; - cluster?: Cluster; - dependencyCheck: DependencyCheck; - dependencyEditor: DependencyEditor; -} diff --git a/projects/ngx-launcher/src/lib/model/summary.model.ts b/projects/ngx-launcher/src/lib/model/summary.model.ts deleted file mode 100644 index d5773a3d..00000000 --- a/projects/ngx-launcher/src/lib/model/summary.model.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Cluster } from './cluster.model'; -import { DependencyCheck } from './dependency-check.model'; -import { GitHubDetails } from './github-details.model'; -import { Mission } from './mission.model'; -import { Runtime } from './runtime.model'; -import { Pipeline } from './pipeline.model'; -import { DependencyEditor } from './dependency-editor/dependency-editor.model'; - -export class Summary { - cluster?: Cluster; - dependencyCheck: DependencyCheck; - dependencyEditor?: DependencyEditor; - gitHubDetails?: GitHubDetails; - mission: Mission; - organization: string; - pipeline: Pipeline; - runtime: Runtime; - targetEnvironment: string; -} diff --git a/projects/ngx-launcher/src/lib/model/target-environment.model.ts b/projects/ngx-launcher/src/lib/model/target-environment.model.ts index 426741b6..3ae7a246 100644 --- a/projects/ngx-launcher/src/lib/model/target-environment.model.ts +++ b/projects/ngx-launcher/src/lib/model/target-environment.model.ts @@ -1,3 +1,6 @@ +import { Cluster } from './cluster.model'; +import { DependencyCheck } from './dependency-check.model'; + export class TargetEnvironment { description: string; benefits: string[]; @@ -7,3 +10,8 @@ export class TargetEnvironment { id: string; styleClass: string; } + +export class TargetEnvironmentSelection { + cluster: Cluster; + dependencyCheck: DependencyCheck; +} diff --git a/projects/ngx-launcher/src/lib/model/workspace.model.ts b/projects/ngx-launcher/src/lib/model/workspace.model.ts deleted file mode 100644 index 0799cd66..00000000 --- a/projects/ngx-launcher/src/lib/model/workspace.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class WorkspaceLinks { - links?: { - open?: string; - }; -} diff --git a/projects/ngx-launcher/src/lib/review.component.ts b/projects/ngx-launcher/src/lib/review.component.ts new file mode 100644 index 00000000..3112d66d --- /dev/null +++ b/projects/ngx-launcher/src/lib/review.component.ts @@ -0,0 +1,19 @@ +import { Input, OnInit } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; +import { Projectile } from './model/projectile.model'; + +export class ReviewComponent implements OnInit { + @Input() + stepId: string; + data: any; + + constructor(private broadcaster: Broadcaster, private projectile: Projectile) {} + + ngOnInit(): void { + this.data = this.projectile.getState(this.stepId).state; + } + + navToStep(id: string = this.stepId) { + this.broadcaster.broadcast('navigate-to', id); + } +} diff --git a/projects/ngx-launcher/src/lib/service/che.service.ts b/projects/ngx-launcher/src/lib/service/che.service.ts deleted file mode 100644 index 34f1ed94..00000000 --- a/projects/ngx-launcher/src/lib/service/che.service.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Observable } from 'rxjs'; -import { Che } from '../model/che.model'; - -/** - * Abstract Che service to get state of Che server - */ -export abstract class CheService { - - /** - * Get state of Che server - * - * @returns {Observable} - */ - abstract getState(): Observable; -} diff --git a/projects/ngx-launcher/src/lib/service/mission-runtime.service.spec.ts b/projects/ngx-launcher/src/lib/service/mission-runtime.service.spec.ts index 789a43b5..3da1a45b 100644 --- a/projects/ngx-launcher/src/lib/service/mission-runtime.service.spec.ts +++ b/projects/ngx-launcher/src/lib/service/mission-runtime.service.spec.ts @@ -1,7 +1,7 @@ -import { EmptyReason, MissionRuntimeService } from './mission-runtime.service'; import { Observable, of } from 'rxjs'; -import { Catalog, CatalogBooster, CatalogMission, CatalogRuntime, CatalogRuntimeVersion } from '../model/catalog.model'; import { BoosterVersion } from '../model/booster.model'; +import { Catalog, CatalogBooster, CatalogMission, CatalogRuntime, CatalogRuntimeVersion } from '../model/catalog.model'; +import { EmptyReason, MissionRuntimeService } from './mission-runtime.service'; export const createMission = (name: string): CatalogMission => ({ id: name, @@ -97,7 +97,7 @@ describe('MissionRuntimeService', () => { spyOn(subscriber, 'errorHandler'); service.getBoosters().subscribe(subscriber.successHandler, subscriber.errorHandler); expect(subscriber.successHandler).not.toHaveBeenCalled(); - const expectedError = new Error(`Invalid catalog booster: ${JSON.stringify(service.catalog.boosters[0])}` ); + const expectedError = new Error(`Invalid catalog booster: ${JSON.stringify(service.catalog.boosters[0])}`); expect(subscriber.errorHandler).toHaveBeenCalledWith(expectedError); }); diff --git a/projects/ngx-launcher/src/lib/service/mission-runtime.service.ts b/projects/ngx-launcher/src/lib/service/mission-runtime.service.ts index 77defe9e..d7b0a254 100644 --- a/projects/ngx-launcher/src/lib/service/mission-runtime.service.ts +++ b/projects/ngx-launcher/src/lib/service/mission-runtime.service.ts @@ -1,8 +1,8 @@ -import { Observable } from 'rxjs'; import * as _ from 'lodash'; -import { Catalog, CatalogMission, CatalogRuntime } from '../model/catalog.model'; -import { Booster, BoosterRuntime, BoosterVersion } from '../model/booster.model'; +import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { Booster, BoosterRuntime, BoosterVersion } from '../model/booster.model'; +import { Catalog, CatalogMission, CatalogRuntime } from '../model/catalog.model'; export enum EmptyReason { @@ -95,7 +95,7 @@ export abstract class MissionRuntimeService { const mission: CatalogMission = missionById[b.mission]; const version = runtime && runtime.versions.find(v => v.id === b.version); if (!mission || !runtime || !version) { - throw new Error(`Invalid catalog booster: ${JSON.stringify(b)}` ); + throw new Error(`Invalid catalog booster: ${JSON.stringify(b)}`); } return { name: b.name, diff --git a/projects/ngx-launcher/src/lib/service/project-summary.service.ts b/projects/ngx-launcher/src/lib/service/project-summary.service.ts index 73c721b1..3bc51a95 100644 --- a/projects/ngx-launcher/src/lib/service/project-summary.service.ts +++ b/projects/ngx-launcher/src/lib/service/project-summary.service.ts @@ -1,6 +1,6 @@ import { Observable } from 'rxjs'; -import { Summary } from '../model/summary.model'; +import { Projectile } from '../model/projectile.model'; /** * Abstract project summary service provided to ensure consumer implements this pattern @@ -9,8 +9,8 @@ export abstract class ProjectSummaryService { /** * Set up the project for the given summary * - * @param {Summary} summary The project summary + * @param {Projectile} summary The project summary * @returns {Observable} */ - abstract setup(summary: Summary, retry?: number): Observable; + abstract setup(summary: Projectile, retry?: number): Observable; } diff --git a/projects/ngx-launcher/src/lib/service/token-provider.ts b/projects/ngx-launcher/src/lib/service/token-provider.ts index 518feddd..1fc3246b 100644 --- a/projects/ngx-launcher/src/lib/service/token-provider.ts +++ b/projects/ngx-launcher/src/lib/service/token-provider.ts @@ -10,8 +10,8 @@ export class TokenProvider { return ''; } - isPromise(token: string| Promise): token is Promise { - return (>token).then !== undefined; + isPromise(token: string | Promise): token is Promise { + return (> token).then !== undefined; } get token(): Promise { diff --git a/projects/ngx-launcher/src/lib/service/token.service.ts b/projects/ngx-launcher/src/lib/service/token.service.ts index a9329007..1c20bc8b 100644 --- a/projects/ngx-launcher/src/lib/service/token.service.ts +++ b/projects/ngx-launcher/src/lib/service/token.service.ts @@ -1,5 +1,5 @@ -import { Cluster } from '../model/cluster.model'; import { Observable } from 'rxjs'; +import { Cluster } from '../model/cluster.model'; export abstract class TokenService { abstract get clusters(): Observable; diff --git a/projects/ngx-launcher/src/lib/service/workSpaces.service.ts b/projects/ngx-launcher/src/lib/service/workSpaces.service.ts deleted file mode 100644 index 0b246c10..00000000 --- a/projects/ngx-launcher/src/lib/service/workSpaces.service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Observable } from 'rxjs'; -import { WorkspaceLinks } from '../model/workspace.model'; - -/** - * Abstract work space services - */ -export abstract class WorkSpacesService { - -/** - * Create a workspace for given codebase ID - * - * @param codeBaseId The ID associated with the given workspace - * @returns {Observable} - */ -abstract createWorkSpace(codeBaseId: string): Observable; -} diff --git a/projects/ngx-launcher/src/lib/shared/button-next-step.component.ts b/projects/ngx-launcher/src/lib/shared/button-next-step.component.ts new file mode 100644 index 00000000..f0de41fa --- /dev/null +++ b/projects/ngx-launcher/src/lib/shared/button-next-step.component.ts @@ -0,0 +1,32 @@ +import { Component, Input } from '@angular/core'; +import { Broadcaster } from 'ngx-base'; + +@Component({ + selector: 'f8launcher-button-next-step', + template: ` +
+
+ +
+
+ ` +}) +export class ButtonNextStepComponent { + @Input() + disabled: boolean; + + @Input() + navFromId: string; + + constructor(private broadcaster: Broadcaster) {} + + navToStep() { + this.broadcaster.broadcast('navigate-from', this.navFromId); + } +} diff --git a/projects/ngx-launcher/src/lib/shared/project-name.validator.ts b/projects/ngx-launcher/src/lib/shared/project-name.validator.ts index 95ada94f..331ab7d0 100644 --- a/projects/ngx-launcher/src/lib/shared/project-name.validator.ts +++ b/projects/ngx-launcher/src/lib/shared/project-name.validator.ts @@ -1,9 +1,9 @@ import { Directive, forwardRef } from '@angular/core'; -import { NG_ASYNC_VALIDATORS, Validator, AbstractControl } from '@angular/forms'; +import { AbstractControl, NG_ASYNC_VALIDATORS, Validator } from '@angular/forms'; import { Observable } from 'rxjs'; -import { DependencyCheckService } from '../service/dependency-check.service'; import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators'; +import { DependencyCheckService } from '../service/dependency-check.service'; @Directive({ selector: '[validateProjectName]', @@ -33,7 +33,7 @@ export class ProjectNameValidatorDirective implements Validator { } else { this.dependencyCheckService.getApplicationsInASpace().subscribe(apps => { const applicationNames = apps.map( - app => app.attributes.name ? (app.attributes.name).toLowerCase() : '' + app => app.attributes.name ? ( app.attributes.name).toLowerCase() : '' ); resolve.next(applicationNames.indexOf(value) !== -1 ? this.createError('duplicate', value) : {}); }); diff --git a/projects/ngx-launcher/src/lib/shared/telemetry.decorator.ts b/projects/ngx-launcher/src/lib/shared/telemetry.decorator.ts index a6422be1..24aeef2b 100644 --- a/projects/ngx-launcher/src/lib/shared/telemetry.decorator.ts +++ b/projects/ngx-launcher/src/lib/shared/telemetry.decorator.ts @@ -1,6 +1,6 @@ +import { Injector } from '@angular/core'; import * as _ from 'lodash'; import { Broadcaster } from 'ngx-base'; -import { Injector } from '@angular/core'; import { PropertiesGetter } from './properties'; import { eventKeyMap } from './woopra-key-map'; @@ -16,11 +16,11 @@ export class StaticInjector { } export function broadcast(event: string, properties: any): MethodDecorator { - return function (target: Function, methodName: string, descriptor: any) { + return function(target: Function, methodName: string, descriptor: any) { const originalMethod = descriptor.value; - descriptor.value = function (...args: any[]) { + descriptor.value = function(...args: any[]) { const injectorInstance = StaticInjector.getInjector(); if (!injectorInstance || !injectorInstance.get(Broadcaster)) { return originalMethod.apply(this, args); diff --git a/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.html b/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.html index 7517d45e..484365f1 100644 --- a/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.html +++ b/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.html @@ -1,7 +1,7 @@
@@ -16,7 +16,7 @@
diff --git a/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.ts b/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.ts index da993631..3e20c4b1 100644 --- a/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.ts +++ b/projects/ngx-launcher/src/lib/step-indicator/step-indicator.component.ts @@ -5,10 +5,12 @@ import { OnInit, ViewEncapsulation } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; -import { Selection } from '../model/selection.model'; +import { Broadcaster } from 'ngx-base'; import { LauncherComponent } from '../launcher.component'; -import { DependencyCheckService } from '../service/dependency-check.service'; +import { DependencyCheck } from '../model/dependency-check.model'; +import { Projectile } from '../model/projectile.model'; import { broadcast } from '../shared/telemetry.decorator'; @Component({ @@ -24,14 +26,20 @@ export class StepIndicatorComponent implements OnInit { * @type {boolean} */ @Input() inProgress = false; + dependencyCheck: DependencyCheck = new DependencyCheck(); - constructor( - @Host() public launcherComponent: LauncherComponent, - private dependencyCheckService: DependencyCheckService) { + constructor(public launcherComponent: LauncherComponent, + public projectile: Projectile, + private route: ActivatedRoute, + broadcaster: Broadcaster) { + broadcaster.on('navigate-to').subscribe(id => this.navToStep(id)); + broadcaster.on('navigate-from').subscribe(id => this.navToNextStep(id)); } - ngOnInit() { - this.restoreSummary(); + ngOnInit(): void { + this.dependencyCheck = this.projectile.sharedState.state; + this.dependencyCheck.projectName = this.dependencyCheck.projectName + || this.route.snapshot.params['projectName']; } // Steps @@ -39,7 +47,11 @@ export class StepIndicatorComponent implements OnInit { /** * Navigate to next step */ + @broadcast('stepIndicatorClicked', { + 'state': 'projectile' + }) navToNextStep(fromStepId?: string): void { + this.projectile.selectedSection = fromStepId; const steps = this.launcherComponent.steps.filter(step => !step.hidden); const index = steps.findIndex(step => step.id === fromStepId); this.navToStep(steps[index + 1].id); @@ -58,15 +70,6 @@ export class StepIndicatorComponent implements OnInit { } } - @broadcast('stepIndicatorProjectInputClicked', {}) - broadcastEvent(): void { } - // Restore mission & runtime summary - private restoreSummary(): void { - const selection: Selection = this.launcherComponent.selectionParams; - if (selection === undefined) { - return; - } - this.launcherComponent.summary.dependencyCheck.projectName = selection.projectName; - } + broadcastEvent() {} } diff --git a/projects/ngx-launcher/src/lib/toast-notification/toast-notification.component.ts b/projects/ngx-launcher/src/lib/toast-notification/toast-notification.component.ts index 90c9abbe..29c682a4 100644 --- a/projects/ngx-launcher/src/lib/toast-notification/toast-notification.component.ts +++ b/projects/ngx-launcher/src/lib/toast-notification/toast-notification.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; @Component({ encapsulation: ViewEncapsulation.None, diff --git a/projects/ngx-launcher/src/public_api.ts b/projects/ngx-launcher/src/public_api.ts index adbe0bd4..af34eec1 100644 --- a/projects/ngx-launcher/src/public_api.ts +++ b/projects/ngx-launcher/src/public_api.ts @@ -3,8 +3,6 @@ */ // Launcher models -import { CatalogMission } from './lib/model/catalog.model'; - export { LauncherModule } from './lib/launcher.module'; export { Cluster } from './lib/model/cluster.model'; export { DependencyCheck } from './lib/model/dependency-check.model'; @@ -12,7 +10,7 @@ export { DependencyEditor } from './lib/model/dependency-editor/dependency-edito export { GitHubDetails } from './lib/model/github-details.model'; export { Pipeline } from './lib/model/pipeline.model'; export { Progress } from './lib/model/progress.model'; -export { Summary } from './lib/model/summary.model'; +export { Projectile } from './lib/model/projectile.model'; export { Catalog, CatalogMission, CatalogRuntime, CatalogBooster } from './lib/model/catalog.model'; export { Booster, BoosterVersion, BoosterMission, BoosterRuntime } from './lib/model/booster.model'; export { TargetEnvironment } from './lib/model/target-environment.model'; @@ -28,8 +26,6 @@ export { ProjectProgressService } from './lib/service/project-progress.service'; export { ProjectSummaryService } from './lib/service/project-summary.service'; export { TargetEnvironmentService } from './lib/service/target-environment.service'; export { TokenService } from './lib/service/token.service'; -export { CheService } from './lib/service/che.service'; -export { WorkSpacesService } from './lib/service/workSpaces.service'; // Utility Service export { AuthHelperService } from './lib/service/auth-provider.service'; @@ -37,6 +33,8 @@ export { HelperService } from './lib/service/helper.service'; export { TokenProvider } from './lib/service/token-provider'; export { Config } from './lib/service/config.component'; export { StaticInjector } from './lib/shared/telemetry.decorator'; +export { LauncherStep } from './lib/launcher-step'; +export { ReviewComponent } from './lib/review.component'; // Imported from Dependency Editor export { URLProvider, DependencyEditorTokenProvider } from './lib/launcher.module'; diff --git a/projects/ngx-launcher/src/test.ts b/projects/ngx-launcher/src/test.ts index e11ff1c9..2403c51a 100644 --- a/projects/ngx-launcher/src/test.ts +++ b/projects/ngx-launcher/src/test.ts @@ -1,8 +1,8 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files - import 'core-js/es7/reflect'; import 'zone.js/dist/zone'; import 'zone.js/dist/zone-testing'; + import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index ca3a0af5..f8d6fae7 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -2,10 +2,11 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CreateAppComponent } from './create-app/create-app.component'; +import { PipelineDemoComponent } from './create-app/pipeline-demo.component'; import { GettingStartedLauncherComponent } from './getting-started-launcher/getting-started-launcher.component'; import { GettingStartedOsioComponent } from './getting-started-osio/getting-started-osio.component'; -import { LauncherAppComponent } from './launcher-app/launcher-app.component'; import { ImportAppComponent } from './import-app/import-app.component'; +import { LauncherAppComponent } from './launcher-app/launcher-app.component'; import { WelcomeComponent } from './welcome/welcome.component'; const routes: Routes = [{ @@ -28,6 +29,10 @@ const routes: Routes = [{ path: 'createapp/:projectName', component: CreateAppComponent, pathMatch: 'full' + }, { + path: 'pipelines', + component: PipelineDemoComponent, + pathMatch: 'full' }, { path: 'importapp/:projectName', component: ImportAppComponent, @@ -47,7 +52,7 @@ const routes: Routes = [{ }]; @NgModule({ - imports: [RouterModule.forRoot(routes, { useHash: true })], + imports: [RouterModule.forRoot(routes, { useHash: true, scrollPositionRestoration: 'enabled'})], exports: [RouterModule] }) export class AppRoutingModule {} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 69b1e264..ccf2fbf3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewEncapsulation} from '@angular/core'; +import { Component, ViewEncapsulation } from '@angular/core'; /* * App Component diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 59dd73ab..79ff83e0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,18 +1,17 @@ import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { Broadcaster } from 'ngx-base'; -//import { DependencyEditorTokenProvider, URLProvider } from 'fabric8-analytics-dependency-editor'; +import { AppRoutingModule } from './app-routing.module'; // App components import { AppComponent } from './app.component'; -import { AppRoutingModule } from './app-routing.module'; // Main areas import { CreateAppComponent } from './create-app/create-app.component'; import { GettingStartedLauncherComponent } from './getting-started-launcher/getting-started-launcher.component'; import { GettingStartedOsioComponent } from './getting-started-osio/getting-started-osio.component'; -import { LauncherAppComponent } from './launcher-app/launcher-app.component'; import { ImportAppComponent } from './import-app/import-app.component'; +import { LauncherAppComponent } from './launcher-app/launcher-app.component'; import { WelcomeComponent } from './welcome/welcome.component'; import { DemoDependencyCheckService } from './service/demo-dependency-check.service'; @@ -25,13 +24,13 @@ import { DemoTargetEnvironmentService } from './service/demo-target-environment. import { DemoTokenService } from './service/demo-token.service'; import { Config } from '../../projects/ngx-launcher/src/lib/service/config.component'; -import { ForgeConfig } from './shared/forge-config'; import { FABRIC8_FORGE_API_URL } from './shared/forge-api-url'; +import { ForgeConfig } from './shared/forge-config'; import { FABRIC8_ORIGIN } from './shared/forge-origin'; import { TokenProvider } from '../../projects/ngx-launcher/src/lib/service/token-provider'; -import { MockAuthenticationService } from './shared/mock-auth.service'; import { AnalyticsUrlService } from './shared/analytics-url.service'; +import { MockAuthenticationService } from './shared/mock-auth.service'; import { HelperService } from '../../projects/ngx-launcher/src/lib/service/helper.service'; @@ -44,12 +43,9 @@ import { ProjectProgressService, ProjectSummaryService, TargetEnvironmentService, - TokenService, URLProvider, - CheService, WorkSpacesService + TokenService, URLProvider } from '../../projects/ngx-launcher/src/lib/launcher.module'; - -import { DemoCheService } from './service/demo-che.service'; -import { DemoWorkSpacesService } from './service/demo-workSpaces.service'; +import { PipelineDemoComponent } from './create-app/pipeline-demo.component'; @NgModule({ imports: [ @@ -62,6 +58,7 @@ import { DemoWorkSpacesService } from './service/demo-workSpaces.service'; declarations: [ AppComponent, CreateAppComponent, + PipelineDemoComponent, GettingStartedLauncherComponent, GettingStartedOsioComponent, ImportAppComponent, @@ -84,9 +81,7 @@ import { DemoWorkSpacesService } from './service/demo-workSpaces.service'; { provide: TokenProvider, useClass: MockAuthenticationService }, { provide: TokenService, useClass: DemoTokenService}, { provide: DependencyEditorTokenProvider, useExisting: TokenProvider }, - { provide: URLProvider, useClass: AnalyticsUrlService }, - { provide: CheService, useClass: DemoCheService }, - { provide: WorkSpacesService, useClass: DemoWorkSpacesService } + { provide: URLProvider, useClass: AnalyticsUrlService } ], bootstrap: [AppComponent] }) diff --git a/src/app/create-app/create-app.component.html b/src/app/create-app/create-app.component.html index 1283b647..098648a2 100644 --- a/src/app/create-app/create-app.component.html +++ b/src/app/create-app/create-app.component.html @@ -1,9 +1,39 @@ -
-
-
- -
+ +
+
-
+
+ + + + + + + + + + + + + + + +
+
+ diff --git a/src/app/create-app/create-app.component.ts b/src/app/create-app/create-app.component.ts index 1f6bc98a..5bb5979b 100644 --- a/src/app/create-app/create-app.component.ts +++ b/src/app/create-app/create-app.component.ts @@ -2,14 +2,16 @@ import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; @Component({ selector: 'create-app', templateUrl: './create-app.component.html' }) export class CreateAppComponent implements OnInit { - constructor(private router: Router) { + depEditorFlag = true; + codeBaseCreated = true; + constructor(private router: Router, private route: ActivatedRoute) { } ngOnInit(): void { @@ -22,4 +24,8 @@ export class CreateAppComponent implements OnInit { complete(): void { this.router.navigate(['/']); } + + createWorkSpace() { + window.open('http://che.openshift.io', '_blank'); + } } diff --git a/src/app/create-app/pipeline-demo.component.ts b/src/app/create-app/pipeline-demo.component.ts new file mode 100644 index 00000000..3bb75fc1 --- /dev/null +++ b/src/app/create-app/pipeline-demo.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + template: ` +
+ screenshot of the pipeline page + Back +
+ ` +}) +export class PipelineDemoComponent { } diff --git a/src/app/import-app/import-app.component.html b/src/app/import-app/import-app.component.html index 50e14a59..80259870 100644 --- a/src/app/import-app/import-app.component.html +++ b/src/app/import-app/import-app.component.html @@ -1,10 +1,35 @@ -
-
-
- + +
+ +
+
+
+ + + + + + + + + +
+
+
+
-
+ + diff --git a/src/app/launcher-app/launcher-app.component.html b/src/app/launcher-app/launcher-app.component.html index a9bc32a9..d855951b 100644 --- a/src/app/launcher-app/launcher-app.component.html +++ b/src/app/launcher-app/launcher-app.component.html @@ -1,9 +1,26 @@ -
-
-
- -
+ +
+
-
+
+ + + + + + + + + + + +
+ + diff --git a/src/app/service/demo-che.service.ts b/src/app/service/demo-che.service.ts deleted file mode 100644 index e9eeb92e..00000000 --- a/src/app/service/demo-che.service.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Observable, of } from 'rxjs'; -import { Che } from '../../../projects/ngx-launcher/src/lib/model/che.model'; - -/** - * Abstract Che service to get state of Che server - */ -export class DemoCheService { - - /** - * Get state of Che server - * - * @returns {Observable} - */ - getState(): Observable { - return of({ - clusterFull: false, - running: true, - multiTenant: true - }); - } -} diff --git a/src/app/service/demo-dependency-check.service.ts b/src/app/service/demo-dependency-check.service.ts index b8414202..311ff436 100644 --- a/src/app/service/demo-dependency-check.service.ts +++ b/src/app/service/demo-dependency-check.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; -import { DependencyCheckService } from '../../../projects/ngx-launcher/src/lib/service/dependency-check.service'; import { DependencyCheck } from '../../../projects/ngx-launcher/src/lib/model/dependency-check.model'; +import { DependencyCheckService } from '../../../projects/ngx-launcher/src/lib/service/dependency-check.service'; @Injectable() export class DemoDependencyCheckService implements DependencyCheckService { @@ -20,7 +20,8 @@ export class DemoDependencyCheckService implements DependencyCheckService { projectName: 'app-test-1', projectVersion: '1.0.0-SNAPSHOT', spacePath: '/myspace', - dependencySnapshot: null + dependencySnapshot: null, + targetEnvironment: location.href.indexOf('launcher') !== -1 ? undefined : 'os' }); } diff --git a/src/app/service/demo-git-provider.service.ts b/src/app/service/demo-git-provider.service.ts index 5ccb8346..037b81eb 100644 --- a/src/app/service/demo-git-provider.service.ts +++ b/src/app/service/demo-git-provider.service.ts @@ -1,13 +1,16 @@ import { Injectable } from '@angular/core'; import { EMPTY, Observable, of } from 'rxjs'; -import { GitProviderService } from '../../../projects/ngx-launcher/src/lib/service/git-provider.service'; import { GitHubDetails } from '../../../projects/ngx-launcher/src/lib/model/github-details.model'; +import { GitProviderService } from '../../../projects/ngx-launcher/src/lib/service/git-provider.service'; const GitHubMock = require('../mock/demo-git-provider.json'); // Enable Access-Conrtol-Expose-Headers for CORS test @Injectable() export class DemoGitProviderService implements GitProviderService { + + private existingRepo = ['fabric8-ui', 'fabric8-uxd', 'patternfly']; + constructor() { } @@ -46,8 +49,7 @@ export class DemoGitProviderService implements GitProviderService { * @returns {Observable} True if GitHub repo exists */ isGitHubRepo(org: string, repoName: string): Observable { - const result = (org === 'patternfly' && repoName === 'patternfly'); // Simulate a existing repo - return of(result); + return of(this.existingRepo.indexOf(repoName) != -1); } /** @@ -56,30 +58,18 @@ export class DemoGitProviderService implements GitProviderService { * @param {string} org The GitHub org (e.g., fabric8-launcher/ngx-launcher) * @returns {Observable} True if GitHub repo exists */ - getGitHubRepoList(org: string): Observable { - const repoList = ['fabric-ui', 'fabric-uxd']; - return of(repoList); + getGitHubRepoList(): Observable { + return of(this.existingRepo); } // Private private isPageRedirect(): boolean { - const result = this.getRequestParam('selection'); // simulate Github auth redirect - return (result !== null); - } - - private getRequestParam(name: string): string { - const search = (window.location.search !== undefined && window.location.search.length > 0) - ? window.location.search : window.location.href; - const param = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(search); - if (param !== null) { - return decodeURIComponent(param[1]); - } - return null; + return window.location.href.indexOf('selectedSection') !== -1; } private redirectToAuth(url: string) { - window.location.href = url; - window.location.reload(true); + window.location.replace(url); + window.location.reload(); } } diff --git a/src/app/service/demo-mission-runtime.service.ts b/src/app/service/demo-mission-runtime.service.ts index 4d947baa..3a073175 100644 --- a/src/app/service/demo-mission-runtime.service.ts +++ b/src/app/service/demo-mission-runtime.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; -import { MissionRuntimeService } from '../../../projects/ngx-launcher/src/lib/service/mission-runtime.service'; import { Catalog, CatalogBooster } from '../../../projects/ngx-launcher/src/lib/model/catalog.model'; +import { MissionRuntimeService } from '../../../projects/ngx-launcher/src/lib/service/mission-runtime.service'; const osioMockData = require('../mock/demo-catalog-osio.json') as Catalog; const launchMockData = require('../mock/demo-catalog-launch.json') as Catalog; @@ -26,7 +26,7 @@ export class DemoMissionRuntimeService extends MissionRuntimeService { mock.runtimes.forEach((r) => { r.versions.forEach((v) => { - const run = { + const run = { name: 'Blank Mission', description: 'Blank mission flow', metadata: null, diff --git a/src/app/service/demo-pipeline.service.ts b/src/app/service/demo-pipeline.service.ts index 894a930d..30906ed8 100644 --- a/src/app/service/demo-pipeline.service.ts +++ b/src/app/service/demo-pipeline.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; -import { PipelineService } from '../../../projects/ngx-launcher/src/lib/service/pipeline.service'; import { Pipeline } from '../../../projects/ngx-launcher/src/lib/model/pipeline.model'; +import { PipelineService } from '../../../projects/ngx-launcher/src/lib/service/pipeline.service'; const MockPipeline = require('../mock/demo-pipeline.json'); diff --git a/src/app/service/demo-project-progress.service.ts b/src/app/service/demo-project-progress.service.ts index a2ceefdf..006ccfd7 100644 --- a/src/app/service/demo-project-progress.service.ts +++ b/src/app/service/demo-project-progress.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { timer, Subject, Subscription } from 'rxjs'; +import { Subject, Subscription, timer } from 'rxjs'; import { ProjectProgressService } from '../../../projects/ngx-launcher/src/lib/service/project-progress.service'; const PROGRESS_ERROR = [ @@ -15,7 +15,7 @@ const PROGRESS_ERROR = [ data: { error: 'Failed to create the Openshift application' } - }, + } ]; const PROGRESS_RETRY = [ diff --git a/src/app/service/demo-project-summary.service.ts b/src/app/service/demo-project-summary.service.ts index 6485b6e3..9386aa92 100644 --- a/src/app/service/demo-project-summary.service.ts +++ b/src/app/service/demo-project-summary.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; +import { Projectile } from 'projects/ngx-launcher/src/lib/model/projectile.model'; import { Observable, of } from 'rxjs'; import { ProjectSummaryService } from '../../../projects/ngx-launcher/src/lib/service/project-summary.service'; -import { Summary } from '../../../projects/ngx-launcher/src/lib/model/summary.model'; @Injectable() export class DemoProjectSummaryService implements ProjectSummaryService { - setup(summary: Summary, retry?: number): Observable { + setup(summary: Projectile, retry?: number): Observable { if (window.location.href.indexOf('import') !== -1) { return of({ 'uuid_link': 'http://import-link.com/', diff --git a/src/app/service/demo-target-environment.service.ts b/src/app/service/demo-target-environment.service.ts index abecff28..4d862c17 100644 --- a/src/app/service/demo-target-environment.service.ts +++ b/src/app/service/demo-target-environment.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { Observable, from } from 'rxjs'; -import { TargetEnvironmentService, TargetEnvironment } from '../../../projects/ngx-launcher/src/lib/launcher.module'; +import { from, Observable } from 'rxjs'; +import { TargetEnvironment, TargetEnvironmentService } from '../../../projects/ngx-launcher/src/lib/launcher.module'; const mockTargetEnvironmments = require('../mock/demo-target-environment.json'); diff --git a/src/app/service/demo-token.service.ts b/src/app/service/demo-token.service.ts index f8a6d763..e580fa63 100644 --- a/src/app/service/demo-token.service.ts +++ b/src/app/service/demo-token.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; -import { TokenService } from '../../../projects/ngx-launcher/src/lib/service/token.service'; -import { Cluster } from '../../../projects/ngx-launcher/src/lib/model/cluster.model'; import { delay } from 'rxjs/operators'; +import { Cluster } from '../../../projects/ngx-launcher/src/lib/model/cluster.model'; +import { TokenService } from '../../../projects/ngx-launcher/src/lib/service/token.service'; const mockClusters = require('../mock/demo-token.json'); @Injectable() diff --git a/src/app/service/demo-workSpaces.service.ts b/src/app/service/demo-workSpaces.service.ts deleted file mode 100644 index f916467c..00000000 --- a/src/app/service/demo-workSpaces.service.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Observable, of } from 'rxjs'; -import { WorkspaceLinks } from '../../../projects/ngx-launcher/src/lib/model/workspace.model'; - -/** - * Abstract work space services - */ -export class DemoWorkSpacesService { - - /** - * Create a workspace for given codebase ID - * - * @param codeBaseId The ID associated with the given workspace - * @returns {Observable} - */ - createWorkSpace(codeBaseId: string): Observable { - return of({ - links: { - open: 'che.openshift.io' - } - }); - } -} diff --git a/src/app/shared/mock-auth.service.ts b/src/app/shared/mock-auth.service.ts index 11ea1cc8..7095eb20 100644 --- a/src/app/shared/mock-auth.service.ts +++ b/src/app/shared/mock-auth.service.ts @@ -1,12 +1,12 @@ -import {Injectable} from '@angular/core'; +import { Injectable } from '@angular/core'; @Injectable() export class MockAuthenticationService { getToken(): string | Promise { return ''; } - isPromise(token: string| Promise): token is Promise { - return (>token).then !== undefined; + isPromise(token: string | Promise): token is Promise { + return (> token).then !== undefined; } get token(): Promise { diff --git a/src/assets/dummy-pipeline-page.png b/src/assets/dummy-pipeline-page.png new file mode 100644 index 00000000..c38291bb Binary files /dev/null and b/src/assets/dummy-pipeline-page.png differ diff --git a/src/polyfills.ts b/src/polyfills.ts index d310405a..d12b6ee6 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -74,7 +74,6 @@ import 'core-js/es7/reflect'; import 'zone.js/dist/zone'; // Included with Angular CLI. - /*************************************************************************************************** * APPLICATION IMPORTS */ diff --git a/src/test.ts b/src/test.ts index 16317897..36087583 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,6 +1,6 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files - import 'zone.js/dist/zone-testing'; + import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, diff --git a/tslint.json b/tslint.json index 3ea984c7..42d8b2fc 100644 --- a/tslint.json +++ b/tslint.json @@ -2,129 +2,144 @@ "rulesDirectory": [ "node_modules/codelyzer" ], + "linterOptions": { + "exclude": [ + "node_modules/*", + "dist/*", + "runtime/" + ] + }, "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [ + // -------------- Start of Angular rules ------------ + "angular-whitespace": [ true, - "check-space" + "check-interpolation", + "check-semicolon" ], - "curly": true, - "deprecation": { - "severity": "warn" - }, - "eofline": true, - "forin": true, - "import-blacklist": [ + "banana-in-box": true, + "templates-no-negated-async": true, + "max-line-length": [true, 120], + "no-life-cycle-call": true, + "prefer-output-readonly": true, + "no-conflicting-life-cycle-hooks": true, + "enforce-component-selector": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-attribute-parameter-decorator": true, + "no-output-named-after-standard-event": true, + "no-forward-ref": true, + "no-unused-css": true, + "use-life-cycle-interface": true, + "contextual-life-cycle": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "pipe-impure": true, + // -------------- End of Angular rules ------------ + "typedef-whitespace": [ true, - "rxjs/Rx" + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace" + } ], - "import-spacing": true, + + "curly": true, + "no-duplicate-super": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-eval": true, + "no-invalid-template-strings": false, + "no-misused-new": true, + "no-return-await": true, + "no-unsafe-finally": true, + "eofline": true, "indent": [ true, - "spaces" - ], - "interface-over-type-literal": true, - "label-position": true, - "max-line-length": [ - true, - 140 + "spaces", + 2 ], - "member-access": false, - "member-ordering": [ + "trailing-comma": [ true, { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] + "multiline": "never", + "singleline": "never", + "esSpecCompliant": true } ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ + "no-consecutive-blank-lines": [ true, - "debug", - "info", - "time", - "timeEnd", - "trace" + 2 ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": [ - true, - "ignore-params" - ], - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, + "no-irregular-whitespace": true, "no-trailing-whitespace": true, "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-use-before-declare": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, + "no-unnecessary-qualifier": true, + "object-literal-key-quotes": [ + false, + "as-needed" + ], "one-line": [ true, - "check-open-brace", "check-catch", "check-else", + "check-finally", + "check-open-brace", "check-whitespace" ], - "prefer-const": true, + "ordered-imports": [ + true, + { + "import-sources-order": "case-insensitive", + "named-imports-order": "case-insensitive" + } + ], "quotemark": [ true, - "single" + "single", + "avoid-escape" ], - "radix": true, "semicolon": [ true, "always" ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ + "space-before-function-paren": [ true, { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" + "anonymous": "never", + "asyncArrow": "always", + "constructor": "never", + "method": "never", + "named": "never" } ], - "unified-signatures": true, - "variable-name": false, + "space-within-parens": [ + true, + 0 + ], "whitespace": [ true, "check-branch", "check-decl", "check-operator", + "check-module", "check-separator", - "check-type" - ], - "no-output-on-prefix": true, - "use-input-property-decorator": true, - "use-output-property-decorator": true, - "use-host-property-decorator": true, - "no-input-rename": true, - "no-output-rename": true, - "use-life-cycle-interface": true, - "use-pipe-transform-interface": true, - "component-class-suffix": true, - "directive-class-suffix": true + "check-type", + "check-typecast", + "check-preblock", + "check-type-operator", + "check-rest-spread" + ] } -} +} \ No newline at end of file