diff --git a/packages/console/package.json b/packages/console/package.json index 251821a93..741447e1c 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -1,6 +1,6 @@ { "name": "@flyteorg/console", - "version": "0.0.9", + "version": "0.0.10", "description": "Flyteconsole main app module", "main": "./dist/index.js", "module": "./lib/index.js", diff --git a/packages/console/src/components/Project/ProjectDashboard.tsx b/packages/console/src/components/Project/ProjectDashboard.tsx index 7ce1886f1..0f29b22c4 100644 --- a/packages/console/src/components/Project/ProjectDashboard.tsx +++ b/packages/console/src/components/Project/ProjectDashboard.tsx @@ -32,8 +32,11 @@ import { useOnlyMyExecutionsFilterState } from 'components/Executions/filters/us import { WaitForData } from 'components/common/WaitForData'; import { history } from 'routes/history'; import { Routes } from 'routes/routes'; -import { compact } from 'lodash'; -import { getProjectDomainAttributes } from 'models/Project/api'; +import { compact, merge } from 'lodash'; +import { + getProjectAttributes, + getProjectDomainAttributes, +} from 'models/Project/api'; import t from './strings'; import { failedToLoadExecutionsString } from './constants'; @@ -166,7 +169,24 @@ export const ProjectDashboard: React.FC = ({ ); return projectDomainAtributes; }, - staleTime: Infinity, + }); + + const projectAttributesQuery = useQuery< + Admin.ProjectAttributesGetResponse, + Error + >({ + queryKey: ['projectAttributes', project], + queryFn: async () => { + const projectAtributes = await getProjectAttributes({ + project, + }); + queryClient.setQueryData( + ['projectAttributes', project], + projectAtributes, + ); + return projectAtributes; + }, + enabled: !projectDomainAttributesQuery.isFetching, }); const content = executionsQuery.isLoadingError ? ( @@ -191,8 +211,12 @@ export const ProjectDashboard: React.FC = ({ ); const configData = - projectDomainAttributesQuery.data?.attributes?.matchingAttributes - ?.workflowExecutionConfig ?? undefined; + merge( + projectAttributesQuery.data?.attributes?.matchingAttributes + ?.workflowExecutionConfig, + projectDomainAttributesQuery.data?.attributes?.matchingAttributes + ?.workflowExecutionConfig, + ) ?? undefined; const renderDomainSettingsSection = () => ( @@ -206,7 +230,7 @@ export const ProjectDashboard: React.FC = ({ {t('tasksTotal', numberOfTasks)} - + {renderDomainSettingsSection}
diff --git a/packages/console/src/components/Project/test/ProjectDashboard.test.tsx b/packages/console/src/components/Project/test/ProjectDashboard.test.tsx index eee1ae7c0..ecc9c299f 100644 --- a/packages/console/src/components/Project/test/ProjectDashboard.test.tsx +++ b/packages/console/src/components/Project/test/ProjectDashboard.test.tsx @@ -20,7 +20,10 @@ import { import { useUserProfile } from 'components/hooks/useUserProfile'; import { FetchableData } from 'components/hooks/types'; import { loadedFetchable } from 'components/hooks/__mocks__/fetchableData'; -import { getProjectDomainAttributes } from 'models/Project/api'; +import { + getProjectAttributes, + getProjectDomainAttributes, +} from 'models/Project/api'; import { Admin } from '@flyteorg/flyteidl-types'; import * as LocalCache from 'basics/LocalCache'; import { ProjectDashboard } from '../ProjectDashboard'; @@ -33,6 +36,31 @@ jest.mock('notistack', () => ({ })); jest.mock('models/Project/api', () => ({ + getProjectAttributes: jest.fn().mockResolvedValue(() => { + const projectAttributesMock: Admin.ProjectAttributesGetResponse = { + attributes: { + matchingAttributes: { + workflowExecutionConfig: { + maxParallelism: 1, + securityContext: { runAs: { k8sServiceAccount: 'default' } }, + rawOutputDataConfig: { + outputLocationPrefix: + 'cliOutputLocationPrefixFromProjectAttributes', + }, + annotations: { + values: { + cliAnnotationKey: 'cliAnnotationValueFromProjectAttributes', + }, + }, + labels: { + values: { cliLabelKey: 'cliLabelValueFromProjectAttributes' }, + }, + }, + }, + }, + }; + return projectAttributesMock; + }), getProjectDomainAttributes: jest.fn().mockResolvedValue(() => { const projectDomainAttributesMock: Admin.ProjectDomainAttributesDeleteResponse = { @@ -41,9 +69,6 @@ jest.mock('models/Project/api', () => ({ workflowExecutionConfig: { maxParallelism: 5, securityContext: { runAs: { k8sServiceAccount: 'default' } }, - rawOutputDataConfig: { - outputLocationPrefix: 'cliOutputLocationPrefix', - }, annotations: { values: { cliAnnotationKey: 'cliAnnotationValue' }, }, @@ -123,9 +148,17 @@ describe('ProjectDashboard', () => { it('should display domain attributes section when config was provided', async () => { const { getByText } = renderView(); + expect(getProjectAttributes).toHaveBeenCalled(); expect(getProjectDomainAttributes).toHaveBeenCalled(); await waitFor(() => { expect(getByText('Domain Settings')).toBeInTheDocument(); + expect( + getByText('cliOutputLocationPrefixFromProjectAttributes'), + ).toBeInTheDocument(); + expect(getByText('cliAnnotationKey')).toBeInTheDocument(); + expect( + getByText('cliAnnotationValueFromProjectAttributes'), + ).not.toBeInTheDocument(); }); }); diff --git a/packages/console/src/components/common/DomainSettingsSection.tsx b/packages/console/src/components/common/DomainSettingsSection.tsx index 3b11c362c..b156ae126 100644 --- a/packages/console/src/components/common/DomainSettingsSection.tsx +++ b/packages/console/src/components/common/DomainSettingsSection.tsx @@ -55,11 +55,11 @@ export const DomainSettingsSection = ({ return null; } - const role = configData.securityContext?.runAs?.iamRole || t('inherited'); + const role = configData.securityContext?.runAs?.iamRole || t('noValue'); const serviceAccount = - configData.securityContext?.runAs?.k8sServiceAccount || t('inherited'); + configData.securityContext?.runAs?.k8sServiceAccount || t('noValue'); const rawData = - configData.rawOutputDataConfig?.outputLocationPrefix || t('inherited'); + configData.rawOutputDataConfig?.outputLocationPrefix || t('noValue'); const maxParallelism = configData.maxParallelism || undefined; return ( @@ -101,7 +101,7 @@ export const DomainSettingsSection = ({ {configData.labels?.values ? ( ) : ( - t('inherited') + t('noValue') )}
@@ -109,7 +109,7 @@ export const DomainSettingsSection = ({ {configData.annotations?.values ? ( ) : ( - t('inherited') + t('noValue') )}
@@ -122,7 +122,7 @@ export const DomainSettingsSection = ({ {t('maxParallelismHeader')}

- {maxParallelism ?? t('inherited')} + {maxParallelism ?? t('noValue')}
diff --git a/packages/console/src/components/common/strings.ts b/packages/console/src/components/common/strings.ts index 3e8e84cce..ae784c9d1 100644 --- a/packages/console/src/components/common/strings.ts +++ b/packages/console/src/components/common/strings.ts @@ -12,6 +12,7 @@ const str = { securityContextHeader: 'Security Context', serviceAccountHeader: 'Service Account', noMatchingResults: 'No matching results', + noValue: '-', missingUnionListOfSubType: 'Unexpected missing type for union', missingMapSubType: 'Unexpected missing subtype for map', mapMissingMapProperty: 'Map literal missing `map` property', diff --git a/packages/console/src/components/common/test/DomainSettingsSection.test.tsx b/packages/console/src/components/common/test/DomainSettingsSection.test.tsx index 16f9efe31..ca6ae8dde 100644 --- a/packages/console/src/components/common/test/DomainSettingsSection.test.tsx +++ b/packages/console/src/components/common/test/DomainSettingsSection.test.tsx @@ -55,7 +55,7 @@ describe('DomainSettingsSection', () => { const tables = queryAllByRole('table'); expect(tables).toHaveLength(2); // should display a placeholder text, as role was not passed - const emptyRole = queryByText('Inherits from project level values'); + const emptyRole = queryByText('-'); expect(emptyRole).toBeInTheDocument(); }); @@ -76,9 +76,7 @@ describe('DomainSettingsSection', () => { const tables = queryAllByRole('table'); expect(tables).toHaveLength(1); // should display two placeholder text, as role and labels were not passed - const inheritedPlaceholders = queryAllByText( - 'Inherits from project level values', - ); + const inheritedPlaceholders = queryAllByText('-'); expect(inheritedPlaceholders).toHaveLength(2); }); @@ -101,9 +99,7 @@ describe('DomainSettingsSection', () => { const tables = queryByRole('table'); expect(tables).not.toBeInTheDocument(); // should display three placeholder text, as role, labels, annotations were not passed - const inheritedPlaceholders = queryAllByText( - 'Inherits from project level values', - ); + const inheritedPlaceholders = queryAllByText('-'); expect(inheritedPlaceholders).toHaveLength(3); }); }); diff --git a/packages/console/src/models/Common/constants.ts b/packages/console/src/models/Common/constants.ts index 4350c97d2..198e7a59b 100644 --- a/packages/console/src/models/Common/constants.ts +++ b/packages/console/src/models/Common/constants.ts @@ -7,6 +7,7 @@ export const endpointPrefixes = { nodeExecution: '/node_executions', dynamicWorkflowExecution: '/data/node_executions', project: '/projects', + projectAttributes: '/project_attributes', projectDomainAtributes: '/project_domain_attributes', relaunchExecution: '/executions/relaunch', recoverExecution: '/executions/recover', diff --git a/packages/console/src/models/Project/api.ts b/packages/console/src/models/Project/api.ts index c57dd077c..7b7664f7c 100644 --- a/packages/console/src/models/Project/api.ts +++ b/packages/console/src/models/Project/api.ts @@ -18,6 +18,25 @@ export const listProjects = () => sortBy(projects, project => `${project.name}`.toLowerCase()) as Project[], }); +export const getProjectAttributes = (scope: IdentifierScope) => + getAdminEntity< + Admin.ProjectAttributesGetResponse, + Admin.ProjectAttributesGetResponse + >( + { + path: makeProjectDomainAttributesPath( + endpointPrefixes.projectAttributes, + scope, + ), + messageType: Admin.ProjectAttributesGetResponse, + }, + { + params: { + resource_type: Admin.MatchableResource.WORKFLOW_EXECUTION_CONFIG, + }, + }, + ); + export const getProjectDomainAttributes = (scope: IdentifierScope) => getAdminEntity< Admin.ProjectDomainAttributesGetResponse, @@ -32,7 +51,7 @@ export const getProjectDomainAttributes = (scope: IdentifierScope) => }, { params: { - resource_type: 'WORKFLOW_EXECUTION_CONFIG', + resource_type: Admin.MatchableResource.WORKFLOW_EXECUTION_CONFIG, }, }, ); diff --git a/packages/console/src/models/Project/utils.ts b/packages/console/src/models/Project/utils.ts index 8856402ba..50ae585b6 100644 --- a/packages/console/src/models/Project/utils.ts +++ b/packages/console/src/models/Project/utils.ts @@ -1,3 +1,4 @@ +import { compact } from 'lodash'; import { Identifier } from 'models/Common/types'; import { Project } from './types'; @@ -15,5 +16,5 @@ export function makeProjectDomainAttributesPath( prefix: string, { project, domain }: Partial, ) { - return [prefix, project, domain].join('/'); + return compact([prefix, project, domain]).join('/'); }