From 26af455a6cb6f720469063a3e13e47664fefc088 Mon Sep 17 00:00:00 2001 From: May Zhang Date: Fri, 26 Mar 2021 09:36:55 -0700 Subject: [PATCH] fix: global project info is missing in UI (#5861) Signed-off-by: May Zhang --- server/application/application.go | 2 +- .../project-details/project-details.tsx | 20 ++++++ .../project-details/resource-lists-panel.tsx | 69 ++++++++++++++++++- 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/server/application/application.go b/server/application/application.go index b7f011e771..12b60b3efe 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -736,7 +736,7 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati } func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Application, validate bool) error { - proj, err := s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Get(ctx, app.Spec.GetProject(), metav1.GetOptions{}) + proj, err := argo.GetAppProject(&app.Spec, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr) if err != nil { if apierr.IsNotFound(err) { return status.Errorf(codes.InvalidArgument, "application references project %s which does not exist", app.Spec.Project) diff --git a/ui/src/app/settings/components/project-details/project-details.tsx b/ui/src/app/settings/components/project-details/project-details.tsx index eb44d703b0..037f72ee2e 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -50,6 +50,26 @@ function loadGlobal(name: string) { merged.clusterResourceWhitelist = merged.clusterResourceWhitelist.concat(proj.spec.clusterResourceWhitelist || []); merged.namespaceResourceBlacklist = merged.namespaceResourceBlacklist.concat(proj.spec.namespaceResourceBlacklist || []); merged.namespaceResourceWhitelist = merged.namespaceResourceWhitelist.concat(proj.spec.namespaceResourceWhitelist || []); + merged.sourceRepos = merged.sourceRepos.concat(proj.spec.sourceRepos || []); + merged.destinations = merged.destinations.concat(proj.spec.destinations || []); + + merged.sourceRepos = merged.sourceRepos.filter((item, index) => { + return ( + index === + merged.sourceRepos.findIndex(obj => { + return obj === item; + }) + ); + }); + + merged.destinations = merged.destinations.filter((item, index) => { + return ( + index === + merged.destinations.findIndex(obj => { + return obj.server === item.server && obj.namespace === item.namespace; + }) + ); + }); merged.clusterResourceBlacklist = merged.clusterResourceBlacklist.filter((item, index) => { return ( diff --git a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx index c1224669ee..2e5c1d1fed 100644 --- a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx +++ b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import {FormApi} from 'react-form'; import {EditablePanel} from '../../../shared/components'; -import {GroupKind, Groups, Project, ProjectSpec, ResourceKinds} from '../../../shared/models'; +import {ApplicationDestination, GroupKind, Groups, Project, ProjectSpec, ResourceKinds} from '../../../shared/models'; function removeEl(items: any[], index: number) { return items.slice(0, index).concat(items.slice(index + 1)); @@ -69,6 +69,71 @@ function viewList(type: field, proj: Project) { ); } +const sourceReposInfoByField: {[type: string]: {title: string; helpText: string}} = { + sourceRepos: { + title: 'source repositories', + helpText: 'Git repositories where application manifests are permitted to be retrieved from' + } +}; + +function viewSourceReposInfoList(type: field, proj: Project) { + const info = sourceReposInfoByField[type]; + const list = proj.spec[type] as Array; + return ( + +

+ {info.title} {helpTip(info.helpText)} +

+ {(list || []).length > 0 ? ( + + {list.map((repo, i) => ( +
+
{repo}
+
+ ))} +
+ ) : ( +

The {info.title} is empty

+ )} +
+ ); +} + +const destinationsInfoByField: {[type: string]: {title: string; helpText: string}} = { + destinations: { + title: 'destinations', + helpText: 'Cluster and namespaces where applications are permitted to be deployed to' + } +}; + +function viewDestinationsInfoList(type: field, proj: Project) { + const info = destinationsInfoByField[type]; + const list = proj.spec[type] as Array; + return ( + +

+ {info.title} {helpTip(info.helpText)} +

+ {(list || []).length > 0 ? ( + +
+
Server
+
Namespace
+
+ {list.map((destination, i) => ( +
+
{destination.server}
+
{destination.namespace}
+
+ ))} +
+ ) : ( +

The {info.title} is empty

+ )} +
+ ); +} + function editList(type: field, formApi: FormApi) { const info = infoByField[type]; @@ -114,6 +179,8 @@ export const ResourceListsPanel = ({proj, saveProject, title}: {proj: Project; t {Object.keys(infoByField).map(key => ( {viewList(key as field, proj)} ))} + {!proj.metadata && Object.keys(sourceReposInfoByField).map(key => {viewSourceReposInfoList(key as field, proj)})} + {!proj.metadata && Object.keys(destinationsInfoByField).map(key => {viewDestinationsInfoList(key as field, proj)})} } edit={