diff --git a/package-lock.json b/package-lock.json index 5fabfab8a..bd5a24e31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0", + "version": "0.5.0-beta-6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0", + "version": "0.5.0-beta-6", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 39d63d669..90c0df155 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0", + "version": "0.5.0-beta-6", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", diff --git a/src/Common/ChartVersionAndTypeSelector.tsx b/src/Common/ChartVersionAndTypeSelector.tsx index ac40e8c24..7272120ba 100644 --- a/src/Common/ChartVersionAndTypeSelector.tsx +++ b/src/Common/ChartVersionAndTypeSelector.tsx @@ -72,8 +72,7 @@ const ChartVersionAndTypeSelector = ({ setSelectedChartRefId }: ChartVersionAndT
Chart Type
- Chart Version + Chart Version ({ parseSearchParams: parseDeploymentHistoryDiffSearchParams(previousWfrId), @@ -51,14 +55,9 @@ export const DeploymentHistoryConfigDiff = ({ // ASYNC CALLS // Load comparison deployment data - const [ - compareDeploymentConfigLoader, - compareDeploymentConfig, - compareDeploymentConfigErr, - reloadCompareDeploymentConfig, - ] = useAsync( + const [compareDeploymentConfigLoader, compareDeploymentConfig, , reloadCompareDeploymentConfig] = useAsync( () => - Promise.all([ + Promise.allSettled([ getAppEnvDeploymentConfig({ params: { appName, @@ -83,124 +82,84 @@ export const DeploymentHistoryConfigDiff = ({ [currentWfrId, compareWfrId], ) - const [ - deploymentTemplateResolvedDataLoader, - deploymentTemplateResolvedData, - deploymentTemplateResolvedDataErr, - reloadDeploymentTemplateResolvedData, - ] = useAsync( - () => - abortPreviousRequests( - () => - Promise.all([ - getAppEnvDeploymentConfig({ - params: { - configArea: 'ResolveData', - appName, - envName, - }, - payload: { - values: getDeploymentTemplateValues( - compareDeploymentConfig[0].result?.deploymentTemplate, - ), - }, - signal: deploymentTemplateResolvedDataAbortControllerRef.current?.signal, - }), - getAppEnvDeploymentConfig({ - params: { - configArea: 'ResolveData', - appName, - envName, - }, - payload: { - values: getDeploymentTemplateValues( - compareDeploymentConfig[1].result?.deploymentTemplate, - ), - }, - signal: deploymentTemplateResolvedDataAbortControllerRef.current?.signal, - }), - ]), - deploymentTemplateResolvedDataAbortControllerRef, - ), - [convertVariables, compareDeploymentConfig], - convertVariables && !!compareDeploymentConfig, - ) - // METHODS - const reload = () => { - reloadCompareDeploymentConfig() - reloadDeploymentTemplateResolvedData() - } - const getNavItemHref = (resourceType: EnvResourceType, resourceName: string) => `${generatePath(path, { ...params })}/${resourceType}${resourceName ? `/${resourceName}` : ''}${search}` // Generate the deployment history config list const deploymentConfigList = useMemo(() => { - const isDeploymentTemplateLoaded = !deploymentTemplateResolvedDataLoader && deploymentTemplateResolvedData - const isComparisonDataLoaded = !compareDeploymentConfigLoader && compareDeploymentConfig - - const shouldLoadData = convertVariables - ? isComparisonDataLoaded && isDeploymentTemplateLoaded - : isComparisonDataLoaded - - if (shouldLoadData) { - const compareList = isPreviousDeploymentConfigAvailable - ? compareDeploymentConfig[1].result - : { - configMapData: null, - deploymentTemplate: null, - secretsData: null, - isAppAdmin: false, - } - const currentList = compareDeploymentConfig[0].result + if (!compareDeploymentConfigLoader && compareDeploymentConfig) { + const compareList = + isPreviousDeploymentConfigAvailable && compareDeploymentConfig[1].status === 'fulfilled' + ? compareDeploymentConfig[1].value.result + : { + configMapData: null, + deploymentTemplate: null, + secretsData: null, + isAppAdmin: false, + } + + const currentList = + compareDeploymentConfig[0].status === 'fulfilled' ? compareDeploymentConfig[0].value.result : null const configData = getAppEnvDeploymentConfigList({ currentList, compareList, getNavItemHref, convertVariables, - ...(convertVariables - ? { - currentDeploymentTemplateResolvedData: deploymentTemplateResolvedData[0].result, - compareDeploymentTemplateResolvedData: deploymentTemplateResolvedData[1].result, - } - : {}), }) return configData } return null - }, [ - isPreviousDeploymentConfigAvailable, - compareDeploymentConfigErr, - compareDeploymentConfig, - convertVariables, - deploymentTemplateResolvedDataLoader, - deploymentTemplateResolvedData, - ]) + }, [isPreviousDeploymentConfigAvailable, compareDeploymentConfigLoader, compareDeploymentConfig, convertVariables]) + + const compareDeploymentConfigErr = useMemo( + () => + !compareDeploymentConfigLoader && compareDeploymentConfig + ? getDeploymentHistoryConfigDiffError(compareDeploymentConfig[0]) || + getDeploymentHistoryConfigDiffError(compareDeploymentConfig[1]) + : null, + [compareDeploymentConfigLoader, compareDeploymentConfig], + ) const groupedDeploymentConfigList = useMemo( () => (deploymentConfigList ? groupArrayByObjectKey(deploymentConfigList.configList, 'groupHeader') : []), [deploymentConfigList], ) - const isLoading = compareDeploymentConfigLoader || deploymentTemplateResolvedDataLoader - const isError = - compareDeploymentConfigErr || - (deploymentTemplateResolvedDataErr && !getIsRequestAborted(deploymentTemplateResolvedDataErr)) + /** Previous deployment config has 404 error. */ + const hasPreviousDeploymentConfigNotFoundError = + compareDeploymentConfig && isDeploymentHistoryConfigDiffNotFoundError(compareDeploymentConfig[1]) + /** Hide diff state if the previous deployment config is unavailable or returns a 404 error. */ + const hideDiffState = !isPreviousDeploymentConfigAvailable || hasPreviousDeploymentConfigNotFoundError + // LOADING + const isLoading = compareDeploymentConfigLoader || (!compareDeploymentConfigErr && !deploymentConfigList) + // ERROR CONFIG + const errorConfig = { + code: compareDeploymentConfigErr?.code, + error: compareDeploymentConfigErr && !compareDeploymentConfigLoader, + reload: reloadCompareDeploymentConfig, + } + + if (compareDeploymentConfig && isDeploymentHistoryConfigDiffNotFoundError(compareDeploymentConfig[0])) { + return ( +
+ +
+ ) + } return ( - {isError && !isLoading ? ( - + {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( + ) : (
- {isLoading || (!isError && !deploymentConfigList) ? ( + {isLoading ? ( ) : ( <>

- Showing configuration change with respect to previous deployment + {hideDiffState + ? 'Configurations used for this deployment trigger' + : 'Showing configuration change with respect to previous deployment'}

-
- {Object.keys(groupedDeploymentConfigList).map((groupHeader) => - renderDeploymentHistoryConfig( - groupedDeploymentConfigList[groupHeader], - groupHeader !== 'UNGROUPED' ? groupHeader : null, - pathname, - ), +
+
+ {Object.keys(groupedDeploymentConfigList).map((groupHeader) => + renderDeploymentHistoryConfig( + groupedDeploymentConfigList[groupHeader], + groupHeader !== 'UNGROUPED' ? groupHeader : null, + pathname, + hideDiffState, + ), + )} +
+ {hasPreviousDeploymentConfigNotFoundError && ( + )}
diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx index 51ec5ae79..7d23c80fb 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -11,7 +11,11 @@ import { } from '@Shared/Components/SelectPicker' import { ComponentSizeType } from '@Shared/constants' -import { DeploymentHistoryDiffDetailedProps, DeploymentHistoryConfigDiffQueryParams } from './types' +import { + DeploymentHistoryDiffDetailedProps, + DeploymentHistoryConfigDiffQueryParams, + DeploymentHistoryConfigDiffRouteParams, +} from './types' import { getPipelineDeploymentsOptions, parseDeploymentHistoryDiffSearchParams } from './utils' export const DeploymentHistoryConfigDiffCompare = ({ @@ -25,10 +29,12 @@ export const DeploymentHistoryConfigDiffCompare = ({ runSource, renderRunSource, resourceId, + isCompareDeploymentConfigNotAvailable, ...props }: DeploymentHistoryDiffDetailedProps) => { // HOOKS - const { path, params } = useRouteMatch() + const { path, params } = useRouteMatch() + const { resourceType, resourceName } = params // URL FILTERS const { compareWfrId, updateSearchParams, sortBy, sortOrder, handleSorting } = useUrlFilters< @@ -58,30 +64,40 @@ export const DeploymentHistoryConfigDiffCompare = ({ renderRunSource, resourceId, }) + const previousDeployment = pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId) + const isPreviousDeploymentConfigAvailable = !!pipelineDeploymentsOptions.length const deploymentSelectorOnChange = ({ value }: SelectPickerOptionType) => { updateSearchParams({ compareWfrId: value }) } const selectorsConfig: DeploymentConfigDiffProps['selectorsConfig'] = { - primaryConfig: [ - { - id: 'deployment-config-diff-deployment-selector', - type: 'selectPicker', - selectPickerProps: { - name: 'deployment-config-diff-deployment-selector', - inputId: 'deployment-config-diff-deployment-selector', - classNamePrefix: 'deployment-config-diff-deployment-selector', - variant: SelectPickerVariantType.BORDER_LESS, - options: pipelineDeploymentsOptions, - placeholder: 'Select Deployment', - value: getSelectPickerOptionByValue(pipelineDeploymentsOptions, compareWfrId, null), - onChange: deploymentSelectorOnChange, - showSelectedOptionIcon: false, - menuSize: ComponentSizeType.large, - }, - }, - ], + primaryConfig: isPreviousDeploymentConfigAvailable + ? [ + { + id: 'deployment-config-diff-deployment-selector', + type: 'selectPicker', + selectPickerProps: { + name: 'deployment-config-diff-deployment-selector', + inputId: 'deployment-config-diff-deployment-selector', + classNamePrefix: 'deployment-config-diff-deployment-selector', + variant: SelectPickerVariantType.BORDER_LESS, + options: pipelineDeploymentsOptions, + placeholder: 'Select Deployment', + value: getSelectPickerOptionByValue(pipelineDeploymentsOptions, compareWfrId, null), + onChange: deploymentSelectorOnChange, + showSelectedOptionIcon: false, + menuSize: ComponentSizeType.large, + }, + }, + ] + : [ + { + id: 'no-previous-deployment', + type: 'string', + text: 'No previous deployment', + }, + ], secondaryConfig: [ { id: 'base-configuration', @@ -91,6 +107,16 @@ export const DeploymentHistoryConfigDiffCompare = ({ ], } + const getNavHelpText = () => { + if (isPreviousDeploymentConfigAvailable) { + return isCompareDeploymentConfigNotAvailable + ? `Diff unavailable: Configurations for deployment execution ‘${previousDeployment?.label || 'N/A'}’ not found` + : `Showing diff in configuration deployed on: ${previousDeployment?.label || 'N/A'} & ${currentDeployment}` + } + + return null + } + const onSorting = () => handleSorting(sortOrder !== SortingOrder.DESC ? 'sort-config' : '') const sortingConfig: DeploymentConfigDiffProps['sortingConfig'] = { @@ -109,12 +135,11 @@ export const DeploymentHistoryConfigDiffCompare = ({ {...props} showDetailedDiffState navHeading={`Comparing ${envName}`} - navHelpText={ - compareWfrId - ? `Showing diff in configuration deployed on: ${pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId).label} & ${currentDeployment}` - : null - } - goBackURL={generatePath(path.split('/:resourceType')[0], params)} + headerText={!isPreviousDeploymentConfigAvailable ? '' : undefined} // using `undefined` to ensure component picks default value + scrollIntoViewId={`${resourceType}${resourceName ? `-${resourceName}` : ''}`} + navHelpText={getNavHelpText()} + isNavHelpTextShowingError={isCompareDeploymentConfigNotAvailable} + goBackURL={generatePath(path.split('/:resourceType')[0], { ...params })} selectorsConfig={selectorsConfig} sortingConfig={sortingConfig} scopeVariablesConfig={scopeVariablesConfig} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx index 3e98d5e6d..95f227858 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx @@ -34,10 +34,11 @@ const DeploymentHistoryDiffView = ({ isUnpublished, isDeleteDraft, rootClassName, - sortBy = '', - sortOrder = null, + sortingConfig, + codeEditorKey, }: DeploymentTemplateHistoryType) => { const { historyComponent, historyComponentName } = useParams() + const { sortBy, sortOrder } = sortingConfig ?? { sortBy: '', sortOrder: null } const [convertVariables, setConvertVariables] = useState(false) @@ -86,7 +87,7 @@ const DeploymentHistoryDiffView = ({ const renderDeploymentDiffViaCodeEditor = () => (
{baseTemplateConfiguration?.codeEditorValue?.displayName} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx index 05d77a985..140c8ecb8 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx @@ -28,8 +28,9 @@ export const renderDeploymentHistoryConfig = ( config: DeploymentConfigDiffProps['configList'], heading: string, pathname: string, + hideDiffState: boolean, ) => ( -
+
{heading && (

{heading}

@@ -41,14 +42,18 @@ export const renderDeploymentHistoryConfig = ( return (

- {name || title} + + {name || title} +

- {renderState(diffState)} + {!hideDiffState && renderState(diffState)}
) })} @@ -73,7 +78,7 @@ export const renderPipelineDeploymentOptionDescription = ({ runSource, }: Pick & Pick) => ( -
+

{stage} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts index 717487cd9..350ed7d50 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts @@ -18,7 +18,7 @@ export interface DeploymentHistoryConfigDiffProps export type DeploymentHistoryDiffDetailedProps = Pick< DeploymentConfigDiffProps, - 'collapsibleNavList' | 'configList' | 'errorConfig' | 'isLoading' | 'navList' + 'collapsibleNavList' | 'configList' | 'errorConfig' | 'isLoading' | 'navList' | 'hideDiffState' > & Required< Pick< @@ -30,6 +30,7 @@ export type DeploymentHistoryDiffDetailedProps = Pick< previousWfrId: number convertVariables: boolean setConvertVariables: Dispatch> + isCompareDeploymentConfigNotAvailable?: boolean } export interface DeploymentHistoryConfigDiffQueryParams { diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts index a9be8f4e7..21a41d472 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts @@ -1,6 +1,6 @@ import moment from 'moment' -import { DATE_TIME_FORMATS } from '@Common/Constants' +import { DATE_TIME_FORMATS, ERROR_STATUS_CODE } from '@Common/Constants' import { DeploymentStageType } from '@Shared/constants' import { SelectPickerOptionType } from '@Shared/Components/SelectPicker' @@ -10,7 +10,7 @@ import { DeploymentHistoryConfigDiffProps } from './types' export const getPipelineDeployments = (triggerHistory: DeploymentHistoryConfigDiffProps['triggerHistory']) => Array.from(triggerHistory) - .filter(([, value]) => value?.stage === DeploymentStageType.DEPLOY) + .filter(([, value]) => value.stage === DeploymentStageType.DEPLOY) .map(([, value]) => value) export const getPipelineDeploymentsWfrIds = ({ @@ -65,3 +65,9 @@ export const getPipelineDeploymentsOptions = ({ export const parseDeploymentHistoryDiffSearchParams = (compareWfrId: number) => (searchParams: URLSearchParams) => ({ compareWfrId: +(searchParams.get('compareWfrId') || compareWfrId), }) + +export const isDeploymentHistoryConfigDiffNotFoundError = (res: PromiseSettledResult) => + res.status === 'rejected' && res.reason?.code === ERROR_STATUS_CODE.NOT_FOUND + +export const getDeploymentHistoryConfigDiffError = (res: PromiseSettledResult) => + res.status === 'rejected' && res.reason?.code !== ERROR_STATUS_CODE.NOT_FOUND ? res.reason : null diff --git a/src/Shared/Components/CICDHistory/TriggerOutput.tsx b/src/Shared/Components/CICDHistory/TriggerOutput.tsx index bb8fc3864..790799ea2 100644 --- a/src/Shared/Components/CICDHistory/TriggerOutput.tsx +++ b/src/Shared/Components/CICDHistory/TriggerOutput.tsx @@ -297,7 +297,7 @@ const StartDetails = ({ return (

-
+
Start
diff --git a/src/Shared/Components/CICDHistory/service.tsx b/src/Shared/Components/CICDHistory/service.tsx index 437e67ae9..2763c2eb1 100644 --- a/src/Shared/Components/CICDHistory/service.tsx +++ b/src/Shared/Components/CICDHistory/service.tsx @@ -197,8 +197,11 @@ export const prepareConfigMapAndSecretData = ( let typeValue = 'Environment Variable' if (rawData.type === 'volume') { typeValue = 'Data Volume' - if (rawData.mountPath) { - secretValues['mountPath'] = { displayName: 'Volume mount path', value: rawData.mountPath } + if (rawData.mountPath || rawData.defaultMountPath) { + secretValues['mountPath'] = { + displayName: 'Volume mount path', + value: rawData.mountPath || rawData.defaultMountPath, + } } if (rawData.subPath) { secretValues['subPath'] = { displayName: 'Set SubPath', value: 'Yes' } diff --git a/src/Shared/Components/CICDHistory/types.tsx b/src/Shared/Components/CICDHistory/types.tsx index e2e05633c..329a763f4 100644 --- a/src/Shared/Components/CICDHistory/types.tsx +++ b/src/Shared/Components/CICDHistory/types.tsx @@ -488,8 +488,11 @@ export interface DeploymentTemplateHistoryType { isUnpublished?: boolean isDeleteDraft?: boolean rootClassName?: string - sortBy?: string - sortOrder?: SortingOrder + codeEditorKey?: React.Key + sortingConfig?: { + sortBy: string + sortOrder: SortingOrder + } } export interface DeploymentHistoryDetailRes extends ResponseType { result?: DeploymentHistoryDetail diff --git a/src/Shared/Components/Collapse/Collapse.tsx b/src/Shared/Components/Collapse/Collapse.tsx index 26e9b8768..273dd55a3 100644 --- a/src/Shared/Components/Collapse/Collapse.tsx +++ b/src/Shared/Components/Collapse/Collapse.tsx @@ -1,6 +1,62 @@ +import { useEffect, useRef, useState } from 'react' import { CollapseProps } from './types' -export const Collapse = ({ expand, children }: CollapseProps) => ( - // TODO: removed animation because of miscalculations (broken with auto editor height) -
{expand ? children : null}
-) +/** + * Collapse component for smoothly expanding or collapsing its content. + * Dynamically calculates the content height and applies smooth transitions. + * It also supports a callback when the transition ends. + */ +export const Collapse = ({ expand, onTransitionEnd, children }: CollapseProps) => { + // Reference to the content container to calculate its height + const contentRef = useRef(null) + + // State to store the dynamic height of the content; initially set to 0 if collapsed + const [contentHeight, setContentHeight] = useState(!expand ? 0 : null) + + /** + * Effect to observe changes in the content size when expanded and recalculate the height. + * Uses a ResizeObserver to handle dynamic content size changes. + */ + useEffect(() => { + if (!contentHeight || !expand || !contentRef.current) { + return null + } + + const resizeObserver = new ResizeObserver((entries) => { + // Update the height when content size changes + setContentHeight(entries[0].contentRect.height) + }) + + // Observe the content container for resizing + resizeObserver.observe(contentRef.current) + + // Clean up the observer when the component unmounts or content changes + return () => { + resizeObserver.disconnect() + } + }, [contentHeight, expand]) + + /** + * Effect to handle the initial setting of content height during expansion or collapse. + * Sets height to the content's full height when expanded, or 0 when collapsed. + */ + useEffect(() => { + if (expand) { + // Set the content height when expanded + setContentHeight(contentRef.current?.getBoundingClientRect().height) + } else { + // Collapse content by setting the height to 0 + setContentHeight(0) + } + }, [expand]) + + return ( +
+ {/* The container that holds the collapsible content */} +
{children}
+
+ ) +} diff --git a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index 0460df09b..e60d8edd6 100644 --- a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx +++ b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx @@ -45,7 +45,7 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP > @@ -60,7 +60,7 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP
) : ( - items.map(({ title, href, iconConfig, subtitle, onClick }) => ( + items.map(({ title, strikeThrough, href, iconConfig, subtitle, onClick }) => (
- + {title} {subtitle && ( diff --git a/src/Shared/Components/CollapsibleList/CollapsibleList.types.ts b/src/Shared/Components/CollapsibleList/CollapsibleList.types.ts index be4944f82..e67b599ff 100644 --- a/src/Shared/Components/CollapsibleList/CollapsibleList.types.ts +++ b/src/Shared/Components/CollapsibleList/CollapsibleList.types.ts @@ -10,6 +10,10 @@ export interface CollapsibleListItem { * The subtitle of the list item. */ subtitle?: string + /** + * If true, the title will be rendered with line-through. + */ + strikeThrough?: boolean /** * Configuration for the icon. */ diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx index fd445efcf..d1989c32e 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx @@ -11,8 +11,10 @@ export const DeploymentConfigDiff = ({ goBackURL, navHeading, navHelpText, + isNavHelpTextShowingError, tabConfig, showDetailedDiffState, + hideDiffState, renderedInDrawer, ...resProps }: DeploymentConfigDiffProps) => ( @@ -24,13 +26,16 @@ export const DeploymentConfigDiff = ({ goBackURL={goBackURL} navHeading={navHeading} navHelpText={navHelpText} + isNavHelpTextShowingError={isNavHelpTextShowingError} tabConfig={tabConfig} showDetailedDiffState={showDetailedDiffState} + hideDiffState={hideDiffState} />
diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts index 8ff0aee29..2c6c78f64 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -65,10 +65,13 @@ export interface DeploymentConfigDiffProps { errorConfig?: { error: boolean code: number + message?: string + redirectURL?: string reload: () => void } configList: DeploymentConfigListItem[] showDetailedDiffState?: boolean + hideDiffState?: boolean headerText?: string scrollIntoViewId?: string selectorsConfig: { @@ -86,6 +89,7 @@ export interface DeploymentConfigDiffProps { goBackURL?: string navHeading: string navHelpText?: string + isNavHelpTextShowingError?: boolean tabConfig?: { tabs: string[] activeTab: string @@ -107,8 +111,10 @@ export interface DeploymentConfigDiffNavigationProps | 'goBackURL' | 'navHeading' | 'navHelpText' + | 'isNavHelpTextShowingError' | 'tabConfig' | 'showDetailedDiffState' + | 'hideDiffState' > {} export interface DeploymentConfigDiffMainProps @@ -123,10 +129,11 @@ export interface DeploymentConfigDiffMainProps | 'sortingConfig' | 'scopeVariablesConfig' | 'showDetailedDiffState' + | 'hideDiffState' > {} export type DeploymentConfigDiffAccordionProps = Pick & - Pick & { + Pick & { id: string title: string children: React.ReactNode @@ -151,6 +158,4 @@ export type AppEnvDeploymentConfigListParams = (IsManifestView e getNavItemHref: (resourceType: EnvResourceType, resourceName: string) => string isManifestView?: IsManifestView convertVariables?: boolean - currentDeploymentTemplateResolvedData?: AppEnvDeploymentConfigDTO - compareDeploymentTemplateResolvedData?: AppEnvDeploymentConfigDTO } diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index 814748e0e..a498d9671 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -515,20 +515,50 @@ const getConfigMapSecretData = ( return deploymentConfig } +const getDeploymentTemplateResolvedData = (deploymentTemplate: DeploymentTemplateDTO) => { + try { + if (deploymentTemplate.deploymentDraftData) { + return JSON.parse(deploymentTemplate.deploymentDraftData.configData[0].draftMetadata.draftResolvedValue) + } + return deploymentTemplate.resolvedValue + } catch { + return null + } +} + const getConfigDataWithResolvedDeploymentTemplate = ( - data: AppEnvDeploymentConfigListParams['currentList'], - resolvedData: AppEnvDeploymentConfigListParams['currentDeploymentTemplateResolvedData'], -) => - data && resolvedData?.deploymentTemplate - ? { - ...data, - deploymentTemplate: { - ...data.deploymentTemplate, - deploymentDraftData: null, - data: resolvedData.deploymentTemplate.resolvedValue, - }, - } - : data + data: AppEnvDeploymentConfigListParams['compareList'], + convertVariables: boolean, +): AppEnvDeploymentConfigListParams['compareList'] => { + if (!data) { + return { + deploymentTemplate: null, + configMapData: null, + isAppAdmin: null, + secretsData: null, + pipelineConfigData: null, + } + } + + if (!data.deploymentTemplate || !convertVariables) { + return data + } + + const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) + + return { + ...data, + deploymentTemplate: { + ...data.deploymentTemplate, + ...(deploymentTemplateResolvedData + ? { + data: deploymentTemplateResolvedData, + deploymentDraftData: null, + } + : {}), + }, + } +} /** * Generates a list of deployment configurations for application environments and identifies changes between the current and compare lists. @@ -548,8 +578,6 @@ export const getAppEnvDeploymentConfigList = ): { configList: DeploymentConfigDiffProps['configList'] navList: DeploymentConfigDiffProps['navList'] @@ -558,11 +586,11 @@ export const getAppEnvDeploymentConfigList = ['currentList'], - currentDeploymentTemplateResolvedData, + convertVariables, ) const compareWithObject = getConfigDataWithResolvedDeploymentTemplate( compareList as AppEnvDeploymentConfigListParams['compareList'], - compareDeploymentTemplateResolvedData, + convertVariables, ) const currentDeploymentData = getDeploymentTemplateDiffViewData(compareToObject.deploymentTemplate) const compareDeploymentData = getDeploymentTemplateDiffViewData(compareWithObject.deploymentTemplate) @@ -736,15 +764,6 @@ export const getAppEnvDeploymentConfigList = { - try { - const data = getDeploymentTemplateData(deploymentTemplate) - return JSON.stringify(data) - } catch { - return null - } -} - export const getDefaultVersionAndPreviousDeploymentOptions = (data: TemplateListDTO[]) => data.reduce<{ previousDeployments: TemplateListDTO[]; defaultVersions: TemplateListDTO[] }>( (acc, curr) => ({ diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx index 57aea1524..a13f67817 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx @@ -1,37 +1,33 @@ -import { forwardRef } from 'react' - import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg' import { Collapse } from '../Collapse' import { DeploymentConfigDiffAccordionProps, DeploymentConfigDiffState } from './DeploymentConfigDiff.types' import { diffStateTextColorMap, diffStateTextMap } from './DeploymentConfigDiff.constants' -export const DeploymentConfigDiffAccordion = forwardRef( - ( - { - diffState, - showDetailedDiffState, - children, - title, - id, - isExpanded, - onClick, - onTransitionEnd, - }: DeploymentConfigDiffAccordionProps, - ref, - ) => ( -
- - - {children} - -
- ), + )} + + + {children} + +
) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index c45fc619d..fe2bf119d 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -1,4 +1,4 @@ -import { Fragment, TransitionEvent, useEffect, useState } from 'react' +import { Fragment, useEffect, useRef, useState } from 'react' import Tippy from '@tippyjs/react' import { ReactComponent as ICSortArrowDown } from '@Icons/ic-sort-arrow-down.svg' @@ -19,6 +19,7 @@ import { DeploymentConfigDiffMainProps, DeploymentConfigDiffSelectPickerProps, DeploymentConfigDiffState, + DeploymentConfigDiffAccordionProps, } from './DeploymentConfigDiff.types' export const DeploymentConfigDiffMain = ({ @@ -31,10 +32,15 @@ export const DeploymentConfigDiffMain = ({ scrollIntoViewId, scopeVariablesConfig, showDetailedDiffState, + hideDiffState, }: DeploymentConfigDiffMainProps) => { // STATES const [expandedView, setExpandedView] = useState>({}) + // REFS + /** Ref to track if the element should scroll into view after expanding */ + const scrollIntoViewAfterExpand = useRef(false) + const handleAccordionClick = (id: string) => () => { setExpandedView({ ...expandedView, @@ -42,10 +48,12 @@ export const DeploymentConfigDiffMain = ({ }) } - const handleTransitionEnd = (id: string) => (e: TransitionEvent) => { - if (e.target === e.currentTarget && scrollIntoViewId === id) { + const onTransitionEnd: DeploymentConfigDiffAccordionProps['onTransitionEnd'] = (e) => { + if (scrollIntoViewAfterExpand.current && e.target === e.currentTarget) { const element = document.querySelector(`#${scrollIntoViewId}`) element?.scrollIntoView({ block: 'start' }) + // Reset ref after scrolling into view + scrollIntoViewAfterExpand.current = false } } @@ -65,6 +73,7 @@ export const DeploymentConfigDiffMain = ({ useEffect(() => { if (scrollIntoViewId) { + scrollIntoViewAfterExpand.current = true setExpandedView((prev) => ({ ...prev, [scrollIntoViewId]: true })) } }, [scrollIntoViewId]) @@ -176,8 +185,9 @@ export const DeploymentConfigDiffMain = ({ isExpanded={expandedView[id]} diffState={diffState} onClick={handleAccordionClick(id)} - onTransitionEnd={handleTransitionEnd(id)} + onTransitionEnd={onTransitionEnd} showDetailedDiffState={showDetailedDiffState} + hideDiffState={hideDiffState} > {singleView ? ( <> @@ -186,7 +196,7 @@ export const DeploymentConfigDiffMain = ({
{secondaryHeading}
)}
)} @@ -239,7 +249,14 @@ export const DeploymentConfigDiffMain = ({
- {errorConfig?.error && } + {errorConfig?.error && ( + + )} {!errorConfig?.error && (isLoading ? ( diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index d03722d40..78f45c558 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -4,9 +4,10 @@ import Tippy from '@tippyjs/react' import { ReactComponent as ICClose } from '@Icons/ic-close.svg' import { ReactComponent as ICInfoOutlined } from '@Icons/ic-info-outlined.svg' +import { ReactComponent as ICError } from '@Icons/ic-error.svg' import { StyledRadioGroup } from '@Common/index' -import { CollapsibleList } from '../CollapsibleList' +import { CollapsibleList, CollapsibleListConfig } from '../CollapsibleList' import { DeploymentConfigDiffNavigationProps, DeploymentConfigDiffState } from './DeploymentConfigDiff.types' import { diffStateIconMap, diffStateTooltipTextMap } from './DeploymentConfigDiff.constants' @@ -24,8 +25,10 @@ export const DeploymentConfigDiffNavigation = ({ goBackURL, navHeading, navHelpText, + isNavHelpTextShowingError, tabConfig, showDetailedDiffState, + hideDiffState, }: DeploymentConfigDiffNavigationProps) => { // STATES const [expandedIds, setExpandedIds] = useState>({}) @@ -35,16 +38,17 @@ export const DeploymentConfigDiffNavigation = ({ }, [collapsibleNavList]) /** Collapsible List Config. */ - const collapsibleListConfig = collapsibleNavList.map(({ items, ...resListItem }) => ({ + const collapsibleListConfig = collapsibleNavList.map(({ items, ...resListItem }) => ({ ...resListItem, isExpanded: expandedIds[resListItem.id], - items: items.map(({ diffState, ...resItem }) => ({ + items: items.map(({ diffState, ...resItem }) => ({ ...resItem, - ...(diffState !== DeploymentConfigDiffState.NO_DIFF + strikeThrough: showDetailedDiffState && diffState === DeploymentConfigDiffState.DELETED, + ...(!hideDiffState && diffState !== DeploymentConfigDiffState.NO_DIFF ? { iconConfig: { Icon: showDetailedDiffState ? diffStateIconMap[diffState] : diffStateIconMap.hasDiff, - props: { className: 'icon-dim-16 dc__no-shrink' }, + props: { className: 'dc__no-shrink' }, tooltipProps: { content: showDetailedDiffState ? diffStateTooltipTextMap[diffState] @@ -121,7 +125,7 @@ export const DeploymentConfigDiffNavigation = ({ onClick={onClick} > {title} - {diffState !== DeploymentConfigDiffState.NO_DIFF && ( + {!hideDiffState && diffState !== DeploymentConfigDiffState.NO_DIFF && ( - + {isNavHelpTextShowingError ? ( + + ) : ( + + )} -

{navHelpText}

+

{navHelpText}

)} diff --git a/src/Shared/Services/app.service.ts b/src/Shared/Services/app.service.ts index 2978f4120..a244b84f6 100644 --- a/src/Shared/Services/app.service.ts +++ b/src/Shared/Services/app.service.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ROUTES, ResponseType, get, getUrlWithSearchParams, post, showError } from '../../Common' +import { ROUTES, ResponseType, get, getUrlWithSearchParams, showError } from '../../Common' import { CIMaterialInfoDTO, CIMaterialInfoType, @@ -57,11 +57,9 @@ export const getArtifactInfo = async ( export const getAppEnvDeploymentConfig = ({ params, - payload, signal, }: { params: AppEnvDeploymentConfigPayloadType - payload?: { values: string } signal?: AbortSignal }): Promise> => - post(getUrlWithSearchParams(ROUTES.CONFIG_DATA, params), payload, { signal }) + get(getUrlWithSearchParams(ROUTES.CONFIG_DATA, params), { signal }) diff --git a/src/Shared/Services/app.types.ts b/src/Shared/Services/app.types.ts index 68f84a040..cf3d4f31a 100644 --- a/src/Shared/Services/app.types.ts +++ b/src/Shared/Services/app.types.ts @@ -252,11 +252,6 @@ export type AppEnvDeploymentConfigPayloadType = resourceName?: string configArea?: 'AppConfiguration' } - | { - appName: string - envName: string - configArea: 'ResolveData' - } | { appName: string envName: string @@ -283,6 +278,7 @@ export interface TemplateListDTO { finishedOn?: string status?: string pipelineId?: number + wfrId?: number } export interface ManifestTemplateDTO {