From 38da0f01c09f1556c78ffb59bb4edc1c7cbadd6d Mon Sep 17 00:00:00 2001 From: Guiheux Steven Date: Wed, 17 Jun 2020 17:09:50 +0200 Subject: [PATCH] fix(ui): load project deps+ fix loading application and pipeline after creation (#5258) --- sdk/project.go | 2 +- ui/src/app/store/applications.state.ts | 2 + ui/src/app/store/pipelines.state.ts | 2 + ui/src/app/store/project.action.ts | 4 - ui/src/app/store/project.state.ts | 36 ++--- .../home/filter/home.filter.component.ts | 4 +- .../application/application.list.component.ts | 22 ++- .../show/application/application.list.html | 3 +- .../environment/environment.list.component.ts | 20 ++- .../show/environment/environment.list.html | 4 +- .../show/pipeline/pipeline.list.component.ts | 71 ++++++---- .../project/show/pipeline/pipeline.list.html | 3 +- .../views/project/show/project.component.ts | 21 +-- .../show/workflow/workflow.list.component.ts | 125 ++++++++++-------- .../project/show/workflow/workflow.list.html | 3 +- 15 files changed, 172 insertions(+), 150 deletions(-) diff --git a/sdk/project.go b/sdk/project.go index 7b1e1ea97d..eb20b338a9 100644 --- a/sdk/project.go +++ b/sdk/project.go @@ -43,7 +43,7 @@ type Project struct { Labels []Label `json:"labels,omitempty" yaml:"labels,omitempty" db:"-" cli:"-"` Permissions Permissions `json:"permissions" yaml:"-" db:"-" cli:"-"` Metadata Metadata `json:"metadata" yaml:"metadata" db:"metadata" cli:"-"` - Keys []ProjectKey `json:"keys" yaml:"keys" db:"-" cli:"-"` + Keys []ProjectKey `json:"keys,omitempty" yaml:"keys" db:"-" cli:"-"` VCSServers []ProjectVCSServerLink `json:"vcs_servers" yaml:"vcs_servers" db:"-" cli:"-"` Integrations []ProjectIntegration `json:"integrations" yaml:"integrations" db:"-" cli:"-"` Features map[string]bool `json:"features" yaml:"features" db:"-" cli:"-"` diff --git a/ui/src/app/store/applications.state.ts b/ui/src/app/store/applications.state.ts index 799340cc27..62fa533cf1 100644 --- a/ui/src/app/store/applications.state.ts +++ b/ui/src/app/store/applications.state.ts @@ -65,6 +65,8 @@ export class ApplicationsState { ctx.setState({ ...state, currentProjectKey: action.payload.projectKey, + editMode: false, + editApplication: null, application: app, loading: false }); diff --git a/ui/src/app/store/pipelines.state.ts b/ui/src/app/store/pipelines.state.ts index ae97d2fb7c..d5dec5d48f 100644 --- a/ui/src/app/store/pipelines.state.ts +++ b/ui/src/app/store/pipelines.state.ts @@ -56,6 +56,8 @@ export class PipelinesState { ctx.setState({ ...state, currentProjectKey: action.payload.projectKey, + editPipeline: null, + editMode: false, pipeline: pip, loading: false, }); diff --git a/ui/src/app/store/project.action.ts b/ui/src/app/store/project.action.ts index 11c46f7a7a..ff1be1408a 100644 --- a/ui/src/app/store/project.action.ts +++ b/ui/src/app/store/project.action.ts @@ -215,10 +215,6 @@ export class ResyncEnvironmentsInProject { static readonly type = '[Project] Resync Environments in Project'; constructor(public payload: { projectKey: string }) { } } -export class FetchEnvironmentsInProject { - static readonly type = '[Project] Fetch Environments in Project'; - constructor(public payload: { projectKey: string }) { } -} export class AddEnvironmentKey { static readonly type = '[Project] Add Environment Key in Project'; constructor(public payload: { projectKey: string, envName: string, key: Key }) { } diff --git a/ui/src/app/store/project.state.ts b/ui/src/app/store/project.state.ts index 442e4a0708..9795aa4bf9 100644 --- a/ui/src/app/store/project.state.ts +++ b/ui/src/app/store/project.state.ts @@ -92,14 +92,7 @@ export class ProjectState { }); } - return ctx.dispatch(new ProjectAction.ResyncProject(action.payload)); - } - - @Action(ProjectAction.ResyncProject) - resync(ctx: StateContext, action: ProjectAction.ResyncProject) { - let params = new HttpParams(); let opts = action.payload.opts; - if (Array.isArray(opts) && opts.length) { opts = opts.concat([ new LoadOpts('withGroups', 'groups'), @@ -111,11 +104,18 @@ export class ProjectState { new LoadOpts('withPermission', 'permission') ]; } + opts.push(new LoadOpts('withIntegrations', 'integrations')); opts.push(new LoadOpts('withLabels', 'labels')); + + return ctx.dispatch(new ProjectAction.ResyncProject({projectKey: action.payload.projectKey, opts: opts})); + } + + @Action(ProjectAction.ResyncProject) + resync(ctx: StateContext, action: ProjectAction.ResyncProject) { + let params = new HttpParams(); + let opts = action.payload.opts; opts.push(new LoadOpts('withFeatures', 'features')); - opts.push(new LoadOpts('withIntegrations', 'integrations')); opts.forEach((opt) => params = params.append(opt.queryParam, 'true')); - const state = ctx.getState(); ctx.setState({ ...state, @@ -856,9 +856,6 @@ export class ProjectState { fetchEnvironment(ctx: StateContext, action: ProjectAction.FetchEnvironmentInProject) { const state = ctx.getState(); - if (state.currentProjectKey && state.currentProjectKey !== action.payload.projectKey) { - ctx.dispatch(new ProjectAction.FetchProject({ projectKey: action.payload.projectKey, opts: [] })); - } return this._envService.getEnvironment(action.payload.projectKey, action.payload.envName) .pipe(tap((environment: Environment) => { let envs = state.project.environments; @@ -931,21 +928,6 @@ export class ProjectState { })); } - @Action(ProjectAction.FetchEnvironmentsInProject) - fetchEnvironments(ctx: StateContext, action: ProjectAction.FetchEnvironmentsInProject) { - const state = ctx.getState(); - - if (state.currentProjectKey && state.currentProjectKey === action.payload.projectKey && - state.project && state.project.key && state.project.environments) { - return ctx.dispatch(new ProjectAction.LoadProject(state.project)); - } - if (state.currentProjectKey && state.currentProjectKey !== action.payload.projectKey) { - ctx.dispatch(new ProjectAction.FetchProject({ projectKey: action.payload.projectKey, opts: [] })); - } - - return ctx.dispatch(new ProjectAction.ResyncEnvironmentsInProject(action.payload)); - } - @Action(ProjectAction.LoadEnvironmentsInProject) loadEnvironments(ctx: StateContext, action: ProjectAction.LoadEnvironmentsInProject) { const state = ctx.getState(); diff --git a/ui/src/app/views/home/filter/home.filter.component.ts b/ui/src/app/views/home/filter/home.filter.component.ts index 869ba4ef26..07487ef083 100644 --- a/ui/src/app/views/home/filter/home.filter.component.ts +++ b/ui/src/app/views/home/filter/home.filter.component.ts @@ -7,7 +7,7 @@ import { ProjectStore } from 'app/service/project/project.store'; import { TimelineStore } from 'app/service/timeline/timeline.store'; import { AutoUnsubscribe } from 'app/shared/decorator/autoUnsubscribe'; import { ToastService } from 'app/shared/toast/ToastService'; -import { ResyncProject } from 'app/store/project.action'; +import { FetchProject } from 'app/store/project.action'; import { ProjectState, ProjectStateModel } from 'app/store/project.state'; import cloneDeep from 'lodash-es/cloneDeep'; import { finalize, flatMap } from 'rxjs/operators'; @@ -93,7 +93,7 @@ export class HomeFilterComponent { let opts = new Array(); opts.push(new LoadOpts('withWorkflowNames', 'workflow_names')); - this.store.dispatch(new ResyncProject({ + this.store.dispatch(new FetchProject({ projectKey: projFilter.key, opts })).pipe( diff --git a/ui/src/app/views/project/show/application/application.list.component.ts b/ui/src/app/views/project/show/application/application.list.component.ts index 20061f5f72..96ef47fbf7 100644 --- a/ui/src/app/views/project/show/application/application.list.component.ts +++ b/ui/src/app/views/project/show/application/application.list.component.ts @@ -1,5 +1,8 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { IdName, Project } from 'app/model/project.model'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { IdName, LoadOpts, Project } from 'app/model/project.model'; +import { ResyncProject } from 'app/store/project.action'; +import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-project-applications', @@ -7,7 +10,7 @@ import { IdName, Project } from 'app/model/project.model'; styleUrls: ['./application.list.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class ProjectApplicationListComponent { +export class ProjectApplicationListComponent implements OnInit { @Input() set project(project: Project) { @@ -34,8 +37,19 @@ export class ProjectApplicationListComponent { _project: Project; _filter = ''; + loading = true; filteredApplications: Array = []; - constructor() { } + constructor(private store: Store, private _cd: ChangeDetectorRef) {} + + ngOnInit(): void { + let opts: Array = [new LoadOpts('withApplicationNames', 'application_names')]; + this.store.dispatch(new ResyncProject({ projectKey: this.project.key, opts: opts })) + .pipe(finalize(() => { + this.loading = false; + this._cd.markForCheck(); + })) + .subscribe(); + } } diff --git a/ui/src/app/views/project/show/application/application.list.html b/ui/src/app/views/project/show/application/application.list.html index 9f58f73387..360b40f598 100644 --- a/ui/src/app/views/project/show/application/application.list.html +++ b/ui/src/app/views/project/show/application/application.list.html @@ -1,4 +1,4 @@ -
+

{{ 'project_applications_list' | translate }}

@@ -38,3 +38,4 @@

{{ 'project_applications_list' | translate }}

+
{{'common_loading' | translate}}
diff --git a/ui/src/app/views/project/show/environment/environment.list.component.ts b/ui/src/app/views/project/show/environment/environment.list.component.ts index 115ed49ae0..b29480d247 100644 --- a/ui/src/app/views/project/show/environment/environment.list.component.ts +++ b/ui/src/app/views/project/show/environment/environment.list.component.ts @@ -1,5 +1,8 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { IdName, Project } from 'app/model/project.model'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { IdName, LoadOpts, Project } from 'app/model/project.model'; +import { ResyncProject } from 'app/store/project.action'; +import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-project-environments', @@ -7,7 +10,7 @@ import { IdName, Project } from 'app/model/project.model'; styleUrls: ['./environment.list.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class ProjectEnvironmentListComponent { +export class ProjectEnvironmentListComponent implements OnInit { @Input() set project(project: Project) { @@ -36,8 +39,17 @@ export class ProjectEnvironmentListComponent { _filter = ''; filteredEnvironments: Array = []; + loading = true; - constructor() { + constructor(private store: Store, private _cd: ChangeDetectorRef) {} + ngOnInit(): void { + let opts: Array = [new LoadOpts('withEnvironmentNames', 'environment_names')]; + this.store.dispatch(new ResyncProject({ projectKey: this.project.key, opts: opts })) + .pipe(finalize(() => { + this.loading = false; + this._cd.markForCheck(); + })) + .subscribe(); } } diff --git a/ui/src/app/views/project/show/environment/environment.list.html b/ui/src/app/views/project/show/environment/environment.list.html index 2ebd3eb411..597c17a174 100644 --- a/ui/src/app/views/project/show/environment/environment.list.html +++ b/ui/src/app/views/project/show/environment/environment.list.html @@ -1,4 +1,4 @@ -
+

{{ 'project_env_list_title' | translate }}

@@ -38,3 +38,5 @@

{{ 'project_env_list_title' | translate }}

+
{{'common_loading' | translate}}
+ diff --git a/ui/src/app/views/project/show/pipeline/pipeline.list.component.ts b/ui/src/app/views/project/show/pipeline/pipeline.list.component.ts index 2cafaf055d..f28b2ff611 100644 --- a/ui/src/app/views/project/show/pipeline/pipeline.list.component.ts +++ b/ui/src/app/views/project/show/pipeline/pipeline.list.component.ts @@ -1,5 +1,8 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { IdName, Project } from 'app/model/project.model'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { IdName, LoadOpts, Project } from 'app/model/project.model'; +import { ResyncProject } from 'app/store/project.action'; +import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-project-pipelines', @@ -7,37 +10,49 @@ import { IdName, Project } from 'app/model/project.model'; styleUrls: ['./pipeline.list.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class ProjectPipelinesComponent { - - @Input() - set project(project: Project) { - this._project = project; - if (project.pipeline_names) { - let filter = this.filter.toLowerCase(); - this.filteredPipelines = project.pipeline_names.filter((pip) => pip.name.toLowerCase().indexOf(filter) !== -1); +export class ProjectPipelinesComponent implements OnInit { + + @Input() + set project(project: Project) { + this._project = project; + if (project.pipeline_names) { + let filter = this.filter.toLowerCase(); + this.filteredPipelines = project.pipeline_names.filter((pip) => pip.name.toLowerCase().indexOf(filter) !== -1); + } } - } - get project(): Project { - return this._project; - } - - set filter(filter: string) { - this._filter = filter; - if (this.project.pipeline_names) { - let filterLower = filter.toLowerCase(); - this.filteredPipelines = this.project.pipeline_names.filter((pip) => pip.name.toLowerCase().indexOf(filterLower) !== -1); + + get project(): Project { + return this._project; } - } - get filter(): string { - return this._filter; - } - _project: Project; - _filter = ''; + set filter(filter: string) { + this._filter = filter; + if (this.project.pipeline_names) { + let filterLower = filter.toLowerCase(); + this.filteredPipelines = this.project.pipeline_names.filter((pip) => pip.name.toLowerCase().indexOf(filterLower) !== -1); + } + } - filteredPipelines: Array = []; + get filter(): string { + return this._filter; + } - constructor() { + _project: Project; + _filter = ''; + + filteredPipelines: Array = []; + loading = true; + + constructor(private store: Store, private _cd: ChangeDetectorRef) { + } + ngOnInit(): void { + let opts: Array = [new LoadOpts('withPipelineNames', 'pipeline_names')]; + this.store.dispatch(new ResyncProject({projectKey: this.project.key, opts: opts})) + .pipe(finalize(() => { + this.loading = false; + this._cd.markForCheck(); + })) + .subscribe(); } } diff --git a/ui/src/app/views/project/show/pipeline/pipeline.list.html b/ui/src/app/views/project/show/pipeline/pipeline.list.html index 1b59aae218..460bf4f4af 100644 --- a/ui/src/app/views/project/show/pipeline/pipeline.list.html +++ b/ui/src/app/views/project/show/pipeline/pipeline.list.html @@ -1,4 +1,4 @@ -
+

{{ 'project_pipelines_list' | translate }}

@@ -37,3 +37,4 @@

{{ 'project_pipelines_list' | translate }}

+
{{'common_loading' | translate}}
diff --git a/ui/src/app/views/project/show/project.component.ts b/ui/src/app/views/project/show/project.component.ts index c1d097a9a4..2ffc3f7514 100644 --- a/ui/src/app/views/project/show/project.component.ts +++ b/ui/src/app/views/project/show/project.component.ts @@ -149,28 +149,9 @@ export class ProjectShowComponent implements OnInit { } refreshDatas(key: string): void { - let opts = [ - new LoadOpts('withApplicationNames', 'application_names'), - new LoadOpts('withPipelineNames', 'pipeline_names'), - new LoadOpts('withWorkflowNames', 'workflow_names'), - new LoadOpts('withEnvironmentNames', 'environment_names'), - new LoadOpts('withLabels', 'labels'), - ]; - - if (this.selectedTab) { - switch (this.selectedTab.key) { - case 'variables': - opts.push(new LoadOpts('withVariables', 'variables')); - break; - case 'permissions': - opts.push(new LoadOpts('withEnvironments', 'environments')); - break; - } - } - + let opts = [new LoadOpts('withLabels', 'labels')]; this._store.dispatch(new FetchProject({ projectKey: key, opts })) .subscribe(null, () => this._router.navigate(['/home'])); - } updateFav() { diff --git a/ui/src/app/views/project/show/workflow/workflow.list.component.ts b/ui/src/app/views/project/show/workflow/workflow.list.component.ts index 078287e34e..5581ac342b 100644 --- a/ui/src/app/views/project/show/workflow/workflow.list.component.ts +++ b/ui/src/app/views/project/show/workflow/workflow.list.component.ts @@ -1,7 +1,10 @@ -import { ChangeDetectionStrategy, Component, Input, OnInit, ViewChild } from '@angular/core'; -import { IdName, Label, Project } from 'app/model/project.model'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewChild } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { IdName, Label, LoadOpts, Project } from 'app/model/project.model'; import { ProjectStore } from 'app/service/project/project.store'; import { LabelsEditComponent } from 'app/shared/labels/edit/labels.edit.component'; +import { ResyncProject } from 'app/store/project.action'; +import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-project-workflows', @@ -11,73 +14,83 @@ import { LabelsEditComponent } from 'app/shared/labels/edit/labels.edit.componen }) export class ProjectWorkflowListComponent implements OnInit { - @Input() - set project(project: Project) { - this._project = project; - if (project.workflow_names) { - let filter = this.filter.toLowerCase(); - this.filteredWorkflows = project.workflow_names.filter((wf) => wf.name.toLowerCase().indexOf(filter) !== -1); + @Input() + set project(project: Project) { + this._project = project; + if (project.workflow_names) { + let filter = this.filter.toLowerCase(); + this.filteredWorkflows = project.workflow_names.filter((wf) => wf.name.toLowerCase().indexOf(filter) !== -1); + } + if (project.labels) { + let labelFilter = this.labelFilter.toLowerCase(); + this.filteredLabels = project.labels.filter((lbl) => lbl.name.toLowerCase().indexOf(labelFilter) !== -1); + } } - if (project.labels) { - let labelFilter = this.labelFilter.toLowerCase(); - this.filteredLabels = project.labels.filter((lbl) => lbl.name.toLowerCase().indexOf(labelFilter) !== -1); + + get project(): Project { + return this._project; + } + + set filter(filter: string) { + this._filter = filter; + if (this.project.workflow_names) { + let filterLower = filter.toLowerCase(); + this.filteredWorkflows = this.project.workflow_names.filter((wf) => wf.name.toLowerCase().indexOf(filterLower) !== -1); + } + } + + get filter(): string { + return this._filter; } - } - get project(): Project { - return this._project; - } - set filter(filter: string) { - this._filter = filter; - if (this.project.workflow_names) { - let filterLower = filter.toLowerCase(); - this.filteredWorkflows = this.project.workflow_names.filter((wf) => wf.name.toLowerCase().indexOf(filterLower) !== -1); + set labelFilter(filter: string) { + this._filterLabel = filter; + if (this.project.labels) { + let filterLower = filter.toLowerCase(); + this.filteredLabels = this.project.labels.filter((lbl) => lbl.name.toLowerCase().indexOf(filterLower) !== -1); + } } - } - get filter(): string { - return this._filter; - } - set labelFilter(filter: string) { - this._filterLabel = filter; - if (this.project.labels) { - let filterLower = filter.toLowerCase(); - this.filteredLabels = this.project.labels.filter((lbl) => lbl.name.toLowerCase().indexOf(filterLower) !== -1); + get labelFilter(): string { + return this._filterLabel; } - } - get labelFilter(): string { - return this._filterLabel; - } - // Modal - @ViewChild('projectLabels') - projectLabels: LabelsEditComponent; + // Modal + @ViewChild('projectLabels') + projectLabels: LabelsEditComponent; - _project: Project; - _filter = ''; - _filterLabel = ''; + _project: Project; + _filter = ''; + _filterLabel = ''; - viewMode: 'blocs'|'labels'|'lines' = 'blocs'; - filteredWorkflows: Array = []; - filteredLabels: Array