From ddff3acedecc2fdcde0da7499f6ce7955299482f Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Fri, 9 Aug 2024 13:06:26 +0530 Subject: [PATCH 01/28] refactor: Collapsible List, DeploymentConfigDiffNavigation: add support in NavLink to check for search params for active state --- .../CollapsibleList.component.tsx | 2 ++ .../Components/CollapsibleList/utils.ts | 30 +++++++++++++++++++ .../DeploymentConfigDiffNavigation.tsx | 2 ++ 3 files changed, 34 insertions(+) create mode 100644 src/Shared/Components/CollapsibleList/utils.ts diff --git a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index 8b2569c3e..c394cc366 100644 --- a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx +++ b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx @@ -7,6 +7,7 @@ import { ReactComponent as ICExpand } from '@Icons/ic-expand.svg' import { Collapse } from '../Collapse' import { CollapsibleListProps } from './CollapsibleList.types' +import { checkNavLinkActiveState } from './utils' import './CollapsibleList.scss' const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElement) => ( @@ -66,6 +67,7 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP key={title} to={href} className="collapsible__item flexbox dc__align-items-center dc__gap-8 dc__no-decor br-4 py-6 px-8 cursor" + isActive={checkNavLinkActiveState(href)} onClick={(e) => { // Prevent navigation to the same page if (href === pathname) { diff --git a/src/Shared/Components/CollapsibleList/utils.ts b/src/Shared/Components/CollapsibleList/utils.ts new file mode 100644 index 000000000..5a8500da9 --- /dev/null +++ b/src/Shared/Components/CollapsibleList/utils.ts @@ -0,0 +1,30 @@ +import { NavLinkProps } from 'react-router-dom' + +/** + * Determines if a navigation link is active based on the current location. + * + * This function checks if the provided `href` matches the current location's pathname + * and/or search query, and returns a boolean indicating whether the link should be considered active. + * + * @param href - The target URL or path to compare against the current location. + * + * @returns A function that takes the current location and returns a boolean: + * - `true` if the `href` matches the current location's pathname and/or search query. + * - `false` otherwise. + */ +export const checkNavLinkActiveState = + (href: string): NavLinkProps['isActive'] => + (_, location) => { + const [pathString, queryString] = href.split('?') + + if (pathString && queryString) { + return `${location.pathname}${location.search}` === href + } + if (pathString) { + return location.pathname === pathString + } + if (queryString) { + return location.search === `?${queryString}` + } + return false + } diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index b8f2d8307..186de8044 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -7,6 +7,7 @@ import { ReactComponent as ICInfoOutlined } from '@Icons/ic-info-outlined.svg' import { ReactComponent as ICDiffFileUpdated } from '@Icons/ic-diff-file-updated.svg' import { StyledRadioGroup } from '@Common/index' +import { checkNavLinkActiveState } from '../CollapsibleList/utils' import { CollapsibleList } from '../CollapsibleList' import { DeploymentConfigDiffNavigationProps } from './DeploymentConfigDiff.types' @@ -107,6 +108,7 @@ export const DeploymentConfigDiffNavigation = ({ Date: Fri, 9 Aug 2024 17:16:10 +0530 Subject: [PATCH 02/28] feat: SelectPicker - add support to show tippy on option --- src/Shared/Components/SelectPicker/common.tsx | 71 +++++++++++-------- src/Shared/Components/SelectPicker/type.ts | 5 ++ 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/Shared/Components/SelectPicker/common.tsx b/src/Shared/Components/SelectPicker/common.tsx index fbf8cf465..34366530e 100644 --- a/src/Shared/Components/SelectPicker/common.tsx +++ b/src/Shared/Components/SelectPicker/common.tsx @@ -14,6 +14,7 @@ * limitations under the License. */ +import Tippy, { TippyProps } from '@tippyjs/react' import { components, DropdownIndicatorProps, @@ -31,7 +32,7 @@ import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg' import { ReactComponent as ICClose } from '@Icons/ic-close.svg' import { ReactComponent as ICErrorExclamation } from '@Icons/ic-error-exclamation.svg' import { ChangeEvent } from 'react' -import { noop } from '@Common/Helper' +import { ConditionalWrap, noop } from '@Common/Helper' import { CHECKBOX_VALUE } from '@Common/Types' import { Checkbox } from '@Common/Checkbox' import { ReactSelectInputAction } from '@Common/Constants' @@ -39,6 +40,12 @@ import { isNullOrUndefined } from '@Shared/Helpers' import { SelectPickerGroupHeadingProps, SelectPickerOptionType, SelectPickerProps } from './type' import { getGroupCheckboxValue } from './utils' +const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElement) => ( + + {children} + +) + export const SelectPickerDropdownIndicator = ( props: DropdownIndicatorProps>, ) => { @@ -124,7 +131,7 @@ export const SelectPickerOption = ({ isDisabled, isSelected, } = props - const { description, startIcon, endIcon } = data ?? {} + const { description, startIcon, endIcon, tooltipProps } = data ?? {} const showDescription = !!description // __isNew__ denotes the new option to be created const isCreatableOption = '__isNew__' in data && data.__isNew__ @@ -137,39 +144,41 @@ export const SelectPickerOption = ({ return ( -
- {isMulti && !isCreatableOption && ( - - )} -
- {startIcon && ( -
{startIcon}
+ +
+ {isMulti && !isCreatableOption && ( + )} -
-

- {label} -

- {/* Add support for custom ellipsis if required */} - {showDescription && ( -

- {description} -

+
+ {startIcon && ( +
{startIcon}
+ )} +
+

+ {label} +

+ {/* Add support for custom ellipsis if required */} + {showDescription && ( +

+ {description} +

+ )} +
+ {endIcon && ( +
{endIcon}
)}
- {endIcon && ( -
{endIcon}
- )}
-
+
) } diff --git a/src/Shared/Components/SelectPicker/type.ts b/src/Shared/Components/SelectPicker/type.ts index 820a894b8..c789bdd71 100644 --- a/src/Shared/Components/SelectPicker/type.ts +++ b/src/Shared/Components/SelectPicker/type.ts @@ -22,6 +22,7 @@ import { GroupBase, GroupHeadingProps, Props as ReactSelectProps, SelectInstance import { CreatableProps } from 'react-select/creatable' // This import allows to extend the base interface in react-select module via module augmentation import type {} from 'react-select/base' +import { TippyProps } from '@tippyjs/react' export interface SelectPickerOptionType extends OptionType { /** @@ -36,6 +37,10 @@ export interface SelectPickerOptionType extends O * Icon at the end of the option */ endIcon?: ReactElement + /** + * Props passed to show the tippy on option + */ + tooltipProps?: TippyProps } type SelectProps = ReactSelectProps< From 97aab9da6a7c7969131f17a20368ec5feb79098a Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Fri, 9 Aug 2024 17:17:08 +0530 Subject: [PATCH 03/28] refactor: DeploymentConfigDiff - css refactor, add prop to hide divider between selectors in header --- .../DeploymentConfigDiff/DeploymentConfigDiff.scss | 5 ++--- .../DeploymentConfigDiff.types.ts | 1 + .../DeploymentConfigDiffMain.tsx | 14 +++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss index 9e0859448..85a346b89 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss @@ -18,8 +18,7 @@ } &__main-content { - height: calc(100vh - 122px); - overflow: auto; + flex-grow: 1; &__heading { display: grid; @@ -39,7 +38,7 @@ &__tab-list { label { - flex-grow: 1 + flex-grow: 1; } .radio__item-label { diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts index 9064785a4..988109a4f 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -63,6 +63,7 @@ export interface DeploymentConfigDiffProps { selectorsConfig: { primaryConfig: DeploymentConfigDiffSelectPickerProps[] secondaryConfig: DeploymentConfigDiffSelectPickerProps[] + hideDivider?: boolean } sortingConfig?: { sortBy: string diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index 5ef7c7081..195429cb0 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -65,7 +65,9 @@ export const DeploymentConfigDiffMain = ({ ) : ( configItem.text )} - {index !== list.length - 1 && /} + {!selectorsConfig?.hideDivider && index !== list.length - 1 && ( + / + )} ) } @@ -74,13 +76,15 @@ export const DeploymentConfigDiffMain = ({ return ( -
+
{...selectPickerProps} isDisabled={isLoading || selectPickerProps?.isDisabled} />
- {index !== list.length - 1 && /} + {!selectorsConfig?.hideDivider && index !== list.length - 1 && ( + / + )} ) }) @@ -170,7 +174,7 @@ export const DeploymentConfigDiffMain = ({ }) return ( -
+

{headerText}

@@ -183,7 +187,7 @@ export const DeploymentConfigDiffMain = ({ {renderSortButton()}
-
+
{errorConfig?.error && } {!errorConfig?.error && (isLoading ? ( From cb4a62a964a35efa3d557ffa27ac34f72d098e95 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 19 Sep 2024 11:51:47 +0530 Subject: [PATCH 04/28] feat: DeploymentConfigDiff - Scope Variables Support & code refactor --- src/Common/Helper.tsx | 16 +++++ src/Common/Toggle/Toggle.tsx | 14 +++- .../DeploymentConfigDiff.types.ts | 8 +++ .../DeploymentConfigDiff.utils.tsx | 64 +++++++++++++++-- .../DeploymentConfigDiffMain.tsx | 72 ++++++++++++++----- src/Shared/Services/app.service.ts | 17 +++-- src/Shared/Services/app.types.ts | 43 ++++++++--- 7 files changed, 194 insertions(+), 40 deletions(-) diff --git a/src/Common/Helper.tsx b/src/Common/Helper.tsx index b85fcf37a..6bda59316 100644 --- a/src/Common/Helper.tsx +++ b/src/Common/Helper.tsx @@ -1047,3 +1047,19 @@ export function asyncWrap(promise): any[] { } export const prefixZeroIfSingleDigit = (value: number = 0) => (value > 0 && value < 10 ? `0${value}` : value) + +export const throttle = unknown>( + func: T, + delay: number = 300, +): ((...args: Parameters) => void) => { + let lastCall = 0 + + return (...args: Parameters) => { + const now = Date.now() + + if (now - lastCall >= delay) { + lastCall = now + func(...args) + } + } +} diff --git a/src/Common/Toggle/Toggle.tsx b/src/Common/Toggle/Toggle.tsx index 3a1611d55..ac90a97d4 100644 --- a/src/Common/Toggle/Toggle.tsx +++ b/src/Common/Toggle/Toggle.tsx @@ -14,8 +14,8 @@ * limitations under the License. */ -import React from 'react' -import { useEffectAfterMount } from '../Helper' +import React, { useCallback } from 'react' +import { throttle, useEffectAfterMount } from '../Helper' import './Toggle.scss' const Toggle = ({ @@ -27,6 +27,7 @@ const Toggle = ({ dataTestId = 'handle-toggle-button', Icon = null, iconClass = '', + throttleOnChange = false, ...props }) => { const [active, setActive] = React.useState(selected) @@ -49,13 +50,20 @@ const Toggle = ({ } } + const throttledHandleClick = useCallback(throttle(handleClick, 500), []) + return (
{renderHeaderSelectors(selectorsConfig.secondaryConfig)}
- {renderSortButton()} + {(sortingConfig || scopeVariablesConfig) && ( +
+ {renderSortButton()} + {renderScopeVariablesButton()} +
+ )}
diff --git a/src/Shared/Services/app.service.ts b/src/Shared/Services/app.service.ts index 2f1684359..2978f4120 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, showError } from '../../Common' +import { ROUTES, ResponseType, get, getUrlWithSearchParams, post, showError } from '../../Common' import { CIMaterialInfoDTO, CIMaterialInfoType, @@ -55,8 +55,13 @@ export const getArtifactInfo = async ( } } -export const getAppEnvDeploymentConfig = ( - params: AppEnvDeploymentConfigPayloadType, - signal?: AbortSignal, -): Promise> => - get(getUrlWithSearchParams(ROUTES.CONFIG_DATA, params), { signal }) +export const getAppEnvDeploymentConfig = ({ + params, + payload, + signal, +}: { + params: AppEnvDeploymentConfigPayloadType + payload?: { values: string } + signal?: AbortSignal +}): Promise> => + post(getUrlWithSearchParams(ROUTES.CONFIG_DATA, params), payload, { signal }) diff --git a/src/Shared/Services/app.types.ts b/src/Shared/Services/app.types.ts index 88c4bd402..ea9477ac3 100644 --- a/src/Shared/Services/app.types.ts +++ b/src/Shared/Services/app.types.ts @@ -161,6 +161,7 @@ export interface DraftMetadataDTO { draftId: number draftVersionId: number draftState: number + draftResolvedValue: string approvers: string[] canApprove: boolean commentsCount: number @@ -206,13 +207,19 @@ export enum ConfigResourceType { export interface DeploymentTemplateDTO { resourceType: ConfigResourceType.DeploymentTemplate - data: { [key: string]: any } + data: Record deploymentDraftData: ConfigMapSecretDataType | null + variableSnapshot: { + 'Deployment Template': Record + } + resolvedValue: Record } export interface ConfigMapSecretDataDTO { resourceType: Extract data: ConfigMapSecretDataType + variableSnapshot: Record> + resolvedValue: string } export interface AppEnvDeploymentConfigDTO { @@ -222,16 +229,30 @@ export interface AppEnvDeploymentConfigDTO { isAppAdmin: boolean } -export interface AppEnvDeploymentConfigPayloadType { - appName: string - envName: string - configType: AppEnvDeploymentConfigType - identifierId?: number - pipelineId?: number - resourceType?: ConfigResourceType - resourceId?: number - resourceName?: string -} +export type AppEnvDeploymentConfigPayloadType = + | { + appName: string + envName: string + configType: AppEnvDeploymentConfigType + identifierId?: number + pipelineId?: number + resourceType?: ConfigResourceType + resourceId?: number + resourceName?: string + configArea?: 'AppConfiguration' + } + | { + appName: string + envName: string + configArea: 'ResolveData' + } + | { + appName: string + envName: string + pipelineId: number + configArea: 'CdRollback' | 'DeploymentHistory' + wfrId: number + } export enum TemplateListType { DefaultVersions = 1, From 90dd9f1bc549e4906d5d144fcdb806b4f6de307b Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 19 Sep 2024 15:50:30 +0530 Subject: [PATCH 05/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6fae21d1c..6a30ae1b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.6", + "version": "0.3.6-beta-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.6", + "version": "0.3.6-beta-4", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index f3f5011c1..04213f972 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.6", + "version": "0.3.6-beta-4", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From ee0f3b180be02fcdb202c0f0d6b1ac4413df72e6 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Mon, 23 Sep 2024 23:02:46 +0530 Subject: [PATCH 06/28] feat: TriggerOutput - DeploymentHistoryConfigDiff - revamp UI - using DeploymentConfigDiff --- src/Assets/Icon/ic-diff-file-added.svg | 10 + src/Assets/Icon/ic-diff-file-removed.svg | 10 + src/Assets/Icon/ic-file-code.svg | 7 + .../DeploymentHistoryConfigDiff.tsx | 241 ++++++++++++++++++ .../DeploymentHistoryConfigDiffCompare.tsx | 112 ++++++++ .../DeploymentHistoryDiffView.tsx | 5 +- .../DeploymentHistoryConfigDiff/helpers.tsx | 61 +++++ .../DeploymentHistoryConfigDiff/index.ts | 2 + .../styles.scss | 0 .../DeploymentHistoryConfigDiff/types.ts | 45 ++++ .../DeploymentHistoryConfigDiff/utils.ts | 49 ++++ .../DeploymentHistoryConfigList.component.tsx | 112 -------- .../DeploymentHistoryDetailedView.tsx | 132 ---------- .../DeploymentHistoryHeader.tsx | 179 ------------- .../DeploymentHistorySidebar.tsx | 77 ------ .../DeploymentHistoryDiff/index.tsx | 19 -- .../DeploymentHistoryDiff/types.tsx | 56 ---- .../DeploymentHistoryDiff/utils.tsx | 90 ------- .../Components/CICDHistory/TriggerOutput.tsx | 41 +-- .../Components/CICDHistory/cicdHistory.scss | 10 + src/Shared/Components/CICDHistory/index.tsx | 2 +- src/Shared/Components/CICDHistory/types.tsx | 8 +- .../CollapsibleList.component.tsx | 2 - .../Components/CollapsibleList/utils.ts | 30 --- .../DeploymentConfigDiff.component.tsx | 12 +- .../DeploymentConfigDiff.scss | 8 +- .../DeploymentConfigDiff.types.ts | 45 +++- .../DeploymentConfigDiff.utils.tsx | 203 ++++++++++++--- .../DeploymentConfigDiffAccordion.tsx | 22 +- .../DeploymentConfigDiffMain.tsx | 34 ++- .../DeploymentConfigDiffNavigation.tsx | 69 +++-- src/Shared/Helpers.tsx | 31 +++ src/Shared/Services/app.types.ts | 12 + 33 files changed, 903 insertions(+), 833 deletions(-) create mode 100644 src/Assets/Icon/ic-diff-file-added.svg create mode 100644 src/Assets/Icon/ic-diff-file-removed.svg create mode 100644 src/Assets/Icon/ic-file-code.svg create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx rename src/Shared/Components/CICDHistory/{DeploymentHistoryDiff => DeploymentHistoryConfigDiff}/DeploymentHistoryDiffView.tsx (97%) create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/index.ts rename src/Shared/Components/CICDHistory/{DeploymentHistoryDiff => DeploymentHistoryConfigDiff}/styles.scss (100%) create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts create mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryConfigList.component.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDetailedView.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryHeader.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistorySidebar.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/index.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/types.tsx delete mode 100644 src/Shared/Components/CICDHistory/DeploymentHistoryDiff/utils.tsx delete mode 100644 src/Shared/Components/CollapsibleList/utils.ts diff --git a/src/Assets/Icon/ic-diff-file-added.svg b/src/Assets/Icon/ic-diff-file-added.svg new file mode 100644 index 000000000..fd580b2d2 --- /dev/null +++ b/src/Assets/Icon/ic-diff-file-added.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/Assets/Icon/ic-diff-file-removed.svg b/src/Assets/Icon/ic-diff-file-removed.svg new file mode 100644 index 000000000..48bddae80 --- /dev/null +++ b/src/Assets/Icon/ic-diff-file-removed.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/Assets/Icon/ic-file-code.svg b/src/Assets/Icon/ic-file-code.svg new file mode 100644 index 000000000..304ac012f --- /dev/null +++ b/src/Assets/Icon/ic-file-code.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx new file mode 100644 index 000000000..45ef7a30d --- /dev/null +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx @@ -0,0 +1,241 @@ +import { useMemo, useRef, useState } from 'react' +import { generatePath, Route, Switch, useLocation, useRouteMatch } from 'react-router-dom' + +import { getAppEnvDeploymentConfigList, getDeploymentTemplateValues } from '@Shared/Components/DeploymentConfigDiff' +import { useAsync } from '@Common/Helper' +import { EnvResourceType, getAppEnvDeploymentConfig } from '@Shared/Services' +import { groupArrayByObjectKey } from '@Shared/Helpers' +import ErrorScreenManager from '@Common/ErrorScreenManager' +import { Progressing } from '@Common/Progressing' +import { useUrlFilters } from '@Common/Hooks' + +import { abortPreviousRequests, getIsRequestAborted } from '@Common/Api' +import { DeploymentHistoryConfigDiffCompare } from './DeploymentHistoryConfigDiffCompare' +import { DeploymentHistoryConfigDiffProps, DeploymentHistoryConfigDiffQueryParams } from './types' +import { getPipelineDeploymentsWfrIds, getPipelineDeployments, parseDeploymentHistoryDiffSearchParams } from './utils' +import { renderDeploymentHistoryConfig } from './helpers' + +export const DeploymentHistoryConfigDiff = ({ + appName, + envName, + pipelineId, + wfrId, + triggerHistory, + setFullScreenView, +}: DeploymentHistoryConfigDiffProps) => { + // HOOKS + const { path, params } = useRouteMatch() + const { pathname, search } = useLocation() + + // CONSTANTS + const pipelineDeployments = useMemo(() => getPipelineDeployments(triggerHistory), [triggerHistory]) + const { currentWfrId, previousWfrId } = useMemo( + () => getPipelineDeploymentsWfrIds({ pipelineDeployments, wfrId }), + [pipelineDeployments, wfrId], + ) + const isPreviousDeploymentConfigAvailable = !!previousWfrId + + // REFS + const deploymentTemplateResolvedDataAbortControllerRef = useRef(new AbortController()) + + // URL FILTERS + const { compareWfrId } = useUrlFilters({ + parseSearchParams: parseDeploymentHistoryDiffSearchParams(previousWfrId), + }) + + // STATES + const [convertVariables, setConvertVariables] = useState(false) + + // ASYNC CALLS + // Load comparison deployment data + const [ + compareDeploymentConfigLoader, + compareDeploymentConfig, + compareDeploymentConfigErr, + reloadCompareDeploymentConfig, + ] = useAsync( + () => + Promise.all([ + getAppEnvDeploymentConfig({ + params: { + appName, + envName, + configArea: 'DeploymentHistory', + pipelineId, + wfrId: currentWfrId, + }, + }), + isPreviousDeploymentConfigAvailable + ? getAppEnvDeploymentConfig({ + params: { + appName, + envName, + configArea: 'DeploymentHistory', + pipelineId, + wfrId: compareWfrId, + }, + }) + : null, + ]), + [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 + + 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, + ]) + + const groupedDeploymentConfigList = useMemo( + () => (deploymentConfigList ? groupArrayByObjectKey(deploymentConfigList.configList, 'groupHeader') : []), + [deploymentConfigList], + ) + + return ( + + + + + + {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( + + ) : ( +
+ {compareDeploymentConfigLoader || !deploymentConfigList ? ( + + ) : ( + <> +

+ Showing configuration change with respect to previous deployment +

+
+ {Object.keys(groupedDeploymentConfigList).map((groupHeader) => + renderDeploymentHistoryConfig( + groupedDeploymentConfigList[groupHeader], + groupHeader !== 'UNGROUPED' ? groupHeader : null, + pathname, + ), + )} +
+ + )} +
+ )} +
+
+ ) +} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx new file mode 100644 index 000000000..a407a8a32 --- /dev/null +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -0,0 +1,112 @@ +import { useEffect } from 'react' +import { generatePath, useRouteMatch } from 'react-router-dom' + +import { DeploymentConfigDiff, DeploymentConfigDiffProps } from '@Shared/Components/DeploymentConfigDiff' +import { SortingOrder } from '@Common/Constants' +import { useUrlFilters } from '@Common/Hooks' +import { + getSelectPickerOptionByValue, + SelectPickerOptionType, + SelectPickerVariantType, +} from '@Shared/Components/SelectPicker' + +import { DeploymentHistoryDiffDetailedProps, DeploymentHistoryConfigDiffQueryParams } from './types' +import { getPipelineDeploymentsOptions, parseDeploymentHistoryDiffSearchParams } from './utils' + +export const DeploymentHistoryConfigDiffCompare = ({ + envName, + setFullScreenView, + pipelineDeployments, + wfrId, + previousWfrId, + convertVariables, + setConvertVariables, + ...props +}: DeploymentHistoryDiffDetailedProps) => { + // HOOKS + const { path, params } = useRouteMatch() + + // URL FILTERS + const { compareWfrId, updateSearchParams, sortBy, sortOrder, handleSorting } = useUrlFilters< + 'sort-config' | '', + DeploymentHistoryConfigDiffQueryParams + >({ + parseSearchParams: parseDeploymentHistoryDiffSearchParams(previousWfrId), + }) + + useEffect(() => { + // Default Search Params Update + updateSearchParams({ compareWfrId }) + // Set fullscreen for comparing deployment history config + setFullScreenView(true) + + return () => { + setConvertVariables(false) + setFullScreenView(false) + } + }, []) + + // DEPLOYMENT_CONFIG_DIFF_PROPS + const { currentDeployment, pipelineDeploymentsOptions } = getPipelineDeploymentsOptions(pipelineDeployments, wfrId) + + 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, + }, + }, + ], + secondaryConfig: [ + { + id: 'base-configuration', + type: 'string', + text: `Deployed on ${currentDeployment}`, + }, + ], + } + + const onSorting = () => handleSorting(sortOrder !== SortingOrder.DESC ? 'sort-config' : '') + + const sortingConfig: DeploymentConfigDiffProps['sortingConfig'] = { + handleSorting: onSorting, + sortBy, + sortOrder, + } + + const scopeVariablesConfig: DeploymentConfigDiffProps['scopeVariablesConfig'] = { + convertVariables, + onConvertVariablesClick: () => setConvertVariables(!convertVariables), + } + + return ( + value === compareWfrId).label} & ${currentDeployment}` + : null + } + goBackURL={generatePath(path.split('/:resourceType')[0], params)} + selectorsConfig={selectorsConfig} + sortingConfig={sortingConfig} + scopeVariablesConfig={scopeVariablesConfig} + /> + ) +} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDiffView.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx similarity index 97% rename from src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDiffView.tsx rename to src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx index 15adb30ac..d7da03a79 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDiffView.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx @@ -34,7 +34,6 @@ const DeploymentHistoryDiffView = ({ isUnpublished, isDeleteDraft, rootClassName, - comparisonBodyClassName, sortOrder = null, }: DeploymentTemplateHistoryType) => { const { historyComponent, historyComponentName } = useParams() @@ -133,7 +132,7 @@ const DeploymentHistoryDiffView = ({
)}
{(currentConfiguration?.codeEditorValue?.value || baseTemplateConfiguration?.codeEditorValue?.value) && ( -
+
{ + const Icon = diffStateIconMap[diffState] + + return ( +
+ {Icon && } + {diffStateTextMap[diffState]} +
+ ) +} + +export const renderDeploymentHistoryConfig = ( + config: DeploymentConfigDiffProps['configList'], + heading: string, + pathname: string, +) => ( +
+ {heading && ( +
+

{heading}

+
+ )} + {config.map(({ id, title, diffState }, index) => { + const resourceType = (title.split('/')[0] || title).trim().toLowerCase().replace(' ', '-') + const resourceName = title.split('/')[1]?.trim() + + return ( + +

+ + {resourceName || title} +

+ {renderState(diffState)} +
+ ) + })} +
+) + +export const renderPipelineDeploymentStatusIcon = (status: string) => ( + +) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/index.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/index.ts new file mode 100644 index 000000000..ef8a5ead2 --- /dev/null +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/index.ts @@ -0,0 +1,2 @@ +export * from './DeploymentHistoryConfigDiff' +export { default as DeploymentHistoryDiffView } from './DeploymentHistoryDiffView' diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/styles.scss b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/styles.scss similarity index 100% rename from src/Shared/Components/CICDHistory/DeploymentHistoryDiff/styles.scss rename to src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/styles.scss diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts new file mode 100644 index 000000000..c3f91b9d5 --- /dev/null +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts @@ -0,0 +1,45 @@ +import { Dispatch, SetStateAction } from 'react' + +import { DeploymentConfigDiffProps } from '@Shared/Components/DeploymentConfigDiff' +import { EnvResourceType } from '@Shared/Services' + +import { History } from '../types' + +export interface DeploymentHistoryConfigDiffProps { + appName: string + envName: string + pipelineId: number + wfrId: number + triggerHistory: Map + setFullScreenView: (fullscreen: boolean) => void +} + +export type DeploymentHistoryDiffDetailedProps = Pick< + DeploymentConfigDiffProps, + 'collapsibleNavList' | 'configList' | 'errorConfig' | 'isLoading' | 'navList' +> & + Pick & { + pipelineDeployments: History[] + previousWfrId: number + convertVariables: boolean + setConvertVariables: Dispatch> + } + +export interface DeploymentHistoryConfigDiffQueryParams { + compareWfrId: number +} + +export interface DeploymentHistoryConfigDiffRouteParams { + resourceType: EnvResourceType + resourceName: string +} + +export interface DeploymentHistoryParamsType { + appId: string + pipelineId?: string + historyComponent?: string + baseConfigurationId?: string + historyComponentName?: string + envId?: string + triggerId?: string +} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts new file mode 100644 index 000000000..e17979e63 --- /dev/null +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts @@ -0,0 +1,49 @@ +import moment from 'moment' + +import { DATE_TIME_FORMATS } from '@Common/Constants' +import { DeploymentStageType } from '@Shared/constants' + +import { History } from '../types' +import { renderPipelineDeploymentStatusIcon } from './helpers' +import { DeploymentHistoryConfigDiffProps } from './types' + +export const getPipelineDeployments = (triggerHistory: DeploymentHistoryConfigDiffProps['triggerHistory']) => + Array.from(triggerHistory) + .filter(([, value]) => value?.stage === DeploymentStageType.DEPLOY) + .map(([, value]) => value) + +export const getPipelineDeploymentsWfrIds = ({ + pipelineDeployments, + wfrId, +}: { pipelineDeployments: History[] } & Pick) => { + const currentDeploymentIndex = pipelineDeployments.findIndex(({ id }) => id === wfrId) + const previousWfrId = currentDeploymentIndex > -1 ? pipelineDeployments[currentDeploymentIndex + 1]?.id : null + + return { + currentWfrId: wfrId, + previousWfrId: previousWfrId ?? null, + } +} + +export const getPipelineDeploymentsOptions = (pipelineDeployments: History[], wfrId: number) => { + const currentDeploymentIndex = pipelineDeployments.findIndex(({ id }) => id === wfrId) + const previousDeployments = pipelineDeployments.slice(currentDeploymentIndex + 1) + + const pipelineDeploymentsOptions = previousDeployments.map( + ({ id, finishedOn, stage, triggeredBy, triggeredByEmail, status }) => ({ + value: id, + label: moment(finishedOn).format(DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT), + description: `${stage} · ${triggeredBy === 1 ? 'auto trigger' : triggeredByEmail}`, + startIcon: renderPipelineDeploymentStatusIcon(status), + }), + ) + const currentDeployment = moment(pipelineDeployments[currentDeploymentIndex].finishedOn).format( + DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT, + ) + + return { currentDeployment, pipelineDeploymentsOptions } +} + +export const parseDeploymentHistoryDiffSearchParams = (compareWfrId: number) => (searchParams: URLSearchParams) => ({ + compareWfrId: +(searchParams.get('compareWfrId') || compareWfrId), +}) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryConfigList.component.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryConfigList.component.tsx deleted file mode 100644 index 58875ffd3..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryConfigList.component.tsx +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable no-nested-ternary */ -import { useEffect, useState } from 'react' -import { NavLink, useRouteMatch, useParams } from 'react-router-dom' -import { GenericEmptyState, Progressing } from '../../../../Common' -import { ReactComponent as ICChevron } from '../../../../Assets/Icon/ic-chevron-down.svg' -import { DeploymentHistoryParamsType, TemplateConfiguration } from './types' -import { getDeploymentHistoryList } from '../service' -import { EMPTY_STATE_STATUS, DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP } from '../../../constants' - -const DeploymentHistoryConfigList = ({ - setFullScreenView, - deploymentHistoryList, - setDeploymentHistoryList, -}: TemplateConfiguration) => { - const match = useRouteMatch() - const { appId, pipelineId, triggerId } = useParams() - const [deploymentListLoader, setDeploymentListLoader] = useState(false) - - useEffect(() => { - setDeploymentListLoader(true) - // eslint-disable-next-line @typescript-eslint/no-floating-promises - getDeploymentHistoryList(appId, pipelineId, triggerId).then((response) => { - setDeploymentHistoryList(response.result) - setDeploymentListLoader(false) - }) - }, [triggerId]) - - const getNavLink = ( - index: number, - componentId: number, - componentName: string, - key: string, - childComponentName?: string, - ) => { - const currentComponent = DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP[componentName] - const configURL = `${match.url}/${currentComponent.VALUE}/${componentId}${ - childComponentName ? `/${childComponentName}` : '' - }` - return ( - { - setFullScreenView(false) - }} - data-testid={`configuration-link-option-${index}`} - className="bcb-1 dc__no-decor bcn-0 cn-9 pl-16 pr-16 pt-12 pb-12 br-4 en-2 bw-1 flex dc__content-space cursor lh-20" - > - {childComponentName || currentComponent.DISPLAY_NAME} - - - ) - } - - return ( - // eslint-disable-next-line react/jsx-no-useless-fragment - <> - {!deploymentHistoryList && !deploymentListLoader ? ( - - ) : deploymentListLoader ? ( - - ) : ( - deploymentHistoryList && - deploymentHistoryList.map((historicalComponent, index) => ( - // eslint-disable-next-line react/no-array-index-key -
- {historicalComponent.childList?.length > 0 ? ( - <> -
- {DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP[historicalComponent.name].DISPLAY_NAME} -
- {historicalComponent.childList.map((historicalComponentName, childIndex) => - getNavLink( - index, - historicalComponent.id, - historicalComponent.name, - `config-${index}-${childIndex}`, - historicalComponentName, - ), - )} - - ) : ( - getNavLink(index, historicalComponent.id, historicalComponent.name, `config-${index}`) - )} -
- )) - )} - - ) -} - -export default DeploymentHistoryConfigList diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDetailedView.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDetailedView.tsx deleted file mode 100644 index 296aa3549..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryDetailedView.tsx +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useEffect, useState } from 'react' -import { useParams } from 'react-router-dom' -import { showError, Progressing } from '../../../../Common' -import DeploymentHistoryHeader from './DeploymentHistoryHeader' -import DeploymentHistoryDiffView from './DeploymentHistoryDiffView' -import DeploymentHistorySidebar from './DeploymentHistorySidebar' -import { CompareViewDeploymentType, DeploymentHistoryParamsType, DeploymentTemplateOptions } from './types' -import { DeploymentHistoryDetail } from '../types' -import { getDeploymentHistoryDetail, prepareHistoryData } from '../service' - -const DeploymentHistoryDetailedView = ({ - setFullScreenView, - deploymentHistoryList, - setDeploymentHistoryList, - renderRunSource, - resourceId, -}: CompareViewDeploymentType) => { - const { appId, pipelineId, historyComponent, baseConfigurationId, historyComponentName } = - useParams() - const [selectedDeploymentTemplate, setSelectedDeploymentTemplate] = useState() - const [currentConfiguration, setCurrentConfiguration] = useState() - const [baseTemplateConfiguration, setBaseTemplateConfiguration] = useState() - const [previousConfigAvailable, setPreviousConfigAvailable] = useState(true) - const [loader, setLoader] = useState(true) - - useEffect(() => { - if (selectedDeploymentTemplate) { - setLoader(true) - if (selectedDeploymentTemplate.value === 'NA') { - setLoader(false) - } else { - try { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - getDeploymentHistoryDetail( - appId, - pipelineId, - selectedDeploymentTemplate.value, - historyComponent, - historyComponentName, - ).then((response) => { - setCurrentConfiguration(prepareHistoryData(response.result, historyComponent)) - setLoader(false) - }) - } catch (err) { - showError(err) - setLoader(false) - } - } - } - }, [selectedDeploymentTemplate]) - - useEffect(() => { - try { - setLoader(true) - setSelectedDeploymentTemplate(null) - setCurrentConfiguration(null) - // eslint-disable-next-line @typescript-eslint/no-floating-promises - getDeploymentHistoryDetail( - appId, - pipelineId, - baseConfigurationId, - historyComponent, - historyComponentName, - ).then((response) => { - setBaseTemplateConfiguration(prepareHistoryData(response.result, historyComponent)) - }) - } catch (err) { - showError(err) - setLoader(false) - } - }, [baseConfigurationId, historyComponent, historyComponentName]) - - useEffect(() => { - // show template showing historical diff detailed view - // in case if !showTemplate CD detail component being rendered - setFullScreenView(true) - - return (): void => { - setFullScreenView(false) - } - }, []) - - return ( - <> - - -
- - {loader ? ( - - ) : ( -
- -
- )} -
- - ) -} - -export default DeploymentHistoryDetailedView diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryHeader.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryHeader.tsx deleted file mode 100644 index 2bb22524d..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistoryHeader.tsx +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useEffect, useState } from 'react' -import ReactSelect from 'react-select' -import { useHistory, useRouteMatch, useParams, NavLink } from 'react-router-dom' -import moment from 'moment' -import Tippy from '@tippyjs/react' -import { DATE_TIME_FORMATS, URLS, showError } from '../../../../Common' -import { DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP } from '../../../constants' -import { ReactComponent as LeftIcon } from '../../../../Assets/Icon/ic-arrow-backward.svg' -import { DeploymentTemplateOptions, DeploymentHistoryParamsType, CompareWithBaseConfiguration } from './types' -import { getDeploymentDiffSelector } from '../service' -import { dropdownStyles, Option } from './utils' - -const DeploymentHistoryHeader = ({ - selectedDeploymentTemplate, - setSelectedDeploymentTemplate, - setFullScreenView, - setLoader, - setPreviousConfigAvailable, - renderRunSource, - resourceId, -}: CompareWithBaseConfiguration) => { - const { url } = useRouteMatch() - const history = useHistory() - const { pipelineId, historyComponent, baseConfigurationId, historyComponentName } = - useParams() - const [baseTemplateTimeStamp, setBaseTemplateTimeStamp] = useState('') - const [deploymentTemplateOption, setDeploymentTemplateOption] = useState([]) - - const onClickTimeStampSelector = (selected: { label: string; value: string }) => { - setSelectedDeploymentTemplate(selected) - } - - useEffect(() => { - if (pipelineId && historyComponent && baseConfigurationId) { - try { - setLoader(true) - // eslint-disable-next-line @typescript-eslint/no-floating-promises - getDeploymentDiffSelector(pipelineId, historyComponent, baseConfigurationId, historyComponentName).then( - (response) => { - const deploymentTemplateOpt = [] - if (response.result) { - const resultLen = response.result.length - for (let i = 0; i < resultLen; i++) { - if (response.result[i].id.toString() === baseConfigurationId) { - setBaseTemplateTimeStamp(response.result[i].deployedOn) - } else { - deploymentTemplateOpt.push({ - value: String(response.result[i].id), - label: moment(response.result[i].deployedOn).format( - DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT, - ), - author: response.result[i].deployedBy, - status: response.result[i].deploymentStatus, - runSource: response.result[i].runSource, - renderRunSource, - resourceId, - }) - } - } - } - setPreviousConfigAvailable(deploymentTemplateOpt.length > 0) - setDeploymentTemplateOption(deploymentTemplateOpt) - setSelectedDeploymentTemplate( - deploymentTemplateOpt[0] || { - label: 'NA', - value: 'NA', - author: 'NA', - status: 'NA', - runSource: null, - }, - ) - }, - ) - } catch (err) { - showError(err) - setLoader(false) - } - } - }, [historyComponent, baseConfigurationId, historyComponentName]) - - const renderGoBackToConfiguration = () => ( - { - e.preventDefault() - setFullScreenView(false) - history.push( - `${url.split(URLS.DEPLOYMENT_HISTORY_CONFIGURATIONS)[0]}${URLS.DEPLOYMENT_HISTORY_CONFIGURATIONS}`, - ) - }} - > - - - ) - - const renderCompareDeploymentConfig = () => ( -
-
- Compare with -
-
- {deploymentTemplateOption.length > 0 ? ( - - ) : ( -
- - { - DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP[ - historyComponent.replace('-', '_').toUpperCase() - ]?.DISPLAY_NAME - } - {historyComponentName ? ` “${historyComponentName}”` : ''} was added in this - deployment. There is no previous instance to compare with. - - } - > - No options - -
- )} -
-
- ) - - const renderBaseDeploymentConfig = () => ( -
- - Base configuration - -
- {baseTemplateTimeStamp && moment(baseTemplateTimeStamp).format(DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT)} -
-
- ) - return ( -
- {renderGoBackToConfiguration()} - {renderCompareDeploymentConfig()} - {renderBaseDeploymentConfig()} -
- ) -} - -export default DeploymentHistoryHeader diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistorySidebar.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistorySidebar.tsx deleted file mode 100644 index 3763fd8e1..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/DeploymentHistorySidebar.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useEffect } from 'react' -import { NavLink, useRouteMatch, useParams } from 'react-router-dom' -import { DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP } from '../../../constants' -import { DeploymentHistoryParamsType } from './types' -import { getDeploymentHistoryList } from '../service' -import { DeploymentHistorySidebarType } from '../types' -import { URLS } from '../../../../Common' - -const DeploymentHistorySidebar = ({ - deploymentHistoryList, - setDeploymentHistoryList, -}: DeploymentHistorySidebarType) => { - const match = useRouteMatch() - const { appId, pipelineId, triggerId } = useParams() - useEffect(() => { - if (!deploymentHistoryList) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - getDeploymentHistoryList(appId, pipelineId, triggerId).then((response) => { - setDeploymentHistoryList(response.result) - }) - } - }, [deploymentHistoryList]) - - const getNavLink = (componentId: number, componentName: string, key: string, childComponentName?: string) => { - const currentComponent = DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP[componentName] - const childComponentDetail = childComponentName ? `/${childComponentName}` : '' - const configURL = `${match.url.split(URLS.DEPLOYMENT_HISTORY_CONFIGURATIONS)[0]}${ - URLS.DEPLOYMENT_HISTORY_CONFIGURATIONS - }/${currentComponent.VALUE}/${componentId}${childComponentDetail}` - return ( -
- - {currentComponent.DISPLAY_NAME + childComponentDetail} - -
- ) - } - - return ( -
- {deploymentHistoryList?.map((historicalComponent, index) => - historicalComponent.childList?.length > 0 - ? historicalComponent.childList.map((historicalComponentName, childIndex) => - getNavLink( - historicalComponent.id, - historicalComponent.name, - `config-${index}-${childIndex}`, - historicalComponentName, - ), - ) - : getNavLink(historicalComponent.id, historicalComponent.name, `config-${index}`), - )} -
- ) -} - -export default DeploymentHistorySidebar diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/index.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/index.tsx deleted file mode 100644 index 94dcac337..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as DeploymentHistoryDetailedView } from './DeploymentHistoryDetailedView' -export { default as DeploymentHistoryConfigList } from './DeploymentHistoryConfigList.component' -export { default as DeploymentHistoryDiffView } from './DeploymentHistoryDiffView' diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/types.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/types.tsx deleted file mode 100644 index 74879b908..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/types.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OptionType } from '../../../../Common' -import { DeploymentTemplateList, RunSourceType, RenderRunSourceType } from '../types' - -export interface DeploymentHistoryParamsType { - appId: string - pipelineId?: string - historyComponent?: string - baseConfigurationId?: string - historyComponentName?: string - envId?: string - triggerId?: string -} - -export interface CompareViewDeploymentType extends RenderRunSourceType { - setFullScreenView: React.Dispatch> - deploymentHistoryList: DeploymentTemplateList[] - setDeploymentHistoryList: React.Dispatch> - resourceId?: number -} - -export interface DeploymentTemplateOptions extends OptionType { - author: string - status: string - runSource?: RunSourceType -} - -export interface CompareWithBaseConfiguration extends RenderRunSourceType { - selectedDeploymentTemplate: DeploymentTemplateOptions - setSelectedDeploymentTemplate: (selected) => void - setFullScreenView: React.Dispatch> - setLoader: React.Dispatch> - setPreviousConfigAvailable: React.Dispatch> - resourceId?: number -} - -export interface TemplateConfiguration { - setFullScreenView: React.Dispatch> - deploymentHistoryList: DeploymentTemplateList[] - setDeploymentHistoryList: React.Dispatch> -} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/utils.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/utils.tsx deleted file mode 100644 index 60470a4dd..000000000 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryDiff/utils.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { components } from 'react-select' -import { multiSelectStyles } from '../../../../Common/MultiSelectCustomization' - -export const dropdownStyles = { - ...multiSelectStyles, - menu: (base) => ({ ...base, zIndex: 9999, textAlign: 'left', width: '150%' }), - control: (base) => ({ - ...base, - backgroundColor: 'transparent', - minHeight: '12px', - cursor: 'pointer', - border: 0, - outline: 'none', - boxShadow: 'none', - fontSize: '13px', - }), - singleValue: (base) => ({ - ...base, - fontWeight: 600, - color: '#06c', - marginLeft: 0, - }), - option: (base, state) => ({ - ...base, - backgroundColor: state.isFocused ? 'var(--N100)' : 'white', - color: 'var(--N900)', - textOverflow: 'ellipsis', - overflow: 'hidden', - whiteSpace: 'nowrap', - cursor: 'pointer', - padding: '0 4px', - }), - valueContainer: (base) => ({ - ...base, - height: '20px', - padding: 0, - }), - indicatorsContainer: (base) => ({ - ...base, - padding: 0, - }), - dropdownIndicator: (styles) => ({ ...styles, padding: 0 }), -} - -export const Option = (props: any) => { - const { - isSelected, - data: { status, author, runSource, renderRunSource, resourceId }, - label, - } = props - return ( - -
-
-
-
-
{label}
-
- Deploy  -
-   - {author === 'system' ? 'auto-triggered' : author} -
-
- {runSource && renderRunSource && renderRunSource(runSource, resourceId === runSource.id)} -
-
- - ) -} diff --git a/src/Shared/Components/CICDHistory/TriggerOutput.tsx b/src/Shared/Components/CICDHistory/TriggerOutput.tsx index 96f6ea2e2..e66fd1030 100644 --- a/src/Shared/Components/CICDHistory/TriggerOutput.tsx +++ b/src/Shared/Components/CICDHistory/TriggerOutput.tsx @@ -66,7 +66,7 @@ import { GitTriggers } from '../../types' import warn from '../../../Assets/Icon/ic-warning.svg' import { LogsRenderer } from './LogsRenderer' import DeploymentDetailSteps from './DeploymentDetailSteps' -import { DeploymentHistoryDetailedView, DeploymentHistoryConfigList } from './DeploymentHistoryDiff' +import { DeploymentHistoryConfigDiff } from './DeploymentHistoryConfigDiff' import { GitChanges, Scroller } from './History.components' import Artifacts from './Artifacts' import { statusColor as colorMap, EMPTY_STATE_STATUS, PULSATING_STATUS_MAP } from '../../constants' @@ -488,8 +488,6 @@ const HistoryLogs: React.FC = ({ triggerDetails, loading, setFullScreenView, - deploymentHistoryList, - setDeploymentHistoryList, deploymentAppType, isBlobStorageConfigured, userApprovalMetadata, @@ -500,8 +498,6 @@ const HistoryLogs: React.FC = ({ tagsEditable, hideImageTaggingHardDelete, selectedEnvironmentName, - resourceId, - renderRunSource, processVirtualEnvironmentDeploymentData, renderDeploymentApprovalInfo, renderCIListHeader, @@ -509,6 +505,8 @@ const HistoryLogs: React.FC = ({ scrollToTop, scrollToBottom, fullScreenView, + appName, + triggerHistory, }) => { const { path } = useRouteMatch() const { appId, pipelineId, triggerId, envId } = useParams<{ @@ -528,7 +526,7 @@ const HistoryLogs: React.FC = ({ const CDBuildReportUrl = `app/cd-pipeline/workflow/download/${appId}/${envId}/${pipelineId}/${triggerId}` return ( -
+
{loading ? ( ) : ( @@ -591,24 +589,14 @@ const HistoryLogs: React.FC = ({ /> {triggerDetails.stage === 'DEPLOY' && ( - - - - )} - {triggerDetails.stage === 'DEPLOY' && ( - - + )} @@ -662,8 +650,6 @@ const TriggerOutput = ({ triggerHistory, setTriggerHistory, setFullScreenView, - setDeploymentHistoryList, - deploymentHistoryList, deploymentAppType, isBlobStorageConfigured, appReleaseTags, @@ -683,6 +669,7 @@ const TriggerOutput = ({ scrollToTop, scrollToBottom, renderTargetConfigInfo, + appName, }: TriggerOutputProps) => { const { appId, triggerId, envId, pipelineId } = useParams<{ appId: string @@ -913,8 +900,6 @@ const TriggerOutput = ({ userApprovalMetadata={triggerDetailsResult?.result?.userApprovalMetadata} triggeredByEmail={triggerDetailsResult?.result?.triggeredByEmail} setFullScreenView={setFullScreenView} - setDeploymentHistoryList={setDeploymentHistoryList} - deploymentHistoryList={deploymentHistoryList} deploymentAppType={deploymentAppType} isBlobStorageConfigured={isBlobStorageConfigured} artifactId={triggerDetailsResult?.result?.artifactId} @@ -932,6 +917,8 @@ const TriggerOutput = ({ scrollToTop={scrollToTop} scrollToBottom={scrollToBottom} fullScreenView={fullScreenView} + appName={appName} + triggerHistory={triggerHistory} /> ) diff --git a/src/Shared/Components/CICDHistory/cicdHistory.scss b/src/Shared/Components/CICDHistory/cicdHistory.scss index a834f2fe9..45cdc6f26 100644 --- a/src/Shared/Components/CICDHistory/cicdHistory.scss +++ b/src/Shared/Components/CICDHistory/cicdHistory.scss @@ -134,6 +134,16 @@ display: grid; grid-template-columns: 50% 50%; grid-template-rows: auto; + position: relative; + + &::after { + content: ''; + position: absolute; + width: 1px; + height: 100%; + left: calc(50% - 1px); + background: var(--N200); + } } .historical-diff__left { diff --git a/src/Shared/Components/CICDHistory/index.tsx b/src/Shared/Components/CICDHistory/index.tsx index 55f027204..8b53a4c78 100644 --- a/src/Shared/Components/CICDHistory/index.tsx +++ b/src/Shared/Components/CICDHistory/index.tsx @@ -27,6 +27,6 @@ export * from './History.components' export * from './utils' export * from './TriggerOutput' export * from './LogsRenderer' -export * from './DeploymentHistoryDiff' +export * from './DeploymentHistoryConfigDiff' export * from './CiPipelineSourceConfig' export * from './StatusFilterButtonComponent' diff --git a/src/Shared/Components/CICDHistory/types.tsx b/src/Shared/Components/CICDHistory/types.tsx index 9203727dd..b7a85ba55 100644 --- a/src/Shared/Components/CICDHistory/types.tsx +++ b/src/Shared/Components/CICDHistory/types.tsx @@ -377,14 +377,13 @@ export interface TriggerOutputProps extends RenderRunSourceType, Pick setFullScreenView: React.Dispatch> - deploymentHistoryList: DeploymentTemplateList[] - setDeploymentHistoryList: React.Dispatch> deploymentAppType: DeploymentAppTypes isBlobStorageConfigured: boolean appReleaseTags: string[] tagsEditable: boolean hideImageTaggingHardDelete: boolean fetchIdData: FetchIdDataStatus + appName: string selectedEnvironmentName?: string renderCIListHeader?: (renderCIListHeaderProps: RenderCIListHeaderProps) => JSX.Element renderDeploymentApprovalInfo?: (userApprovalMetadata: UserApprovalMetadataType) => JSX.Element @@ -407,8 +406,6 @@ export interface HistoryLogsProps | 'scrollToTop' | 'scrollToBottom' | 'setFullScreenView' - | 'deploymentHistoryList' - | 'setDeploymentHistoryList' | 'deploymentAppType' | 'isBlobStorageConfigured' | 'appReleaseTags' @@ -420,6 +417,8 @@ export interface HistoryLogsProps | 'renderCIListHeader' | 'renderVirtualHistoryArtifacts' | 'fullScreenView' + | 'appName' + | 'triggerHistory' > { triggerDetails: History loading: boolean @@ -478,7 +477,6 @@ export interface DeploymentTemplateHistoryType { isUnpublished?: boolean isDeleteDraft?: boolean rootClassName?: string - comparisonBodyClassName?: string sortOrder?: SortingOrder } export interface DeploymentHistoryDetailRes extends ResponseType { diff --git a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index c394cc366..8b2569c3e 100644 --- a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx +++ b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx @@ -7,7 +7,6 @@ import { ReactComponent as ICExpand } from '@Icons/ic-expand.svg' import { Collapse } from '../Collapse' import { CollapsibleListProps } from './CollapsibleList.types' -import { checkNavLinkActiveState } from './utils' import './CollapsibleList.scss' const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElement) => ( @@ -67,7 +66,6 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP key={title} to={href} className="collapsible__item flexbox dc__align-items-center dc__gap-8 dc__no-decor br-4 py-6 px-8 cursor" - isActive={checkNavLinkActiveState(href)} onClick={(e) => { // Prevent navigation to the same page if (href === pathname) { diff --git a/src/Shared/Components/CollapsibleList/utils.ts b/src/Shared/Components/CollapsibleList/utils.ts deleted file mode 100644 index 5a8500da9..000000000 --- a/src/Shared/Components/CollapsibleList/utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { NavLinkProps } from 'react-router-dom' - -/** - * Determines if a navigation link is active based on the current location. - * - * This function checks if the provided `href` matches the current location's pathname - * and/or search query, and returns a boolean indicating whether the link should be considered active. - * - * @param href - The target URL or path to compare against the current location. - * - * @returns A function that takes the current location and returns a boolean: - * - `true` if the `href` matches the current location's pathname and/or search query. - * - `false` otherwise. - */ -export const checkNavLinkActiveState = - (href: string): NavLinkProps['isActive'] => - (_, location) => { - const [pathString, queryString] = href.split('?') - - if (pathString && queryString) { - return `${location.pathname}${location.search}` === href - } - if (pathString) { - return location.pathname === pathString - } - if (queryString) { - return location.search === `?${queryString}` - } - return false - } diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx index 7c48506d8..fd445efcf 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx @@ -12,9 +12,11 @@ export const DeploymentConfigDiff = ({ navHeading, navHelpText, tabConfig, + showDetailedDiffState, + renderedInDrawer, ...resProps }: DeploymentConfigDiffProps) => ( -
+
+ -
) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss index 85a346b89..e5f8a18d5 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.scss @@ -3,6 +3,10 @@ grid-template-columns: 255px 1fr; height: 100%; + &--drawer { + grid-template-columns: 220px 1fr; + } + &__accordion { scroll-margin-top: 12px; } @@ -26,10 +30,6 @@ grid-template-columns: calc(50% - 15px) calc(50% - 15px); grid-template-rows: auto; } - - &__comparison { - margin: 16px 0 0; - } } & .react-monaco-editor-container { diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts index 4e8165558..35176fcdb 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -13,6 +13,13 @@ import { CollapsibleListConfig, CollapsibleListItem } from '../CollapsibleList' import { SelectPickerProps } from '../SelectPicker' import { CollapseProps } from '../Collapse' +export enum DeploymentConfigDiffState { + NO_DIFF = 'noDiff', + HAS_DIFF = 'hasDiff', + ADDED = 'added', + DELETED = 'deleted', +} + export interface DeploymentConfigType { list: DeploymentHistoryDetail heading: React.ReactNode @@ -23,8 +30,9 @@ export interface DeploymentConfigListItem { title: string primaryConfig: DeploymentConfigType secondaryConfig: DeploymentConfigType - hasDiff?: boolean - isDeploymentTemplate?: boolean + diffState: DeploymentConfigDiffState + singleView?: boolean + groupHeader?: string } export type DeploymentConfigDiffSelectPickerProps = @@ -42,7 +50,7 @@ export type DeploymentConfigDiffSelectPickerProps = } export interface DeploymentConfigDiffNavigationItem extends Pick { - hasDiff?: boolean + diffState: DeploymentConfigListItem['diffState'] } export interface DeploymentConfigDiffNavigationCollapsibleItem @@ -58,6 +66,7 @@ export interface DeploymentConfigDiffProps { reload: () => void } configList: DeploymentConfigListItem[] + showDetailedDiffState?: boolean headerText?: string scrollIntoViewId?: string selectorsConfig: { @@ -84,12 +93,20 @@ export interface DeploymentConfigDiffProps { convertVariables: boolean onConvertVariablesClick: () => void } + renderedInDrawer?: boolean } export interface DeploymentConfigDiffNavigationProps extends Pick< DeploymentConfigDiffProps, - 'isLoading' | 'navList' | 'collapsibleNavList' | 'goBackURL' | 'navHeading' | 'navHelpText' | 'tabConfig' + | 'isLoading' + | 'navList' + | 'collapsibleNavList' + | 'goBackURL' + | 'navHeading' + | 'navHelpText' + | 'tabConfig' + | 'showDetailedDiffState' > {} export interface DeploymentConfigDiffMainProps @@ -103,16 +120,18 @@ export interface DeploymentConfigDiffMainProps | 'selectorsConfig' | 'sortingConfig' | 'scopeVariablesConfig' + | 'showDetailedDiffState' > {} -export interface DeploymentConfigDiffAccordionProps extends Pick { - id: string - title: string - children: React.ReactNode - hasDiff?: boolean - isExpanded?: boolean - onClick?: (e: React.MouseEvent) => void -} +export type DeploymentConfigDiffAccordionProps = Pick & + Pick & { + id: string + title: string + children: React.ReactNode + diffState: DeploymentConfigDiffState + isExpanded?: boolean + onClick?: (e: React.MouseEvent) => void + } export type DiffHeadingDataType = DeploymentTemplate extends true ? DeploymentTemplateDTO @@ -122,12 +141,10 @@ export type AppEnvDeploymentConfigListParams = (IsManifestView e ? { currentList: ManifestTemplateDTO compareList: ManifestTemplateDTO - sortOrder?: never } : { currentList: AppEnvDeploymentConfigDTO compareList: AppEnvDeploymentConfigDTO - sortOrder?: SortingOrder }) & { getNavItemHref: (resourceType: EnvResourceType, resourceName: string) => string isManifestView?: IsManifestView diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index 35df165b2..cd012b85d 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -1,13 +1,18 @@ +import { FunctionComponent, SVGProps } from 'react' + import { ReactComponent as ICCheck } from '@Icons/ic-check.svg' import { ReactComponent as ICStamp } from '@Icons/ic-stamp.svg' import { ReactComponent as ICEditFile } from '@Icons/ic-edit-file.svg' -import { stringComparatorBySortOrder, yamlComparatorBySortOrder } from '@Shared/Helpers' +import { ReactComponent as ICDiffFileUpdated } from '@Icons/ic-diff-file-updated.svg' +import { ReactComponent as ICDiffFileAdded } from '@Icons/ic-diff-file-added.svg' +import { ReactComponent as ICDiffFileRemoved } from '@Icons/ic-diff-file-removed.svg' +import { stringComparatorBySortOrder } from '@Shared/Helpers' import { DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP } from '@Shared/constants' -import { YAMLStringify } from '@Common/Helper' -import { SortingOrder } from '@Common/Constants' import { AppEnvDeploymentConfigListParams, DeploymentConfigDiffProps, + DeploymentConfigDiffState, + DeploymentHistoryDetail, DiffHeadingDataType, prepareHistoryData, } from '@Shared/Components' @@ -20,10 +25,23 @@ import { DraftState, EnvResourceType, ManifestTemplateDTO, + PipelineConfigDataDTO, TemplateListDTO, TemplateListType, } from '../../Services/app.types' +export const getDeploymentTemplateData = (data: DeploymentTemplateDTO) => { + const parsedDraftData = JSON.parse(data?.deploymentDraftData?.configData[0].draftMetadata.data || null) + + return ( + parsedDraftData?.envOverrideValues || + parsedDraftData?.valuesOverride || + parsedDraftData?.defaultAppOverride || + data?.data || + null + ) +} + /** * Retrieves the draft data from the given configuration data object. * @@ -214,6 +232,29 @@ const getCodeEditorData = ( return { compareToCodeEditorData, compareWithCodeEditorData } } +/** + * Compares two string values and returns the appropriate deployment configuration difference state. + * + * @param compareToValue - The original value to compare. + * @param compareWithValue - The new value to compare against the original. + * @returns `DeploymentConfigDiffState` enum value indicating the difference between the two values + */ +const getDiffState = (compareToValue: string, compareWithValue: string) => { + if (!compareToValue && compareWithValue) { + return DeploymentConfigDiffState.DELETED + } + + if (compareToValue && !compareWithValue) { + return DeploymentConfigDiffState.ADDED + } + + if (compareToValue !== compareWithValue) { + return DeploymentConfigDiffState.HAS_DIFF + } + + return DeploymentConfigDiffState.NO_DIFF +} + /** * Prepares the data for displaying the diff view between two configuration items. * @@ -260,37 +301,27 @@ const getDiffViewData = ( type === ConfigResourceType.Secret && !compareWithIsAdmin, ) - // Check if there is a difference between the compareTo and compareWith data - const hasDiff = compareWithCodeEditorData.value !== compareToCodeEditorData.value - // Return the combined diff data return { compareToDiff, compareWithDiff, - hasDiff, + diffState: getDiffState(compareToCodeEditorData.value, compareWithCodeEditorData.value), } } -const getDeploymentTemplateDiffViewData = (data: DeploymentTemplateDTO | null, sortOrder: SortingOrder) => { - const parsedDraftData = JSON.parse(data?.deploymentDraftData?.configData[0].draftMetadata.data || null) - const _data = - parsedDraftData?.envOverrideValues || - parsedDraftData?.valuesOverride || - parsedDraftData?.defaultAppOverride || - data?.data || - null - +const getDeploymentTemplateDiffViewData = (data: DeploymentTemplateDTO | null) => { + const _data = getDeploymentTemplateData(data) const codeEditorValue = { displayName: 'data', - value: _data - ? YAMLStringify(_data, { - sortMapEntries: (a, b) => yamlComparatorBySortOrder(a, b, sortOrder), - }) ?? '' - : '', + value: _data ? JSON.stringify(_data) : '', } const diffViewData = prepareHistoryData( - { codeEditorValue }, + { + ...(data || {}), + isAppMetricsEnabled: data ? data.isAppMetricsEnabled || false : null, + codeEditorValue, + }, DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP.DEPLOYMENT_TEMPLATE.VALUE, ) @@ -311,6 +342,20 @@ const getManifestDiffViewData = (data: ManifestTemplateDTO) => { return diffViewData } +const getPipelineConfigDiffViewData = (data: PipelineConfigDataDTO) => { + const codeEditorValue = { + displayName: 'data', + value: data?.data ? JSON.stringify(data.data) : '', + } + + const diffViewData = prepareHistoryData( + { ...(data || {}), strategy: data?.Strategy, codeEditorValue }, + DEPLOYMENT_HISTORY_CONFIGURATION_LIST_MAP.PIPELINE_STRATEGY.VALUE, + ) + + return diffViewData +} + const getDiffHeading = ( data: DiffHeadingDataType, deploymentTemplate?: DeploymentTemplate, @@ -410,7 +455,7 @@ const getConfigMapSecretData = ( ) const deploymentConfig = combinedList.map(([currentItem, compareItem]) => { - const { compareToDiff, compareWithDiff, hasDiff } = getDiffViewData( + const { compareToDiff, compareWithDiff, diffState } = getDiffViewData( currentItem, compareItem, resourceType, @@ -430,7 +475,8 @@ const getConfigMapSecretData = ( heading: getDiffHeading(currentItem), list: compareToDiff, }, - hasDiff, + diffState, + groupHeader: resourceType === ConfigResourceType.ConfigMap ? 'CONFIGMAPS' : 'SECRETS', } }) @@ -469,7 +515,6 @@ export const getAppEnvDeploymentConfigList = ['compareList'], compareDeploymentTemplateResolvedData, ) - const currentDeploymentData = getDeploymentTemplateDiffViewData(_currentList.deploymentTemplate, sortOrder) - const compareDeploymentData = getDeploymentTemplateDiffViewData(_compareList.deploymentTemplate, sortOrder) + const currentDeploymentData = getDeploymentTemplateDiffViewData(_currentList.deploymentTemplate) + const compareDeploymentData = getDeploymentTemplateDiffViewData(_compareList.deploymentTemplate) const deploymentTemplateData = { id: EnvResourceType.DeploymentTemplate, @@ -501,8 +546,35 @@ export const getAppEnvDeploymentConfigList = { const element = document.querySelector(`#${deploymentTemplateData.id}`) element?.scrollIntoView({ block: 'start' }) }, }, + ...(pipelineConfigData + ? [ + { + title: pipelineConfigData.title, + diffState: pipelineConfigData.diffState, + href: getNavItemHref(EnvResourceType.PipelineConfiguration, null), + onClick: () => { + const element = document.querySelector(`#${pipelineConfigData.id}`) + element?.scrollIntoView({ block: 'start' }) + }, + }, + ] + : []), ] const collapsibleNavList: DeploymentConfigDiffProps['collapsibleNavList'] = [ { header: 'ConfigMaps', id: EnvResourceType.ConfigMap, - items: cmData.map(({ name, hasDiff, id }) => ({ + items: cmData.map(({ name, diffState, id }) => ({ title: name, - hasDiff, + diffState, href: getNavItemHref(EnvResourceType.ConfigMap, name), onClick: () => { const element = document.querySelector(`#${id}`) @@ -555,9 +645,9 @@ export const getAppEnvDeploymentConfigList = ({ + items: secretData.map(({ name, diffState, id }) => ({ title: name, - hasDiff, + diffState, href: getNavItemHref(EnvResourceType.Secret, name), onClick: () => { const element = document.querySelector(`#${id}`) @@ -592,8 +682,8 @@ export const getAppEnvDeploymentConfigList = Generated Manifest, list: currentManifestData, }, - hasDiff: currentManifestData.codeEditorValue.value !== compareManifestData.codeEditorValue.value, - isDeploymentTemplate: true, + diffState: getDiffState(currentManifestData.codeEditorValue.value, compareManifestData.codeEditorValue.value), + singleView: true, } const configList: DeploymentConfigDiffProps['configList'] = [manifestData] @@ -601,7 +691,7 @@ export const getAppEnvDeploymentConfigList = { const element = document.querySelector(`#${manifestData.id}`) @@ -617,6 +707,15 @@ 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) => ({ @@ -637,3 +736,31 @@ export const getDefaultVersionAndPreviousDeploymentOptions = (data: TemplateList previousDeployments: [], }, ) + +export const diffStateTextMap: Record = { + hasDiff: 'Has difference', + added: 'Added', + deleted: 'Deleted', + noDiff: 'No change', +} + +export const diffStateIconMap: Record>> = { + hasDiff: ICDiffFileUpdated, + added: ICDiffFileAdded, + deleted: ICDiffFileRemoved, + noDiff: null, +} + +export const diffStateTooltipTextMap: Record = { + hasDiff: 'File has difference', + added: 'File has been added', + deleted: 'File has been deleted', + noDiff: null, +} + +export const diffStateTextColorMap: Record = { + hasDiff: 'cy-7', + added: 'cg-5', + deleted: 'cr-5', + noDiff: 'cn-7', +} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx index 64b720431..1ac28404e 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx @@ -3,11 +3,21 @@ import { forwardRef } from 'react' import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg' import { Collapse } from '../Collapse' -import { DeploymentConfigDiffAccordionProps } from './DeploymentConfigDiff.types' +import { DeploymentConfigDiffAccordionProps, DeploymentConfigDiffState } from './DeploymentConfigDiff.types' +import { diffStateTextColorMap, diffStateTextMap } from './DeploymentConfigDiff.utils' export const DeploymentConfigDiffAccordion = forwardRef( ( - { hasDiff, children, title, id, isExpanded, onClick, onTransitionEnd }: DeploymentConfigDiffAccordionProps, + { + diffState, + showDetailedDiffState, + children, + title, + id, + isExpanded, + onClick, + onTransitionEnd, + }: DeploymentConfigDiffAccordionProps, ref, ) => (
@@ -23,8 +33,12 @@ export const DeploymentConfigDiffAccordion = forwardRef

{title}

{`${hasDiff ? 'Has' : 'No'} difference`}

+ className={`m-0 fs-13 lh-20 fw-6 ${showDetailedDiffState ? diffStateTextColorMap[diffState] : (diffState !== DeploymentConfigDiffState.NO_DIFF && 'cy-7') || 'cg-7'}`} + > + {showDetailedDiffState + ? diffStateTextMap[diffState] + : `${diffState !== DeploymentConfigDiffState.NO_DIFF ? 'Has' : 'No'} difference`} +

{children} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index ce38194cd..548c50883 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -15,7 +15,11 @@ import { Button, ButtonStyleType, ButtonVariantType } from '../Button' import { SelectPicker } from '../SelectPicker' import { DeploymentHistoryDiffView } from '../CICDHistory' import { DeploymentConfigDiffAccordion } from './DeploymentConfigDiffAccordion' -import { DeploymentConfigDiffMainProps, DeploymentConfigDiffSelectPickerProps } from './DeploymentConfigDiff.types' +import { + DeploymentConfigDiffMainProps, + DeploymentConfigDiffSelectPickerProps, + DeploymentConfigDiffState, +} from './DeploymentConfigDiff.types' export const DeploymentConfigDiffMain = ({ isLoading, @@ -26,6 +30,7 @@ export const DeploymentConfigDiffMain = ({ sortingConfig, scrollIntoViewId, scopeVariablesConfig, + showDetailedDiffState, }: DeploymentConfigDiffMainProps) => { // STATES const [expandedView, setExpandedView] = useState>({}) @@ -48,7 +53,10 @@ export const DeploymentConfigDiffMain = ({ if (!isLoading) { setExpandedView( configList.reduce( - (acc, curr) => ({ ...acc, [curr.id]: scrollIntoViewId === curr.id || curr.hasDiff }), + (acc, curr) => ({ + ...acc, + [curr.id]: scrollIntoViewId === curr.id || curr.diffState !== DeploymentConfigDiffState.NO_DIFF, + }), {}, ), ) @@ -156,7 +164,7 @@ export const DeploymentConfigDiffMain = ({ } const renderDiffs = () => - configList.map(({ id, isDeploymentTemplate, primaryConfig, secondaryConfig, title, hasDiff }) => { + configList.map(({ id, primaryConfig, secondaryConfig, title, diffState, singleView }) => { const { heading: primaryHeading, list: primaryList } = primaryConfig const { heading: secondaryHeading, list: secondaryList } = secondaryConfig @@ -166,11 +174,12 @@ export const DeploymentConfigDiffMain = ({ id={id} title={title} isExpanded={expandedView[id]} - hasDiff={hasDiff} + diffState={diffState} onClick={handleAccordionClick(id)} onTransitionEnd={handleTransitionEnd(id)} + showDetailedDiffState={showDetailedDiffState} > - {isDeploymentTemplate ? ( + {singleView ? ( <>
{primaryHeading}
@@ -190,16 +199,17 @@ export const DeploymentConfigDiffMain = ({ ) : (
-
-
{primaryHeading}
-
{secondaryHeading}
-
+ {primaryHeading && secondaryHeading && ( +
+
{primaryHeading}
+
{secondaryHeading}
+
+ )}
@@ -212,7 +222,7 @@ export const DeploymentConfigDiffMain = ({
-

{headerText}

+ {!!headerText &&

{headerText}

} {renderHeaderSelectors(selectorsConfig.primaryConfig)}
diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index 186de8044..4d31d8bcd 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -4,12 +4,11 @@ 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 ICDiffFileUpdated } from '@Icons/ic-diff-file-updated.svg' import { StyledRadioGroup } from '@Common/index' -import { checkNavLinkActiveState } from '../CollapsibleList/utils' import { CollapsibleList } from '../CollapsibleList' -import { DeploymentConfigDiffNavigationProps } from './DeploymentConfigDiff.types' +import { DeploymentConfigDiffNavigationProps, DeploymentConfigDiffState } from './DeploymentConfigDiff.types' +import { diffStateIconMap, diffStateTooltipTextMap } from './DeploymentConfigDiff.utils' // LOADING SHIMMER const ShimmerText = ({ width }: { width: string }) => ( @@ -26,6 +25,7 @@ export const DeploymentConfigDiffNavigation = ({ navHeading, navHelpText, tabConfig, + showDetailedDiffState, }: DeploymentConfigDiffNavigationProps) => { // STATES const [expandedIds, setExpandedIds] = useState>({}) @@ -38,14 +38,20 @@ export const DeploymentConfigDiffNavigation = ({ const collapsibleListConfig = collapsibleNavList.map(({ items, ...resListItem }) => ({ ...resListItem, isExpanded: expandedIds[resListItem.id], - items: items.map(({ hasDiff, ...resItem }) => ({ + items: items.map(({ diffState, ...resItem }) => ({ ...resItem, - ...(hasDiff + ...(diffState !== DeploymentConfigDiffState.NO_DIFF ? { iconConfig: { - Icon: ICDiffFileUpdated, + Icon: showDetailedDiffState ? diffStateIconMap[diffState] : diffStateIconMap.hasDiff, props: { className: 'icon-dim-16 dc__no-shrink' }, - tooltipProps: { content: 'File has difference', arrow: false, placement: 'right' as const }, + tooltipProps: { + content: showDetailedDiffState + ? diffStateTooltipTextMap[diffState] + : diffStateTooltipTextMap.hasDiff, + arrow: false, + placement: 'right' as const, + }, }, } : {}), @@ -104,25 +110,36 @@ export const DeploymentConfigDiffNavigation = ({ const renderContent = () => ( <> - {navList.map(({ title, href, onClick, hasDiff }) => ( - - {title} - {hasDiff && ( - -
- -
-
- )} -
- ))} + {navList.map(({ title, href, onClick, diffState }) => { + const Icon = showDetailedDiffState ? diffStateIconMap[diffState] : diffStateIconMap.hasDiff + return ( + + {title} + {diffState !== DeploymentConfigDiffState.NO_DIFF && ( + +
+ +
+
+ )} +
+ ) + })} {navHelpText && (
diff --git a/src/Shared/Helpers.tsx b/src/Shared/Helpers.tsx index 5dff56f68..5eaac04f8 100644 --- a/src/Shared/Helpers.tsx +++ b/src/Shared/Helpers.tsx @@ -821,3 +821,34 @@ export const getDefaultValueFromType = (value: unknown) => { return null } } + +/** + * Groups an array of objects by a specified key. + * + * This function takes an array of objects and a key, and groups the objects in the array + * based on the value of the specified key. If an object does not have the specified key, + * it will be grouped under the `'UNGROUPED'` key. + * + * @param array - The array of objects to be grouped. + * @param key - The key of the object used to group the array. + * @returns An object where the keys are the unique values of the specified key in the array, + * and the values are arrays of objects that share the same key value. + */ +export const groupArrayByObjectKey = , K extends keyof T>( + array: T[], + key: K, +): Record => + array.reduce( + (result, currentValue) => { + const groupKey = currentValue[key] ?? 'UNGROUPED' + + if (!result[groupKey]) { + Object.assign(result, { [groupKey]: [] }) + } + + result[groupKey].push(currentValue) + + return result + }, + {} as Record, + ) diff --git a/src/Shared/Services/app.types.ts b/src/Shared/Services/app.types.ts index ea9477ac3..186569507 100644 --- a/src/Shared/Services/app.types.ts +++ b/src/Shared/Services/app.types.ts @@ -203,6 +203,7 @@ export enum ConfigResourceType { ConfigMap = 'ConfigMap', Secret = 'Secret', DeploymentTemplate = 'Deployment Template', + PipelineStrategy = 'Pipeline Strategy', } export interface DeploymentTemplateDTO { @@ -212,6 +213,8 @@ export interface DeploymentTemplateDTO { variableSnapshot: { 'Deployment Template': Record } + templateVersion: string + isAppMetricsEnabled?: true resolvedValue: Record } @@ -222,10 +225,18 @@ export interface ConfigMapSecretDataDTO { resolvedValue: string } +export interface PipelineConfigDataDTO { + resourceType: ConfigResourceType.PipelineStrategy + data: Record + pipelineTriggerType: string + Strategy: string +} + export interface AppEnvDeploymentConfigDTO { deploymentTemplate: DeploymentTemplateDTO | null configMapData: ConfigMapSecretDataDTO | null secretsData: ConfigMapSecretDataDTO | null + pipelineConfigData?: PipelineConfigDataDTO isAppAdmin: boolean } @@ -292,4 +303,5 @@ export enum EnvResourceType { Secret = 'secrets', DeploymentTemplate = 'deployment-template', Manifest = 'manifest', + PipelineConfiguration = 'pipeline-configuration', } From b7a228091e79cad96f7218445540bea879384643 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 24 Sep 2024 00:47:53 +0530 Subject: [PATCH 07/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b8f9617b..9ee5fecc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14", + "version": "0.3.14-beta-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14", + "version": "0.3.14-beta-1", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 67be4b90b..4b3f038db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14", + "version": "0.3.14-beta-1", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From d0949d10bbc1d6b4fcaf5e77c4656194701ce606 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 24 Sep 2024 13:54:02 +0530 Subject: [PATCH 08/28] feat: DeploymentConfigDiff - UAT changes, code refactor; DeploymentHistoryConfigDiff - renderRunSource integration --- .../DeploymentHistoryConfigDiff.tsx | 27 +++++++------ .../DeploymentHistoryConfigDiffCompare.tsx | 13 +++++- .../DeploymentHistoryConfigDiff/helpers.tsx | 40 ++++++++++++++++--- .../DeploymentHistoryConfigDiff/types.ts | 13 ++++-- .../DeploymentHistoryConfigDiff/utils.ts | 28 ++++++++++--- .../Components/CICDHistory/TriggerOutput.tsx | 5 +++ .../DeploymentConfigDiff.types.ts | 2 + .../DeploymentConfigDiff.utils.tsx | 11 +++-- .../DeploymentConfigDiffMain.tsx | 2 +- .../ImageCard/ArtifactInfo/ArtifactInfo.tsx | 9 +++-- src/Shared/Components/SelectPicker/common.tsx | 17 ++++---- src/Shared/Components/SelectPicker/type.ts | 2 +- src/Shared/Services/app.types.ts | 2 +- 13 files changed, 129 insertions(+), 42 deletions(-) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx index 45ef7a30d..e006e7941 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx @@ -22,6 +22,9 @@ export const DeploymentHistoryConfigDiff = ({ wfrId, triggerHistory, setFullScreenView, + runSource, + resourceId, + renderRunSource, }: DeploymentHistoryConfigDiffProps) => { // HOOKS const { path, params } = useRouteMatch() @@ -182,23 +185,20 @@ export const DeploymentHistoryConfigDiff = ({ [deploymentConfigList], ) + const isLoading = compareDeploymentConfigLoader || deploymentTemplateResolvedDataLoader + const isError = + compareDeploymentConfigErr || + (deploymentTemplateResolvedDataErr && !getIsRequestAborted(deploymentTemplateResolvedDataErr)) + return ( - {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( + {isError && !isLoading ? ( ) : (
- {compareDeploymentConfigLoader || !deploymentConfigList ? ( + {isLoading || (!isError && !deploymentConfigList) ? ( ) : ( <> diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx index a407a8a32..f26d2cad6 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -9,6 +9,7 @@ import { SelectPickerOptionType, SelectPickerVariantType, } from '@Shared/Components/SelectPicker' +import { ComponentSizeType } from '@Shared/constants' import { DeploymentHistoryDiffDetailedProps, DeploymentHistoryConfigDiffQueryParams } from './types' import { getPipelineDeploymentsOptions, parseDeploymentHistoryDiffSearchParams } from './utils' @@ -21,6 +22,9 @@ export const DeploymentHistoryConfigDiffCompare = ({ previousWfrId, convertVariables, setConvertVariables, + runSource, + renderRunSource, + resourceId, ...props }: DeploymentHistoryDiffDetailedProps) => { // HOOKS @@ -47,7 +51,13 @@ export const DeploymentHistoryConfigDiffCompare = ({ }, []) // DEPLOYMENT_CONFIG_DIFF_PROPS - const { currentDeployment, pipelineDeploymentsOptions } = getPipelineDeploymentsOptions(pipelineDeployments, wfrId) + const { currentDeployment, pipelineDeploymentsOptions } = getPipelineDeploymentsOptions({ + pipelineDeployments, + wfrId, + runSource, + renderRunSource, + resourceId, + }) const deploymentSelectorOnChange = ({ value }: SelectPickerOptionType) => { updateSearchParams({ compareWfrId: value }) @@ -68,6 +78,7 @@ export const DeploymentHistoryConfigDiffCompare = ({ value: getSelectPickerOptionByValue(pipelineDeploymentsOptions, compareWfrId, null), onChange: deploymentSelectorOnChange, showSelectedOptionIcon: false, + menuSize: ComponentSizeType.large, }, }, ], diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx index 861139cf7..05d77a985 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx @@ -1,6 +1,7 @@ import { NavLink } from 'react-router-dom' import { ReactComponent as ICFileCode } from '@Icons/ic-file-code.svg' +import { ReactComponent as ICDocker } from '@Icons/ic-docker.svg' import { DeploymentConfigDiffProps, DeploymentConfigDiffState, @@ -9,6 +10,9 @@ import { diffStateTextMap, } from '@Shared/Components/DeploymentConfigDiff' +import { History } from '../types' +import { DeploymentHistoryConfigDiffProps } from './types' + const renderState = (diffState: DeploymentConfigDiffState) => { const Icon = diffStateIconMap[diffState] @@ -31,19 +35,18 @@ export const renderDeploymentHistoryConfig = (

{heading}

)} - {config.map(({ id, title, diffState }, index) => { - const resourceType = (title.split('/')[0] || title).trim().toLowerCase().replace(' ', '-') - const resourceName = title.split('/')[1]?.trim() + {config.map(({ id, title, name, diffState, pathType }, index) => { + const href = `${pathname}/${name ? `${pathType}/${name}` : pathType}` return (

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

{renderState(diffState)}
@@ -59,3 +62,30 @@ export const renderPipelineDeploymentStatusIcon = (status: string) => ( .replace(/\s+/g, '')}`} /> ) + +export const renderPipelineDeploymentOptionDescription = ({ + stage, + triggeredBy, + triggeredByEmail, + artifact, + renderRunSource, + resourceId, + runSource, +}: Pick & + Pick) => ( +
+

+ {stage} + + {artifact && ( + + + {artifact.split(':')[1].slice(-12)} + + )} + + {triggeredBy === 1 ? 'auto trigger' : triggeredByEmail} +

+ {runSource && renderRunSource && renderRunSource(runSource, resourceId === runSource?.id)} +
+) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts index c3f91b9d5..717487cd9 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts @@ -3,13 +3,15 @@ import { Dispatch, SetStateAction } from 'react' import { DeploymentConfigDiffProps } from '@Shared/Components/DeploymentConfigDiff' import { EnvResourceType } from '@Shared/Services' -import { History } from '../types' +import { History, HistoryLogsProps, RunSourceType } from '../types' -export interface DeploymentHistoryConfigDiffProps { +export interface DeploymentHistoryConfigDiffProps + extends Required> { appName: string envName: string pipelineId: number wfrId: number + runSource: RunSourceType triggerHistory: Map setFullScreenView: (fullscreen: boolean) => void } @@ -18,7 +20,12 @@ export type DeploymentHistoryDiffDetailedProps = Pick< DeploymentConfigDiffProps, 'collapsibleNavList' | 'configList' | 'errorConfig' | 'isLoading' | 'navList' > & - Pick & { + Required< + Pick< + DeploymentHistoryConfigDiffProps, + 'setFullScreenView' | 'wfrId' | 'envName' | 'renderRunSource' | 'resourceId' | 'runSource' + > + > & { pipelineDeployments: History[] previousWfrId: number convertVariables: boolean diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts index e17979e63..1fbde7ea8 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts @@ -2,9 +2,10 @@ import moment from 'moment' import { DATE_TIME_FORMATS } from '@Common/Constants' import { DeploymentStageType } from '@Shared/constants' +import { SelectPickerOptionType } from '@Shared/Components/SelectPicker' import { History } from '../types' -import { renderPipelineDeploymentStatusIcon } from './helpers' +import { renderPipelineDeploymentOptionDescription, renderPipelineDeploymentStatusIcon } from './helpers' import { DeploymentHistoryConfigDiffProps } from './types' export const getPipelineDeployments = (triggerHistory: DeploymentHistoryConfigDiffProps['triggerHistory']) => @@ -25,15 +26,32 @@ export const getPipelineDeploymentsWfrIds = ({ } } -export const getPipelineDeploymentsOptions = (pipelineDeployments: History[], wfrId: number) => { +export const getPipelineDeploymentsOptions = ({ + pipelineDeployments, + wfrId, + renderRunSource, + resourceId, + runSource, +}: Required> & { + pipelineDeployments: History[] + wfrId: number +}) => { const currentDeploymentIndex = pipelineDeployments.findIndex(({ id }) => id === wfrId) const previousDeployments = pipelineDeployments.slice(currentDeploymentIndex + 1) - const pipelineDeploymentsOptions = previousDeployments.map( - ({ id, finishedOn, stage, triggeredBy, triggeredByEmail, status }) => ({ + const pipelineDeploymentsOptions: SelectPickerOptionType[] = previousDeployments.map( + ({ id, finishedOn, stage, triggeredBy, triggeredByEmail, status, artifact }) => ({ value: id, label: moment(finishedOn).format(DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT), - description: `${stage} · ${triggeredBy === 1 ? 'auto trigger' : triggeredByEmail}`, + description: renderPipelineDeploymentOptionDescription({ + stage, + triggeredByEmail, + triggeredBy, + artifact, + renderRunSource, + resourceId, + runSource, + }), startIcon: renderPipelineDeploymentStatusIcon(status), }), ) diff --git a/src/Shared/Components/CICDHistory/TriggerOutput.tsx b/src/Shared/Components/CICDHistory/TriggerOutput.tsx index 4ab2444bd..27c92cd29 100644 --- a/src/Shared/Components/CICDHistory/TriggerOutput.tsx +++ b/src/Shared/Components/CICDHistory/TriggerOutput.tsx @@ -498,6 +498,8 @@ const HistoryLogs: React.FC = ({ tagsEditable, hideImageTaggingHardDelete, selectedEnvironmentName, + resourceId, + renderRunSource, processVirtualEnvironmentDeploymentData, renderDeploymentApprovalInfo, renderCIListHeader, @@ -597,6 +599,9 @@ const HistoryLogs: React.FC = ({ wfrId={+triggerId} triggerHistory={triggerHistory} setFullScreenView={setFullScreenView} + resourceId={resourceId} + renderRunSource={renderRunSource} + runSource={triggerDetails.runSource} />
)} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts index 35176fcdb..8ff0aee29 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -28,6 +28,8 @@ export interface DeploymentConfigType { export interface DeploymentConfigListItem { id: string title: string + name?: string + pathType: EnvResourceType primaryConfig: DeploymentConfigType secondaryConfig: DeploymentConfigType diffState: DeploymentConfigDiffState diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index cd012b85d..9758f38d1 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -454,7 +454,7 @@ const getConfigMapSecretData = ( getConfigMapSecretResolvedValues(compareWithList, convertVariables), ) - const deploymentConfig = combinedList.map(([currentItem, compareItem]) => { + const deploymentConfig: DeploymentConfigDiffProps['configList'] = combinedList.map(([currentItem, compareItem]) => { const { compareToDiff, compareWithDiff, diffState } = getDiffViewData( currentItem, compareItem, @@ -465,6 +465,8 @@ const getConfigMapSecretData = ( return { id: `${resourceType === ConfigResourceType.ConfigMap ? EnvResourceType.ConfigMap : EnvResourceType.Secret}-${currentItem?.name || compareItem?.name}`, + pathType: + resourceType === ConfigResourceType.ConfigMap ? EnvResourceType.ConfigMap : EnvResourceType.Secret, title: `${resourceType === ConfigResourceType.ConfigMap ? 'ConfigMap' : 'Secret'} / ${currentItem?.name || compareItem?.name}`, name: currentItem?.name || compareItem?.name, primaryConfig: { @@ -537,6 +539,7 @@ export const getAppEnvDeploymentConfigList = { const element = document.querySelector(`#${pipelineConfigData.id}`) element?.scrollIntoView({ block: 'start' }) @@ -673,6 +677,7 @@ export const getAppEnvDeploymentConfigList = Generated Manifest, diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index 548c50883..a4893ec7f 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -90,7 +90,7 @@ export const DeploymentConfigDiffMain = ({ return ( -
+
{...selectPickerProps} isDisabled={isLoading || selectPickerProps?.isDisabled} diff --git a/src/Shared/Components/ImageCard/ArtifactInfo/ArtifactInfo.tsx b/src/Shared/Components/ImageCard/ArtifactInfo/ArtifactInfo.tsx index c482227f0..56d5b6025 100644 --- a/src/Shared/Components/ImageCard/ArtifactInfo/ArtifactInfo.tsx +++ b/src/Shared/Components/ImageCard/ArtifactInfo/ArtifactInfo.tsx @@ -15,6 +15,7 @@ */ import Tippy from '@tippyjs/react' +import { Tooltip } from '@Common/Tooltip' import { DefaultUserKey } from '../../../types' import { ImagePathTippyContentProps } from './types' import { ArtifactInfoProps } from '../types' @@ -57,8 +58,8 @@ const ArtifactInfo = ({ } return ( -
- +
+ {deployedTime}
) @@ -88,7 +89,9 @@ const ArtifactInfo = ({ > {deployedBy[0]} - {deployedBy} + + {deployedBy} +
) } diff --git a/src/Shared/Components/SelectPicker/common.tsx b/src/Shared/Components/SelectPicker/common.tsx index 34366530e..d6faa293b 100644 --- a/src/Shared/Components/SelectPicker/common.tsx +++ b/src/Shared/Components/SelectPicker/common.tsx @@ -165,13 +165,16 @@ export const SelectPickerOption = ({ {label} {/* Add support for custom ellipsis if required */} - {showDescription && ( -

- {description} -

- )} + {showDescription && + (typeof description === 'string' ? ( +

+ {description} +

+ ) : ( + description + ))}
{endIcon && (
{endIcon}
diff --git a/src/Shared/Components/SelectPicker/type.ts b/src/Shared/Components/SelectPicker/type.ts index c789bdd71..ad8c88ea1 100644 --- a/src/Shared/Components/SelectPicker/type.ts +++ b/src/Shared/Components/SelectPicker/type.ts @@ -28,7 +28,7 @@ export interface SelectPickerOptionType extends O /** * Description to be displayed for the option */ - description?: string + description?: ReactNode /** * Icon at the start of the option */ diff --git a/src/Shared/Services/app.types.ts b/src/Shared/Services/app.types.ts index 186569507..68f84a040 100644 --- a/src/Shared/Services/app.types.ts +++ b/src/Shared/Services/app.types.ts @@ -303,5 +303,5 @@ export enum EnvResourceType { Secret = 'secrets', DeploymentTemplate = 'deployment-template', Manifest = 'manifest', - PipelineConfiguration = 'pipeline-configuration', + PipelineStrategy = 'pipeline-strategy', } From 75d62ecc3bbf94c457e2fa9e1801b26628c2c7dd Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 24 Sep 2024 17:39:13 +0530 Subject: [PATCH 09/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ee5fecc6..6610d1040 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14-beta-1", + "version": "0.3.14-beta-2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14-beta-1", + "version": "0.3.14-beta-2", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 4b3f038db..3c590dda4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.14-beta-1", + "version": "0.3.14-beta-2", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From c6c937bf206e6ff3a50b8d683ff1fbcebb8d29d9 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Wed, 25 Sep 2024 12:12:58 +0530 Subject: [PATCH 10/28] fix: useForm: null check missing --- src/Shared/Hooks/useForm/useForm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared/Hooks/useForm/useForm.ts b/src/Shared/Hooks/useForm/useForm.ts index e3362ede5..181526b86 100644 --- a/src/Shared/Hooks/useForm/useForm.ts +++ b/src/Shared/Hooks/useForm/useForm.ts @@ -69,7 +69,7 @@ export const useForm = = {}>(options?: { */ const onBlur = (key: keyof T, noTrim: boolean) => () => { if (!noTrim) { - setData({ ...data, [key]: data[key].trim() }) + setData({ ...data, [key]: data[key]?.trim() }) } if (options?.validationMode === 'onBlur') { From 843c9dd7af7f6f66e2a5392876dd4492b06a2954 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Fri, 27 Sep 2024 13:31:58 +0530 Subject: [PATCH 11/28] fix: DeploymentHistory - diff state not properly showing in some cases, deployed time incorrect in case of in-progress deployment --- .../DeploymentHistoryConfigDiff/utils.ts | 6 ++-- .../DeploymentConfigDiff.utils.tsx | 28 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts index 1fbde7ea8..7e604692f 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts @@ -40,9 +40,9 @@ export const getPipelineDeploymentsOptions = ({ const previousDeployments = pipelineDeployments.slice(currentDeploymentIndex + 1) const pipelineDeploymentsOptions: SelectPickerOptionType[] = previousDeployments.map( - ({ id, finishedOn, stage, triggeredBy, triggeredByEmail, status, artifact }) => ({ + ({ id, startedOn, stage, triggeredBy, triggeredByEmail, status, artifact }) => ({ value: id, - label: moment(finishedOn).format(DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT), + label: moment(startedOn).format(DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT), description: renderPipelineDeploymentOptionDescription({ stage, triggeredByEmail, @@ -55,7 +55,7 @@ export const getPipelineDeploymentsOptions = ({ startIcon: renderPipelineDeploymentStatusIcon(status), }), ) - const currentDeployment = moment(pipelineDeployments[currentDeploymentIndex].finishedOn).format( + const currentDeployment = moment(pipelineDeployments[currentDeploymentIndex].startedOn).format( DATE_TIME_FORMATS.TWELVE_HOURS_FORMAT, ) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index 9758f38d1..e3926bd50 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -16,6 +16,7 @@ import { DiffHeadingDataType, prepareHistoryData, } from '@Shared/Components' +import { deepEqual } from '@Common/Helper' import { ConfigMapSecretDataConfigDatumDTO, @@ -233,22 +234,25 @@ const getCodeEditorData = ( } /** - * Compares two string values and returns the appropriate deployment configuration difference state. + * Compares two values and returns the appropriate deployment configuration difference state. * * @param compareToValue - The original value to compare. * @param compareWithValue - The new value to compare against the original. * @returns `DeploymentConfigDiffState` enum value indicating the difference between the two values */ -const getDiffState = (compareToValue: string, compareWithValue: string) => { - if (!compareToValue && compareWithValue) { +const getDiffState = (compareToValue: DeploymentHistoryDetail, compareWithValue: DeploymentHistoryDetail) => { + const isCompareToPresent = !!compareToValue.codeEditorValue.value + const isCompareWithPresent = !!compareWithValue.codeEditorValue.value + + if (!isCompareToPresent && isCompareWithPresent) { return DeploymentConfigDiffState.DELETED } - if (compareToValue && !compareWithValue) { + if (isCompareToPresent && !isCompareWithPresent) { return DeploymentConfigDiffState.ADDED } - if (compareToValue !== compareWithValue) { + if (!deepEqual(compareToValue, compareWithValue)) { return DeploymentConfigDiffState.HAS_DIFF } @@ -305,7 +309,7 @@ const getDiffViewData = ( return { compareToDiff, compareWithDiff, - diffState: getDiffState(compareToCodeEditorData.value, compareWithCodeEditorData.value), + diffState: getDiffState(compareToDiff, compareWithDiff), } } @@ -549,10 +553,7 @@ export const getAppEnvDeploymentConfigList = Generated Manifest, list: currentManifestData, }, - diffState: getDiffState(currentManifestData.codeEditorValue.value, compareManifestData.codeEditorValue.value), + diffState: getDiffState(currentManifestData, compareManifestData), singleView: true, } From d7b7271223c14db441e12016e83bb8d5e8ee8019 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Fri, 27 Sep 2024 13:33:35 +0530 Subject: [PATCH 12/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e1209cb90..2a44073a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.15", + "version": "0.3.15-beta-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.15", + "version": "0.3.15-beta-3", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index ea3decc58..1b79cdf56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.15", + "version": "0.3.15-beta-3", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From 95dcbad6e56f8deb0cc56d0a2caf6939932256a5 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 3 Oct 2024 15:21:09 +0530 Subject: [PATCH 13/28] fix: DeploymentConfigDiff: review fixes --- src/Common/Toggle/Toggle.tsx | 2 +- .../DeploymentHistoryConfigDiffCompare.tsx | 2 +- .../DeploymentHistoryDiffView.tsx | 4 +- .../DeploymentHistoryConfigDiff/utils.ts | 2 +- src/Shared/Components/CICDHistory/types.tsx | 1 + .../DeploymentConfigDiff.constants.ts | 35 ++++++++ .../DeploymentConfigDiff.utils.tsx | 83 ++++++------------- .../DeploymentConfigDiffAccordion.tsx | 2 +- .../DeploymentConfigDiffMain.tsx | 1 + .../DeploymentConfigDiffNavigation.tsx | 2 +- .../Components/DeploymentConfigDiff/index.ts | 1 + src/Shared/Components/SelectPicker/common.tsx | 27 +++--- src/Shared/Components/SelectPicker/type.ts | 7 +- 13 files changed, 94 insertions(+), 75 deletions(-) create mode 100644 src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.constants.ts diff --git a/src/Common/Toggle/Toggle.tsx b/src/Common/Toggle/Toggle.tsx index ac90a97d4..8440e0046 100644 --- a/src/Common/Toggle/Toggle.tsx +++ b/src/Common/Toggle/Toggle.tsx @@ -50,7 +50,7 @@ const Toggle = ({ } } - const throttledHandleClick = useCallback(throttle(handleClick, 500), []) + const throttledHandleClick = useCallback(throttle(handleClick, 500), [disabled]) return (
diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index 4d31d8bcd..d03722d40 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -8,7 +8,7 @@ import { StyledRadioGroup } from '@Common/index' import { CollapsibleList } from '../CollapsibleList' import { DeploymentConfigDiffNavigationProps, DeploymentConfigDiffState } from './DeploymentConfigDiff.types' -import { diffStateIconMap, diffStateTooltipTextMap } from './DeploymentConfigDiff.utils' +import { diffStateIconMap, diffStateTooltipTextMap } from './DeploymentConfigDiff.constants' // LOADING SHIMMER const ShimmerText = ({ width }: { width: string }) => ( diff --git a/src/Shared/Components/DeploymentConfigDiff/index.ts b/src/Shared/Components/DeploymentConfigDiff/index.ts index c84340d18..0b8c7a4d5 100644 --- a/src/Shared/Components/DeploymentConfigDiff/index.ts +++ b/src/Shared/Components/DeploymentConfigDiff/index.ts @@ -1,3 +1,4 @@ export * from './DeploymentConfigDiff.component' export * from './DeploymentConfigDiff.types' export * from './DeploymentConfigDiff.utils' +export * from './DeploymentConfigDiff.constants' diff --git a/src/Shared/Components/SelectPicker/common.tsx b/src/Shared/Components/SelectPicker/common.tsx index d6faa293b..fee77a0be 100644 --- a/src/Shared/Components/SelectPicker/common.tsx +++ b/src/Shared/Components/SelectPicker/common.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import Tippy, { TippyProps } from '@tippyjs/react' import { components, DropdownIndicatorProps, @@ -32,19 +31,27 @@ import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg' import { ReactComponent as ICClose } from '@Icons/ic-close.svg' import { ReactComponent as ICErrorExclamation } from '@Icons/ic-error-exclamation.svg' import { ChangeEvent } from 'react' -import { ConditionalWrap, noop } from '@Common/Helper' +import { noop } from '@Common/Helper' import { CHECKBOX_VALUE } from '@Common/Types' import { Checkbox } from '@Common/Checkbox' import { ReactSelectInputAction } from '@Common/Constants' import { isNullOrUndefined } from '@Shared/Helpers' +import { Tooltip } from '@Common/Tooltip' +import { TooltipProps } from '@Common/Tooltip/types' import { SelectPickerGroupHeadingProps, SelectPickerOptionType, SelectPickerProps } from './type' import { getGroupCheckboxValue } from './utils' -const renderWithTippy = (tippyProps: TippyProps) => (children: React.ReactElement) => ( - - {children} - -) +const getTooltipProps = (tooltipProps: SelectPickerOptionType['tooltipProps']): TooltipProps => { + if (Object.hasOwn(tooltipProps, 'shortcutKeyCombo') && 'shortcutKeyCombo' in tooltipProps) { + return tooltipProps + } + + return { + // TODO: using some typing somersaults here, clean it up later + alwaysShowTippyOnHover: !!(tooltipProps as Required>)?.content, + ...(tooltipProps as Required>), + } +} export const SelectPickerDropdownIndicator = ( props: DropdownIndicatorProps>, @@ -144,7 +151,7 @@ export const SelectPickerOption = ({ return ( - +
{isMulti && !isCreatableOption && ( ({ {description}

) : ( - description +
{description}
))}
{endIcon && ( @@ -181,7 +188,7 @@ export const SelectPickerOption = ({ )}
- + ) } diff --git a/src/Shared/Components/SelectPicker/type.ts b/src/Shared/Components/SelectPicker/type.ts index ad8c88ea1..01ce92ace 100644 --- a/src/Shared/Components/SelectPicker/type.ts +++ b/src/Shared/Components/SelectPicker/type.ts @@ -22,7 +22,7 @@ import { GroupBase, GroupHeadingProps, Props as ReactSelectProps, SelectInstance import { CreatableProps } from 'react-select/creatable' // This import allows to extend the base interface in react-select module via module augmentation import type {} from 'react-select/base' -import { TippyProps } from '@tippyjs/react' +import { TooltipProps } from '@Common/Tooltip/types' export interface SelectPickerOptionType extends OptionType { /** @@ -40,7 +40,10 @@ export interface SelectPickerOptionType extends O /** * Props passed to show the tippy on option */ - tooltipProps?: TippyProps + tooltipProps?: + | Omit + | (Omit & + Required>) } type SelectProps = ReactSelectProps< From 901f32e4d580d20feb10955ff51e55f762f5dda2 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 3 Oct 2024 15:27:10 +0530 Subject: [PATCH 14/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index edf34f750..dbf098eab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22", + "version": "0.3.22-beta-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22", + "version": "0.3.22-beta-1", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 3a6d1eb2d..e228d4f85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22", + "version": "0.3.22-beta-1", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From 0c154446cf011f3ae2738d9f98c8230452bf69b1 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 3 Oct 2024 16:20:34 +0530 Subject: [PATCH 15/28] fix: SelecPicker: tooltipProps null check --- package-lock.json | 4 ++-- package.json | 2 +- src/Shared/Components/SelectPicker/common.tsx | 19 +++++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbf098eab..c31035d8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22-beta-1", + "version": "0.3.22-beta-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22-beta-1", + "version": "0.3.22-beta-3", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index e228d4f85..ce743a08c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.3.22-beta-1", + "version": "0.3.22-beta-3", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", diff --git a/src/Shared/Components/SelectPicker/common.tsx b/src/Shared/Components/SelectPicker/common.tsx index fee77a0be..d985b240d 100644 --- a/src/Shared/Components/SelectPicker/common.tsx +++ b/src/Shared/Components/SelectPicker/common.tsx @@ -41,15 +41,22 @@ import { TooltipProps } from '@Common/Tooltip/types' import { SelectPickerGroupHeadingProps, SelectPickerOptionType, SelectPickerProps } from './type' import { getGroupCheckboxValue } from './utils' -const getTooltipProps = (tooltipProps: SelectPickerOptionType['tooltipProps']): TooltipProps => { - if (Object.hasOwn(tooltipProps, 'shortcutKeyCombo') && 'shortcutKeyCombo' in tooltipProps) { - return tooltipProps +const getTooltipProps = (tooltipProps: SelectPickerOptionType['tooltipProps'] = {}): TooltipProps => { + if (tooltipProps) { + if (Object.hasOwn(tooltipProps, 'shortcutKeyCombo') && 'shortcutKeyCombo' in tooltipProps) { + return tooltipProps + } + + return { + // TODO: using some typing somersaults here, clean it up later + alwaysShowTippyOnHover: !!(tooltipProps as Required>)?.content, + ...(tooltipProps as Required>), + } } return { - // TODO: using some typing somersaults here, clean it up later - alwaysShowTippyOnHover: !!(tooltipProps as Required>)?.content, - ...(tooltipProps as Required>), + alwaysShowTippyOnHover: false, + content: null, } } From 38c50932170db856192be47e0d5cd8582fa89ac3 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 8 Oct 2024 13:08:10 +0530 Subject: [PATCH 16/28] feat: DeploymentConfigDiff - logic refactor for resolving deployment template data as per API changes --- .../DeploymentHistoryConfigDiff.tsx | 103 +++--------------- .../DeploymentHistoryDiffView.tsx | 2 +- .../DeploymentConfigDiff.types.ts | 2 - .../DeploymentConfigDiff.utils.tsx | 49 +++++---- src/Shared/Services/app.service.ts | 6 +- src/Shared/Services/app.types.ts | 5 - 6 files changed, 48 insertions(+), 119 deletions(-) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx index e006e7941..2fa335e30 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx @@ -1,7 +1,7 @@ -import { useMemo, useRef, useState } from 'react' +import { useMemo, useState } from 'react' import { generatePath, Route, Switch, useLocation, useRouteMatch } from 'react-router-dom' -import { getAppEnvDeploymentConfigList, getDeploymentTemplateValues } from '@Shared/Components/DeploymentConfigDiff' +import { getAppEnvDeploymentConfigList } from '@Shared/Components/DeploymentConfigDiff' import { useAsync } from '@Common/Helper' import { EnvResourceType, getAppEnvDeploymentConfig } from '@Shared/Services' import { groupArrayByObjectKey } from '@Shared/Helpers' @@ -9,7 +9,6 @@ import ErrorScreenManager from '@Common/ErrorScreenManager' import { Progressing } from '@Common/Progressing' import { useUrlFilters } from '@Common/Hooks' -import { abortPreviousRequests, getIsRequestAborted } from '@Common/Api' import { DeploymentHistoryConfigDiffCompare } from './DeploymentHistoryConfigDiffCompare' import { DeploymentHistoryConfigDiffProps, DeploymentHistoryConfigDiffQueryParams } from './types' import { getPipelineDeploymentsWfrIds, getPipelineDeployments, parseDeploymentHistoryDiffSearchParams } from './utils' @@ -38,9 +37,6 @@ export const DeploymentHistoryConfigDiff = ({ ) const isPreviousDeploymentConfigAvailable = !!previousWfrId - // REFS - const deploymentTemplateResolvedDataAbortControllerRef = useRef(new AbortController()) - // URL FILTERS const { compareWfrId } = useUrlFilters({ parseSearchParams: parseDeploymentHistoryDiffSearchParams(previousWfrId), @@ -83,68 +79,13 @@ 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) { + if (!compareDeploymentConfigLoader && compareDeploymentConfig) { const compareList = isPreviousDeploymentConfigAvailable ? compareDeploymentConfig[1].result : { @@ -160,46 +101,29 @@ export const DeploymentHistoryConfigDiff = ({ compareList, getNavItemHref, convertVariables, - ...(convertVariables - ? { - currentDeploymentTemplateResolvedData: deploymentTemplateResolvedData[0].result, - compareDeploymentTemplateResolvedData: deploymentTemplateResolvedData[1].result, - } - : {}), }) return configData } return null - }, [ - isPreviousDeploymentConfigAvailable, - compareDeploymentConfigErr, - compareDeploymentConfig, - convertVariables, - deploymentTemplateResolvedDataLoader, - deploymentTemplateResolvedData, - ]) + }, [isPreviousDeploymentConfigAvailable, compareDeploymentConfigErr, compareDeploymentConfig, convertVariables]) const groupedDeploymentConfigList = useMemo( () => (deploymentConfigList ? groupArrayByObjectKey(deploymentConfigList.configList, 'groupHeader') : []), [deploymentConfigList], ) - const isLoading = compareDeploymentConfigLoader || deploymentTemplateResolvedDataLoader - const isError = - compareDeploymentConfigErr || - (deploymentTemplateResolvedDataErr && !getIsRequestAborted(deploymentTemplateResolvedDataErr)) - + const isLoading = compareDeploymentConfigLoader || (!compareDeploymentConfigErr && !deploymentConfigList) return ( - {isError && !isLoading ? ( - + {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( + ) : (
- {isLoading || (!isError && !deploymentConfigList) ? ( + {isLoading ? ( ) : ( <> diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx index 3e98d5e6d..5b48a0068 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx @@ -86,7 +86,7 @@ const DeploymentHistoryDiffView = ({ const renderDeploymentDiffViaCodeEditor = () => ( = (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..86bd91338 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -515,20 +515,42 @@ 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: AppEnvDeploymentConfigListParams['compareList'], + convertVariables: boolean, +) => { + if (!data.deploymentTemplate) { + return data + } + + const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) + + return convertVariables ? { ...data, deploymentTemplate: { ...data.deploymentTemplate, - deploymentDraftData: null, - data: resolvedData.deploymentTemplate.resolvedValue, + ...(deploymentTemplateResolvedData + ? { + data: deploymentTemplateResolvedData, + deploymentDraftData: null, + } + : {}), }, } : data +} /** * Generates a list of deployment configurations for application environments and identifies changes between the current and compare lists. @@ -548,8 +570,6 @@ export const getAppEnvDeploymentConfigList = ): { configList: DeploymentConfigDiffProps['configList'] navList: DeploymentConfigDiffProps['navList'] @@ -558,11 +578,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 +756,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/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..2f4a8b4d3 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 From e3a92750953d37a3d2598209e020fa7ecb74fafd Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Sun, 13 Oct 2024 15:31:10 +0530 Subject: [PATCH 17/28] feat: DeploymentHistoryConfigDiff - uat changes, code refactor --- .../DeploymentHistoryConfigDiff.tsx | 20 +++++---- .../DeploymentHistoryConfigDiffCompare.tsx | 45 +++++++++++-------- .../DeploymentHistoryDiffView.tsx | 9 ++-- .../DeploymentHistoryConfigDiff/helpers.tsx | 6 +-- .../DeploymentHistoryConfigDiff/utils.ts | 7 ++- src/Shared/Components/CICDHistory/types.tsx | 7 ++- .../CollapsibleList.component.tsx | 2 +- .../DeploymentConfigDiff.types.ts | 2 + .../DeploymentConfigDiffMain.tsx | 15 +++++-- .../DeploymentConfigDiffNavigation.tsx | 2 +- src/Shared/Services/app.types.ts | 1 + 11 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx index 2fa335e30..9e46bd163 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiff.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from 'react' import { generatePath, Route, Switch, useLocation, useRouteMatch } from 'react-router-dom' import { getAppEnvDeploymentConfigList } from '@Shared/Components/DeploymentConfigDiff' -import { useAsync } from '@Common/Helper' +import { capitalizeFirstLetter, useAsync } from '@Common/Helper' import { EnvResourceType, getAppEnvDeploymentConfig } from '@Shared/Services' import { groupArrayByObjectKey } from '@Shared/Helpers' import ErrorScreenManager from '@Common/ErrorScreenManager' @@ -114,17 +114,20 @@ export const DeploymentHistoryConfigDiff = ({ ) const isLoading = compareDeploymentConfigLoader || (!compareDeploymentConfigErr && !deploymentConfigList) + const errorConfig = { + code: compareDeploymentConfigErr?.code, + error: compareDeploymentConfigErr && !compareDeploymentConfigLoader, + message: capitalizeFirstLetter(compareDeploymentConfigErr?.errors[0]?.userMessage || ''), + reload: reloadCompareDeploymentConfig, + } + return ( {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( ) : (
diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx index 51ec5ae79..6578cfee1 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -64,24 +64,32 @@ export const DeploymentHistoryConfigDiffCompare = ({ } 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: pipelineDeploymentsOptions.length + ? [ + { + 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', @@ -109,6 +117,7 @@ export const DeploymentHistoryConfigDiffCompare = ({ {...props} showDetailedDiffState navHeading={`Comparing ${envName}`} + headerText={!pipelineDeploymentsOptions.length ? '' : undefined} // using `undefined` to ensure component picks default value navHelpText={ compareWfrId ? `Showing diff in configuration deployed on: ${pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId).label} & ${currentDeployment}` diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryDiffView.tsx index 5b48a0068..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..eed9612bf 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx @@ -29,7 +29,7 @@ export const renderDeploymentHistoryConfig = ( heading: string, pathname: string, ) => ( -
+
{heading && (

{heading}

@@ -41,7 +41,7 @@ export const renderDeploymentHistoryConfig = ( return (

@@ -73,7 +73,7 @@ export const renderPipelineDeploymentOptionDescription = ({ runSource, }: Pick & Pick) => ( -

+

{stage} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts index a9be8f4e7..149815ff4 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts @@ -10,7 +10,12 @@ import { DeploymentHistoryConfigDiffProps } from './types' export const getPipelineDeployments = (triggerHistory: DeploymentHistoryConfigDiffProps['triggerHistory']) => Array.from(triggerHistory) - .filter(([, value]) => value?.stage === DeploymentStageType.DEPLOY) + .filter( + ([, value]) => + // TODO: check with Prakash when API returns this erro + // (!value.message || value.message !== 'pg: no rows in result set') && + value.stage === DeploymentStageType.DEPLOY, + ) .map(([, value]) => value) export const getPipelineDeploymentsWfrIds = ({ 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/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index 0460df09b..020a79db2 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 > diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts index a8b593f7c..b86ed4edf 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -65,6 +65,8 @@ export interface DeploymentConfigDiffProps { errorConfig?: { error: boolean code: number + message?: string + redirectURL?: string reload: () => void } configList: DeploymentConfigListItem[] diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index c45fc619d..9d7a945b3 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -186,7 +186,7 @@ export const DeploymentConfigDiffMain = ({

{secondaryHeading}
)}
)} @@ -239,7 +239,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..627c3bde7 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -44,7 +44,7 @@ export const DeploymentConfigDiffNavigation = ({ ? { 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] diff --git a/src/Shared/Services/app.types.ts b/src/Shared/Services/app.types.ts index 2f4a8b4d3..cf3d4f31a 100644 --- a/src/Shared/Services/app.types.ts +++ b/src/Shared/Services/app.types.ts @@ -278,6 +278,7 @@ export interface TemplateListDTO { finishedOn?: string status?: string pipelineId?: number + wfrId?: number } export interface ManifestTemplateDTO { From b180a0ce55ae05b39462d735255d10d7b8090023 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Sun, 13 Oct 2024 16:25:42 +0530 Subject: [PATCH 18/28] feat: Collapse - add Collapse component, DeploymentConfigDiff - handling for scrolling selected config into view --- .../DeploymentHistoryConfigDiffCompare.tsx | 12 ++- src/Shared/Components/Collapse/Collapse.tsx | 43 ++++++++++- .../DeploymentConfigDiffAccordion.tsx | 73 +++++++++---------- .../DeploymentConfigDiffMain.tsx | 15 +++- 4 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx index 6578cfee1..d0a2be2e4 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 = ({ @@ -28,7 +32,8 @@ export const DeploymentHistoryConfigDiffCompare = ({ ...props }: DeploymentHistoryDiffDetailedProps) => { // HOOKS - const { path, params } = useRouteMatch() + const { path, params } = useRouteMatch() + const { resourceType, resourceName } = params // URL FILTERS const { compareWfrId, updateSearchParams, sortBy, sortOrder, handleSorting } = useUrlFilters< @@ -118,12 +123,13 @@ export const DeploymentHistoryConfigDiffCompare = ({ showDetailedDiffState navHeading={`Comparing ${envName}`} headerText={!pipelineDeploymentsOptions.length ? '' : undefined} // using `undefined` to ensure component picks default value + scrollIntoViewId={`${resourceType}${resourceName ? `-${resourceName}` : ''}`} navHelpText={ compareWfrId ? `Showing diff in configuration deployed on: ${pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId).label} & ${currentDeployment}` : null } - goBackURL={generatePath(path.split('/:resourceType')[0], params)} + goBackURL={generatePath(path.split('/:resourceType')[0], { ...params })} selectorsConfig={selectorsConfig} sortingConfig={sortingConfig} scopeVariablesConfig={scopeVariablesConfig} diff --git a/src/Shared/Components/Collapse/Collapse.tsx b/src/Shared/Components/Collapse/Collapse.tsx index 26e9b8768..1f48e7661 100644 --- a/src/Shared/Components/Collapse/Collapse.tsx +++ b/src/Shared/Components/Collapse/Collapse.tsx @@ -1,6 +1,41 @@ +import { useEffect, useState, useRef, useMemo } 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 expanding/collapsing content with smooth transitions. + * Dynamically calculates and applies height based on the content, with support + * for callback execution when the transition ends. + */ +export const Collapse = ({ expand, onTransitionEnd, children }: CollapseProps) => { + // Ref to access the content container + const contentRef = useRef(null) + // State for dynamically calculated height + const [contentHeight, setContentHeight] = useState(0) + + // Calculate and update content height when children change or initially on mount + useEffect(() => { + if (contentRef.current) { + const _contentHeight = contentRef.current.clientHeight || 0 + setContentHeight(_contentHeight) + } + }, [children]) + + const collapseStyle = useMemo( + () => ({ + // Set height based on the 'expand' prop + height: expand ? contentHeight : 0, + transition: 'height 200ms ease-out', + // Hide content overflow during collapse + overflow: 'hidden', + }), + [expand, contentHeight], + ) + + return ( +
+ {/* Content container with reference to calculate height */} +
{children}
+
+ ) +} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx index 57aea1524..ffd5e0b6b 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx @@ -1,48 +1,41 @@ -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} - -
- ), + {showDetailedDiffState + ? diffStateTextMap[diffState] + : `${diffState !== DeploymentConfigDiffState.NO_DIFF ? 'Has' : 'No'} difference`} +

+ + + {children} + +
) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index 9d7a945b3..b825d7009 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 = ({ @@ -35,6 +36,10 @@ export const DeploymentConfigDiffMain = ({ // 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,8 +47,9 @@ 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) { + scrollIntoViewAfterExpand.current = false const element = document.querySelector(`#${scrollIntoViewId}`) element?.scrollIntoView({ block: 'start' }) } @@ -65,6 +71,7 @@ export const DeploymentConfigDiffMain = ({ useEffect(() => { if (scrollIntoViewId) { + scrollIntoViewAfterExpand.current = true setExpandedView((prev) => ({ ...prev, [scrollIntoViewId]: true })) } }, [scrollIntoViewId]) @@ -176,7 +183,7 @@ export const DeploymentConfigDiffMain = ({ isExpanded={expandedView[id]} diffState={diffState} onClick={handleAccordionClick(id)} - onTransitionEnd={handleTransitionEnd(id)} + onTransitionEnd={onTransitionEnd} showDetailedDiffState={showDetailedDiffState} > {singleView ? ( From 90c527f1e83f799e451d90b5e41887c7811a3c89 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Sun, 13 Oct 2024 16:38:19 +0530 Subject: [PATCH 19/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5fabfab8a..1663f883c 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-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0", + "version": "0.5.0-beta-3", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 39d63d669..4b422b6e9 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-3", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From 0765c0ca4a8f660ed9119a6dd0051587c8de6f02 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Mon, 14 Oct 2024 17:55:02 +0530 Subject: [PATCH 20/28] refactor: DeploymentHistoryConfigDiff - Handle case for no configuration present in deployments; fix: Collapse - add resizeObserver to correctly calculate dynamic height; feat: DeploymentConfigDiff - add hideDiffState prop to hide the configuration diff status --- src/Common/ChartVersionAndTypeSelector.tsx | 1 - .../DeploymentHistoryConfigDiff.tsx | 76 +++++++++++++------ .../DeploymentHistoryConfigDiffCompare.tsx | 3 +- .../DeploymentHistoryConfigDiff/helpers.tsx | 3 +- .../DeploymentHistoryConfigDiff/types.ts | 2 +- .../DeploymentHistoryConfigDiff/utils.ts | 15 ++-- .../Components/CICDHistory/TriggerOutput.tsx | 2 +- src/Shared/Components/CICDHistory/service.tsx | 7 +- src/Shared/Components/Collapse/Collapse.tsx | 73 +++++++++++------- .../DeploymentConfigDiff.component.tsx | 3 + .../DeploymentConfigDiff.types.ts | 5 +- .../DeploymentConfigDiff.utils.tsx | 12 ++- .../DeploymentConfigDiffAccordion.tsx | 17 +++-- .../DeploymentConfigDiffMain.tsx | 5 +- .../DeploymentConfigDiffNavigation.tsx | 5 +- 15 files changed, 152 insertions(+), 77 deletions(-) diff --git a/src/Common/ChartVersionAndTypeSelector.tsx b/src/Common/ChartVersionAndTypeSelector.tsx index ac40e8c24..15c7efe83 100644 --- a/src/Common/ChartVersionAndTypeSelector.tsx +++ b/src/Common/ChartVersionAndTypeSelector.tsx @@ -70,7 +70,6 @@ const ChartVersionAndTypeSelector = ({ setSelectedChartRefId }: ChartVersionAndT return (
- Chart Type - Promise.all([ + Promise.allSettled([ getAppEnvDeploymentConfig({ params: { appName, @@ -86,15 +88,18 @@ export const DeploymentHistoryConfigDiff = ({ // Generate the deployment history config list const deploymentConfigList = useMemo(() => { if (!compareDeploymentConfigLoader && compareDeploymentConfig) { - const compareList = isPreviousDeploymentConfigAvailable - ? compareDeploymentConfig[1].result - : { - configMapData: null, - deploymentTemplate: null, - secretsData: null, - isAppAdmin: false, - } - const currentList = compareDeploymentConfig[0].result + 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, @@ -106,21 +111,44 @@ export const DeploymentHistoryConfigDiff = ({ } return null - }, [isPreviousDeploymentConfigAvailable, compareDeploymentConfigErr, compareDeploymentConfig, convertVariables]) + }, [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], ) + /** Hide diff state if the previous deployment config is unavailable or returns a 404 error. */ + const hideDiffState = + !isPreviousDeploymentConfigAvailable || + (compareDeploymentConfig && isDeploymentHistoryConfigDiffNotFoundError(compareDeploymentConfig[1])) + // LOADING const isLoading = compareDeploymentConfigLoader || (!compareDeploymentConfigErr && !deploymentConfigList) + // ERROR CONFIG const errorConfig = { code: compareDeploymentConfigErr?.code, error: compareDeploymentConfigErr && !compareDeploymentConfigLoader, - message: capitalizeFirstLetter(compareDeploymentConfigErr?.errors[0]?.userMessage || ''), reload: reloadCompareDeploymentConfig, } + // TODO: get null state from Utkarsh + if (compareDeploymentConfig && isDeploymentHistoryConfigDiffNotFoundError(compareDeploymentConfig[0])) { + return ( +
+ +
+ ) + } + return ( @@ -138,15 +166,12 @@ export const DeploymentHistoryConfigDiff = ({ runSource={runSource} resourceId={resourceId} renderRunSource={renderRunSource} + hideDiffState={hideDiffState} /> {compareDeploymentConfigErr && !compareDeploymentConfigLoader ? ( - + ) : (
{isLoading ? ( @@ -162,6 +187,7 @@ export const DeploymentHistoryConfigDiff = ({ groupedDeploymentConfigList[groupHeader], groupHeader !== 'UNGROUPED' ? groupHeader : null, pathname, + hideDiffState, ), )}
diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx index d0a2be2e4..3257f73b2 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -63,6 +63,7 @@ export const DeploymentHistoryConfigDiffCompare = ({ renderRunSource, resourceId, }) + const previousDeployment = pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId) const deploymentSelectorOnChange = ({ value }: SelectPickerOptionType) => { updateSearchParams({ compareWfrId: value }) @@ -126,7 +127,7 @@ export const DeploymentHistoryConfigDiffCompare = ({ scrollIntoViewId={`${resourceType}${resourceName ? `-${resourceName}` : ''}`} navHelpText={ compareWfrId - ? `Showing diff in configuration deployed on: ${pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId).label} & ${currentDeployment}` + ? `Showing diff in configuration deployed on: ${previousDeployment?.label || 'N/A'} & ${currentDeployment}` : null } goBackURL={generatePath(path.split('/:resourceType')[0], { ...params })} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx index eed9612bf..131547282 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx @@ -28,6 +28,7 @@ export const renderDeploymentHistoryConfig = ( config: DeploymentConfigDiffProps['configList'], heading: string, pathname: string, + hideDiffState: boolean, ) => (
{heading && ( @@ -48,7 +49,7 @@ export const renderDeploymentHistoryConfig = ( {name || title}

- {renderState(diffState)} + {!hideDiffState && renderState(diffState)} ) })} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts index 717487cd9..5408f81cc 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< diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/utils.ts index 149815ff4..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,12 +10,7 @@ import { DeploymentHistoryConfigDiffProps } from './types' export const getPipelineDeployments = (triggerHistory: DeploymentHistoryConfigDiffProps['triggerHistory']) => Array.from(triggerHistory) - .filter( - ([, value]) => - // TODO: check with Prakash when API returns this erro - // (!value.message || value.message !== 'pg: no rows in result set') && - value.stage === DeploymentStageType.DEPLOY, - ) + .filter(([, value]) => value.stage === DeploymentStageType.DEPLOY) .map(([, value]) => value) export const getPipelineDeploymentsWfrIds = ({ @@ -70,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..1683ecbf1 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/Collapse/Collapse.tsx b/src/Shared/Components/Collapse/Collapse.tsx index 1f48e7661..273dd55a3 100644 --- a/src/Shared/Components/Collapse/Collapse.tsx +++ b/src/Shared/Components/Collapse/Collapse.tsx @@ -1,40 +1,61 @@ -import { useEffect, useState, useRef, useMemo } from 'react' - +import { useEffect, useRef, useState } from 'react' import { CollapseProps } from './types' /** - * Collapse component for expanding/collapsing content with smooth transitions. - * Dynamically calculates and applies height based on the content, with support - * for callback execution when the transition ends. + * 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) => { - // Ref to access the content container + // Reference to the content container to calculate its height const contentRef = useRef(null) - // State for dynamically calculated height - const [contentHeight, setContentHeight] = useState(0) - // Calculate and update content height when children change or initially on mount + // 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 (contentRef.current) { - const _contentHeight = contentRef.current.clientHeight || 0 - setContentHeight(_contentHeight) + if (!contentHeight || !expand || !contentRef.current) { + return null } - }, [children]) - - const collapseStyle = useMemo( - () => ({ - // Set height based on the 'expand' prop - height: expand ? contentHeight : 0, - transition: 'height 200ms ease-out', - // Hide content overflow during collapse - overflow: 'hidden', - }), - [expand, contentHeight], - ) + + 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 ( -
- {/* Content container with reference to calculate height */} +
+ {/* The container that holds the collapsible content */}
{children}
) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx index fd445efcf..b41828d84 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx @@ -13,6 +13,7 @@ export const DeploymentConfigDiff = ({ navHelpText, tabConfig, showDetailedDiffState, + hideDiffState, renderedInDrawer, ...resProps }: DeploymentConfigDiffProps) => ( @@ -26,11 +27,13 @@ export const DeploymentConfigDiff = ({ navHelpText={navHelpText} 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 b86ed4edf..ca67ce0cc 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -71,6 +71,7 @@ export interface DeploymentConfigDiffProps { } configList: DeploymentConfigListItem[] showDetailedDiffState?: boolean + hideDiffState?: boolean headerText?: string scrollIntoViewId?: string selectorsConfig: { @@ -111,6 +112,7 @@ export interface DeploymentConfigDiffNavigationProps | 'navHelpText' | 'tabConfig' | 'showDetailedDiffState' + | 'hideDiffState' > {} export interface DeploymentConfigDiffMainProps @@ -125,10 +127,11 @@ export interface DeploymentConfigDiffMainProps | 'sortingConfig' | 'scopeVariablesConfig' | 'showDetailedDiffState' + | 'hideDiffState' > {} export type DeploymentConfigDiffAccordionProps = Pick & - Pick & { + Pick & { id: string title: string children: React.ReactNode diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index 86bd91338..cbcf62107 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -529,7 +529,17 @@ const getDeploymentTemplateResolvedData = (deploymentTemplate: DeploymentTemplat const getConfigDataWithResolvedDeploymentTemplate = ( data: AppEnvDeploymentConfigListParams['compareList'], convertVariables: boolean, -) => { +): AppEnvDeploymentConfigListParams['compareList'] => { + if (!data) { + return { + deploymentTemplate: null, + configMapData: null, + isAppAdmin: null, + secretsData: null, + pipelineConfigData: null, + } + } + if (!data.deploymentTemplate) { return data } diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx index ffd5e0b6b..a13f67817 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffAccordion.tsx @@ -7,6 +7,7 @@ import { diffStateTextColorMap, diffStateTextMap } from './DeploymentConfigDiff. export const DeploymentConfigDiffAccordion = ({ diffState, showDetailedDiffState, + hideDiffState, children, title, id, @@ -26,13 +27,15 @@ export const DeploymentConfigDiffAccordion = ({ style={{ ['--rotateBy' as string]: isExpanded ? '360deg' : '270deg' }} />

{title}

-

- {showDetailedDiffState - ? diffStateTextMap[diffState] - : `${diffState !== DeploymentConfigDiffState.NO_DIFF ? 'Has' : 'No'} difference`} -

+ {!hideDiffState && ( +

+ {showDetailedDiffState + ? diffStateTextMap[diffState] + : `${diffState !== DeploymentConfigDiffState.NO_DIFF ? 'Has' : 'No'} difference`} +

+ )} {children} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx index b825d7009..fe2bf119d 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffMain.tsx @@ -32,6 +32,7 @@ export const DeploymentConfigDiffMain = ({ scrollIntoViewId, scopeVariablesConfig, showDetailedDiffState, + hideDiffState, }: DeploymentConfigDiffMainProps) => { // STATES const [expandedView, setExpandedView] = useState>({}) @@ -49,9 +50,10 @@ export const DeploymentConfigDiffMain = ({ const onTransitionEnd: DeploymentConfigDiffAccordionProps['onTransitionEnd'] = (e) => { if (scrollIntoViewAfterExpand.current && e.target === e.currentTarget) { - scrollIntoViewAfterExpand.current = false const element = document.querySelector(`#${scrollIntoViewId}`) element?.scrollIntoView({ block: 'start' }) + // Reset ref after scrolling into view + scrollIntoViewAfterExpand.current = false } } @@ -185,6 +187,7 @@ export const DeploymentConfigDiffMain = ({ onClick={handleAccordionClick(id)} onTransitionEnd={onTransitionEnd} showDetailedDiffState={showDetailedDiffState} + hideDiffState={hideDiffState} > {singleView ? ( <> diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index 627c3bde7..7b0764bce 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -26,6 +26,7 @@ export const DeploymentConfigDiffNavigation = ({ navHelpText, tabConfig, showDetailedDiffState, + hideDiffState, }: DeploymentConfigDiffNavigationProps) => { // STATES const [expandedIds, setExpandedIds] = useState>({}) @@ -40,7 +41,7 @@ export const DeploymentConfigDiffNavigation = ({ isExpanded: expandedIds[resListItem.id], items: items.map(({ diffState, ...resItem }) => ({ ...resItem, - ...(diffState !== DeploymentConfigDiffState.NO_DIFF + ...(!hideDiffState && diffState !== DeploymentConfigDiffState.NO_DIFF ? { iconConfig: { Icon: showDetailedDiffState ? diffStateIconMap[diffState] : diffStateIconMap.hasDiff, @@ -121,7 +122,7 @@ export const DeploymentConfigDiffNavigation = ({ onClick={onClick} > {title} - {diffState !== DeploymentConfigDiffState.NO_DIFF && ( + {!hideDiffState && diffState !== DeploymentConfigDiffState.NO_DIFF && ( Date: Mon, 14 Oct 2024 17:58:35 +0530 Subject: [PATCH 21/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1663f883c..28d983a3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0-beta-3", + "version": "0.5.0-beta-5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0-beta-3", + "version": "0.5.0-beta-5", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index 4b422b6e9..b87893156 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0-beta-3", + "version": "0.5.0-beta-5", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From ac348540936493a281461b15e4576bc40ccc45b4 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 15 Oct 2024 13:17:31 +0530 Subject: [PATCH 22/28] feat: DeploymentHistoryConfigDiff - add NullState for previous/current deployment not available & required changes to DeploymentConfigDiff --- src/Common/ChartVersionAndTypeSelector.tsx | 8 ++-- .../DeploymentHistoryConfigDiff.tsx | 46 +++++++++++++------ .../DeploymentHistoryConfigDiffCompare.tsx | 23 +++++++--- .../DeploymentHistoryConfigDiff/helpers.tsx | 6 ++- .../DeploymentHistoryConfigDiff/types.ts | 1 + .../CollapsibleList.component.tsx | 6 ++- .../CollapsibleList/CollapsibleList.types.ts | 4 ++ .../DeploymentConfigDiff.component.tsx | 2 + .../DeploymentConfigDiff.types.ts | 2 + .../DeploymentConfigDiffNavigation.tsx | 17 +++++-- 10 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/Common/ChartVersionAndTypeSelector.tsx b/src/Common/ChartVersionAndTypeSelector.tsx index 15c7efe83..7272120ba 100644 --- a/src/Common/ChartVersionAndTypeSelector.tsx +++ b/src/Common/ChartVersionAndTypeSelector.tsx @@ -70,9 +70,9 @@ const ChartVersionAndTypeSelector = ({ setSelectedChartRefId }: ChartVersionAndT return (
+ Chart Type
- Chart Version + Chart Version - +
) } @@ -167,6 +171,7 @@ export const DeploymentHistoryConfigDiff = ({ resourceId={resourceId} renderRunSource={renderRunSource} hideDiffState={hideDiffState} + isCompareDeploymentConfigNotAvailable={hasPreviousDeploymentConfigNotFoundError} /> @@ -179,16 +184,27 @@ export const DeploymentHistoryConfigDiff = ({ ) : ( <>

- 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, - hideDiffState, - ), +
+
+ {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 3257f73b2..7d23c80fb 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/DeploymentHistoryConfigDiffCompare.tsx @@ -29,6 +29,7 @@ export const DeploymentHistoryConfigDiffCompare = ({ runSource, renderRunSource, resourceId, + isCompareDeploymentConfigNotAvailable, ...props }: DeploymentHistoryDiffDetailedProps) => { // HOOKS @@ -64,13 +65,14 @@ export const DeploymentHistoryConfigDiffCompare = ({ resourceId, }) const previousDeployment = pipelineDeploymentsOptions.find(({ value }) => value === compareWfrId) + const isPreviousDeploymentConfigAvailable = !!pipelineDeploymentsOptions.length const deploymentSelectorOnChange = ({ value }: SelectPickerOptionType) => { updateSearchParams({ compareWfrId: value }) } const selectorsConfig: DeploymentConfigDiffProps['selectorsConfig'] = { - primaryConfig: pipelineDeploymentsOptions.length + primaryConfig: isPreviousDeploymentConfigAvailable ? [ { id: 'deployment-config-diff-deployment-selector', @@ -105,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'] = { @@ -123,13 +135,10 @@ export const DeploymentHistoryConfigDiffCompare = ({ {...props} showDetailedDiffState navHeading={`Comparing ${envName}`} - headerText={!pipelineDeploymentsOptions.length ? '' : undefined} // using `undefined` to ensure component picks default value + headerText={!isPreviousDeploymentConfigAvailable ? '' : undefined} // using `undefined` to ensure component picks default value scrollIntoViewId={`${resourceType}${resourceName ? `-${resourceName}` : ''}`} - navHelpText={ - compareWfrId - ? `Showing diff in configuration deployed on: ${previousDeployment?.label || 'N/A'} & ${currentDeployment}` - : null - } + navHelpText={getNavHelpText()} + isNavHelpTextShowingError={isCompareDeploymentConfigNotAvailable} goBackURL={generatePath(path.split('/:resourceType')[0], { ...params })} selectorsConfig={selectorsConfig} sortingConfig={sortingConfig} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx index 131547282..140c8ecb8 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/helpers.tsx @@ -47,7 +47,11 @@ export const renderDeploymentHistoryConfig = ( >

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

{!hideDiffState && renderState(diffState)} diff --git a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts index 5408f81cc..350ed7d50 100644 --- a/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts +++ b/src/Shared/Components/CICDHistory/DeploymentHistoryConfigDiff/types.ts @@ -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/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index 020a79db2..e60d8edd6 100644 --- a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx +++ b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx @@ -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 b41828d84..d1989c32e 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.component.tsx @@ -11,6 +11,7 @@ export const DeploymentConfigDiff = ({ goBackURL, navHeading, navHelpText, + isNavHelpTextShowingError, tabConfig, showDetailedDiffState, hideDiffState, @@ -25,6 +26,7 @@ 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 ca67ce0cc..2c6c78f64 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.types.ts @@ -89,6 +89,7 @@ export interface DeploymentConfigDiffProps { goBackURL?: string navHeading: string navHelpText?: string + isNavHelpTextShowingError?: boolean tabConfig?: { tabs: string[] activeTab: string @@ -110,6 +111,7 @@ export interface DeploymentConfigDiffNavigationProps | 'goBackURL' | 'navHeading' | 'navHelpText' + | 'isNavHelpTextShowingError' | 'tabConfig' | 'showDetailedDiffState' | 'hideDiffState' diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index 7b0764bce..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,6 +25,7 @@ export const DeploymentConfigDiffNavigation = ({ goBackURL, navHeading, navHelpText, + isNavHelpTextShowingError, tabConfig, showDetailedDiffState, hideDiffState, @@ -36,11 +38,12 @@ 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, + strikeThrough: showDetailedDiffState && diffState === DeploymentConfigDiffState.DELETED, ...(!hideDiffState && diffState !== DeploymentConfigDiffState.NO_DIFF ? { iconConfig: { @@ -145,9 +148,13 @@ export const DeploymentConfigDiffNavigation = ({ {navHelpText && (
- + {isNavHelpTextShowingError ? ( + + ) : ( + + )} -

{navHelpText}

+

{navHelpText}

)} From 1ebf287e339e603e9e7955e603f0527c35874bcf Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 15 Oct 2024 13:19:32 +0530 Subject: [PATCH 23/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28d983a3d..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-beta-5", + "version": "0.5.0-beta-6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0-beta-5", + "version": "0.5.0-beta-6", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index b87893156..90c0df155 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.0-beta-5", + "version": "0.5.0-beta-6", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From 41abc0aa3a94401ff1cb9303e470037cfaef4e7c Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 15 Oct 2024 17:33:34 +0530 Subject: [PATCH 24/28] fix: review fix --- src/Shared/Components/CICDHistory/service.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared/Components/CICDHistory/service.tsx b/src/Shared/Components/CICDHistory/service.tsx index 1683ecbf1..2763c2eb1 100644 --- a/src/Shared/Components/CICDHistory/service.tsx +++ b/src/Shared/Components/CICDHistory/service.tsx @@ -200,7 +200,7 @@ export const prepareConfigMapAndSecretData = ( if (rawData.mountPath || rawData.defaultMountPath) { secretValues['mountPath'] = { displayName: 'Volume mount path', - value: rawData.mountPath ?? rawData.defaultMountPath, + value: rawData.mountPath || rawData.defaultMountPath, } } if (rawData.subPath) { From 16211d500b8dcbd0185942d301fbc7da0fd1ddd2 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 15 Oct 2024 18:31:54 +0530 Subject: [PATCH 25/28] refactor: DeploymentConfigDiff.utils - code refactor --- .../DeploymentConfigDiff.utils.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index cbcf62107..d28b31dc9 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -540,26 +540,24 @@ const getConfigDataWithResolvedDeploymentTemplate = ( } } - if (!data.deploymentTemplate) { - return data + if (data.deploymentTemplate && convertVariables) { + const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) + + return { + ...data, + deploymentTemplate: { + ...data.deploymentTemplate, + ...(deploymentTemplateResolvedData + ? { + data: deploymentTemplateResolvedData, + deploymentDraftData: null, + } + : {}), + }, + } } - const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) - - return convertVariables - ? { - ...data, - deploymentTemplate: { - ...data.deploymentTemplate, - ...(deploymentTemplateResolvedData - ? { - data: deploymentTemplateResolvedData, - deploymentDraftData: null, - } - : {}), - }, - } - : data + return data } /** From 5f784258cdf539195d1e10559a7e486ca12c6a8b Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Tue, 15 Oct 2024 18:35:16 +0530 Subject: [PATCH 26/28] refactor: DeploymentConfigDiff.utils - code refactor --- .../DeploymentConfigDiff.utils.tsx | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx index d28b31dc9..a498d9671 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiff.utils.tsx @@ -540,24 +540,24 @@ const getConfigDataWithResolvedDeploymentTemplate = ( } } - if (data.deploymentTemplate && convertVariables) { - const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) - - return { - ...data, - deploymentTemplate: { - ...data.deploymentTemplate, - ...(deploymentTemplateResolvedData - ? { - data: deploymentTemplateResolvedData, - deploymentDraftData: null, - } - : {}), - }, - } + if (!data.deploymentTemplate || !convertVariables) { + return data } - return data + const deploymentTemplateResolvedData = getDeploymentTemplateResolvedData(data.deploymentTemplate) + + return { + ...data, + deploymentTemplate: { + ...data.deploymentTemplate, + ...(deploymentTemplateResolvedData + ? { + data: deploymentTemplateResolvedData, + deploymentDraftData: null, + } + : {}), + }, + } } /** From 193d05c6cd1b2302420b829c43da906c83c6e2eb Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Wed, 16 Oct 2024 21:05:05 +0530 Subject: [PATCH 27/28] refactor: CollapsibleList, DeploymentConfigDiffNavigation - icon size uat change --- .../Components/CollapsibleList/CollapsibleList.component.tsx | 4 ++-- .../DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx b/src/Shared/Components/CollapsibleList/CollapsibleList.component.tsx index e60d8edd6..3928907f1 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 > @@ -90,7 +90,7 @@ export const CollapsibleList = ({ config, onCollapseBtnClick }: CollapsibleListP > )} diff --git a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx index 78f45c558..3d6841f0e 100644 --- a/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx +++ b/src/Shared/Components/DeploymentConfigDiff/DeploymentConfigDiffNavigation.tsx @@ -48,7 +48,6 @@ export const DeploymentConfigDiffNavigation = ({ ? { iconConfig: { Icon: showDetailedDiffState ? diffStateIconMap[diffState] : diffStateIconMap.hasDiff, - props: { className: 'dc__no-shrink' }, tooltipProps: { content: showDetailedDiffState ? diffStateTooltipTextMap[diffState] @@ -137,7 +136,7 @@ export const DeploymentConfigDiffNavigation = ({ placement="right" >
- +
)} From 02dd3b4c440112e8b265707c77de5d84407b5db2 Mon Sep 17 00:00:00 2001 From: Rohit Raj Date: Thu, 17 Oct 2024 15:56:27 +0530 Subject: [PATCH 28/28] chore: version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45ac20c99..59641eeb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.1", + "version": "0.5.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.1", + "version": "0.5.2", "license": "ISC", "dependencies": { "@types/react-dates": "^21.8.6", diff --git a/package.json b/package.json index d6ee666ab..6f055aeae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "0.5.1", + "version": "0.5.2", "description": "Supporting common component library", "type": "module", "main": "dist/index.js",