diff --git a/package-lock.json b/package-lock.json index 307ba5d4d..e207b28dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.16.0-pre-3", + "version": "1.16.0-pre-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.16.0-pre-3", + "version": "1.16.0-pre-4", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index db9f911ea..ccccb9598 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.16.0-pre-3", + "version": "1.16.0-pre-4", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", diff --git a/src/Common/Types.ts b/src/Common/Types.ts index e9b0165b7..df09dad84 100644 --- a/src/Common/Types.ts +++ b/src/Common/Types.ts @@ -659,10 +659,10 @@ export interface CommonNodeAttr extends Pick )} diff --git a/src/Shared/Components/AppStatusModal/AppStatusModal.component.tsx b/src/Shared/Components/AppStatusModal/AppStatusModal.component.tsx index a2cd53503..daf66cdea 100644 --- a/src/Shared/Components/AppStatusModal/AppStatusModal.component.tsx +++ b/src/Shared/Components/AppStatusModal/AppStatusModal.component.tsx @@ -99,6 +99,7 @@ const AppStatusModal = ({ } : null, isHelmApp: appDetails.appType === AppType.DEVTRON_HELM_CHART, + deploymentAppType: appDetails.deploymentAppType, }), deploymentStatusAbortControllerRef, ) diff --git a/src/Shared/Components/AppStatusModal/service.ts b/src/Shared/Components/AppStatusModal/service.ts index e862199d3..93bf49caf 100644 --- a/src/Shared/Components/AppStatusModal/service.ts +++ b/src/Shared/Components/AppStatusModal/service.ts @@ -51,6 +51,7 @@ export const getDeploymentStatusWithTimeline = async ({ showTimeline, virtualEnvironmentConfig, isHelmApp, + deploymentAppType, }: GetDeploymentStatusWithTimelineParamsType): Promise => { const baseURL = isHelmApp ? ROUTES.HELM_DEPLOYMENT_STATUS_TIMELINE_INSTALLED_APP : ROUTES.DEPLOYMENT_STATUS @@ -68,5 +69,8 @@ export const getDeploymentStatusWithTimeline = async ({ return virtualEnvironmentConfig ? virtualEnvironmentConfig.processVirtualEnvironmentDeploymentData(deploymentStatusDetailsResponse.result) - : processDeploymentStatusDetailsData(deploymentStatusDetailsResponse.result) + : processDeploymentStatusDetailsData( + deploymentStatusDetailsResponse.result.deploymentAppType ?? deploymentAppType, + deploymentStatusDetailsResponse.result, + ) } diff --git a/src/Shared/Components/AppStatusModal/types.ts b/src/Shared/Components/AppStatusModal/types.ts index 6b86ada85..9671e06a7 100644 --- a/src/Shared/Components/AppStatusModal/types.ts +++ b/src/Shared/Components/AppStatusModal/types.ts @@ -1,6 +1,6 @@ import { FunctionComponent, PropsWithChildren, ReactNode } from 'react' -import { APIOptions } from '@Common/Types' +import { APIOptions, DeploymentAppTypes } from '@Common/Types' import { AppDetails, ConfigDriftModalProps, @@ -85,6 +85,7 @@ export type GetDeploymentStatusWithTimelineParamsType = Pick { diff --git a/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx b/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx index 8714dff54..860bbf5d3 100644 --- a/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx @@ -61,7 +61,7 @@ const DeploymentDetailSteps = ({ const processedData = isVirtualEnv.current && processVirtualEnvironmentDeploymentData ? processVirtualEnvironmentDeploymentData() - : processDeploymentStatusDetailsData() + : processDeploymentStatusDetailsData(deploymentAppType ?? appDetails?.deploymentAppType) const [deploymentStatusDetailsBreakdownData, setDeploymentStatusDetailsBreakdownData] = useState(processedData) @@ -115,7 +115,10 @@ const DeploymentDetailSteps = ({ const processedDeploymentStatusDetailsData = isVirtualEnv.current && processVirtualEnvironmentDeploymentData ? processVirtualEnvironmentDeploymentData(deploymentStatusDetailRes) - : processDeploymentStatusDetailsData(deploymentStatusDetailRes) + : processDeploymentStatusDetailsData( + deploymentStatusDetailRes.deploymentAppType, + deploymentStatusDetailRes, + ) clearDeploymentStatusTimer() // If deployment status is in progress then fetch data in every 10 seconds @@ -171,6 +174,7 @@ const DeploymentDetailSteps = ({ isVirtualEnvironment={isVirtualEnv.current} appDetails={appDetails} rootClassName="p-20" + deploymentAppType={deploymentStatusDetailsBreakdownData.deploymentAppType} /> ) diff --git a/src/Shared/Components/CICDHistory/DeploymentStatusBreakdown.tsx b/src/Shared/Components/CICDHistory/DeploymentStatusBreakdown.tsx index 5ba7e5b59..8790ae1ce 100644 --- a/src/Shared/Components/CICDHistory/DeploymentStatusBreakdown.tsx +++ b/src/Shared/Components/CICDHistory/DeploymentStatusBreakdown.tsx @@ -16,6 +16,7 @@ import { Fragment } from 'react' +import { DeploymentAppTypes } from '@Common/Types' import { TIMELINE_STATUS } from '@Shared/types' import { InfoBlock } from '../InfoBlock' @@ -29,6 +30,7 @@ const DeploymentStatusDetailBreakdown = ({ isVirtualEnvironment, appDetails, rootClassName = '', + deploymentAppType, }: DeploymentStatusDetailBreakdownType) => { const isHelmManifestPushed = deploymentStatusDetailsBreakdownData.deploymentStatusBreakdown[ @@ -58,8 +60,9 @@ const DeploymentStatusDetailBreakdown = ({ {( [ TIMELINE_STATUS.GIT_COMMIT, - TIMELINE_STATUS.ARGOCD_SYNC, - TIMELINE_STATUS.KUBECTL_APPLY, + ...(deploymentAppType === DeploymentAppTypes.ARGO + ? [TIMELINE_STATUS.ARGOCD_SYNC, TIMELINE_STATUS.KUBECTL_APPLY] + : []), ] as DeploymentStatusDetailRowType['type'][] ).map((timelineStatus) => ( diff --git a/src/Shared/Components/CICDHistory/TriggerOutput.tsx b/src/Shared/Components/CICDHistory/TriggerOutput.tsx index 128a24f9a..f3929c229 100644 --- a/src/Shared/Components/CICDHistory/TriggerOutput.tsx +++ b/src/Shared/Components/CICDHistory/TriggerOutput.tsx @@ -128,7 +128,8 @@ const HistoryLogs: React.FC = ({ deploymentAppType={deploymentAppType} userApprovalMetadata={userApprovalMetadata} isGitops={ - deploymentAppType === DeploymentAppTypes.GITOPS || + deploymentAppType === DeploymentAppTypes.ARGO || + deploymentAppType === DeploymentAppTypes.FLUX || deploymentAppType === DeploymentAppTypes.MANIFEST_DOWNLOAD || deploymentAppType === DeploymentAppTypes.MANIFEST_PUSH } diff --git a/src/Shared/Components/CICDHistory/types.tsx b/src/Shared/Components/CICDHistory/types.tsx index 82d789232..4c63f94e8 100644 --- a/src/Shared/Components/CICDHistory/types.tsx +++ b/src/Shared/Components/CICDHistory/types.tsx @@ -522,6 +522,7 @@ export interface DeploymentStatusDetailBreakdownType { */ appDetails: AppDetails | null rootClassName?: string + deploymentAppType: DeploymentAppTypes } export interface DeploymentStatusDetailRowType extends Pick { diff --git a/src/Shared/Components/DeploymentStatusBreakdown/constants.ts b/src/Shared/Components/DeploymentStatusBreakdown/constants.ts index 9ced31e1f..1439ba4e5 100644 --- a/src/Shared/Components/DeploymentStatusBreakdown/constants.ts +++ b/src/Shared/Components/DeploymentStatusBreakdown/constants.ts @@ -66,7 +66,7 @@ export const FAILED_DEPLOYMENT_STATUS: typeof PROGRESSING_DEPLOYMENT_STATUS = [ DEPLOYMENT_STATUS.UNABLE_TO_FETCH, ] -export const PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER: Readonly = [ +export const PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER_ARGO: Readonly = [ TIMELINE_STATUS.DEPLOYMENT_INITIATED, TIMELINE_STATUS.GIT_COMMIT, TIMELINE_STATUS.ARGOCD_SYNC, @@ -74,6 +74,12 @@ export const PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER: Readonly = [ + TIMELINE_STATUS.DEPLOYMENT_INITIATED, + TIMELINE_STATUS.GIT_COMMIT, + TIMELINE_STATUS.APP_HEALTH, +] + export const DEPLOYMENT_PHASES: Readonly = [ DeploymentPhaseType.PRE_SYNC, DeploymentPhaseType.SYNC, diff --git a/src/Shared/Components/DeploymentStatusBreakdown/utils.tsx b/src/Shared/Components/DeploymentStatusBreakdown/utils.tsx index 89a232fe0..7815dae4f 100644 --- a/src/Shared/Components/DeploymentStatusBreakdown/utils.tsx +++ b/src/Shared/Components/DeploymentStatusBreakdown/utils.tsx @@ -1,5 +1,6 @@ /* eslint-disable no-param-reassign */ import { findRight, handleUTCTime, logExceptionToSentry } from '@Common/Helper' +import { DeploymentAppTypes } from '@Common/Types' import { DEPLOYMENT_STATUS } from '@Shared/constants' import { DeploymentPhaseType, @@ -14,7 +15,8 @@ import { import { DEPLOYMENT_PHASES, FAILED_DEPLOYMENT_STATUS, - PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER, + PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER_ARGO, + PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER_FLUX, PROGRESSING_DEPLOYMENT_STATUS, SUCCESSFUL_DEPLOYMENT_STATUS, WFR_STATUS_DTO_TO_DEPLOYMENT_STATUS_MAP, @@ -22,6 +24,7 @@ import { import { ProcessUnableToFetchOrTimedOutStatusType } from './types' const getDefaultDeploymentStatusTimeline = ( + deploymentAppType: DeploymentAppTypes, data?: DeploymentStatusDetailsType, ): DeploymentStatusDetailsBreakdownDataType => { const commonProps: Pick< @@ -45,6 +48,7 @@ const getDefaultDeploymentStatusTimeline = ( return { deploymentStatus, + deploymentAppType, deploymentTriggerTime: data?.deploymentStartedOn || '', deploymentEndTime: data?.deploymentFinishedOn || '', triggeredBy: data?.triggeredBy || '', @@ -58,19 +62,26 @@ const getDefaultDeploymentStatusTimeline = ( ...commonProps, displayText: 'Push manifest to Git', }, - [TIMELINE_STATUS.ARGOCD_SYNC]: { - ...commonProps, - displayText: 'Synced with Argo CD', - }, - [TIMELINE_STATUS.KUBECTL_APPLY]: { - ...commonProps, - displayText: 'Apply manifest to Kubernetes', - resourceDetails: [], - subSteps: [], - }, + ...(deploymentAppType === DeploymentAppTypes.ARGO + ? { + [TIMELINE_STATUS.ARGOCD_SYNC]: { + ...commonProps, + displayText: 'Synced with Argo CD', + }, + [TIMELINE_STATUS.KUBECTL_APPLY]: { + ...commonProps, + displayText: 'Apply manifest to Kubernetes', + resourceDetails: [], + subSteps: [], + }, + } + : {}), [TIMELINE_STATUS.APP_HEALTH]: { ...commonProps, - displayText: 'Propagate manifest to Kubernetes resources', + displayText: + deploymentAppType === DeploymentAppTypes.FLUX + ? 'Synced with Flux CD' + : 'Propagate manifest to Kubernetes resources', }, }, errorBarConfig: deploymentErrorMessage @@ -219,13 +230,17 @@ const processKubeCTLApply = ( * This function processes the deployment status details data and returns a breakdown of the deployment status. * Cases it handles: * 1. If timelines are not present, say the case of helm deployment, we will parse the wfrStatus and put the status and basic deployment info [triggeredBy, deploymentStartedOn, deploymentFinishedOn] into the breakdown data and return it. - * 2. In case of gitops: + * 2. In case of argo_cd: * - There are five timelines in chronological order: * - Deployment Initiated * - Git commit * - ArgoCD Sync * - Kubectl Apply * - App Health + * In case of flux_cd + * - Deployment Initiated + * - Git commit + * - App Health * - Basic flow is we traverse the timelines in order, if find the last status for that specific timeline from response by traversing the timelines in reverse order. * - If element is found, we will parse the status and set the icon, display text, time, etc. for that timeline and set the next timeline to inprogress. * - If element is not found, we will parse on basis of factors like: @@ -233,12 +248,13 @@ const processKubeCTLApply = ( * - In similar fashion based on the deploymentStatus we will set the icon and display text for the timeline. */ export const processDeploymentStatusDetailsData = ( + deploymentAppType: DeploymentAppTypes, data?: DeploymentStatusDetailsType, ): DeploymentStatusDetailsBreakdownDataType => { if (data && !WFR_STATUS_DTO_TO_DEPLOYMENT_STATUS_MAP[data.wfrStatus]) { logExceptionToSentry(new Error(`New WFR status found: ${data?.wfrStatus}`)) } - const deploymentData = getDefaultDeploymentStatusTimeline(data) + const deploymentData = getDefaultDeploymentStatusTimeline(deploymentAppType, data) const { deploymentStatus } = deploymentData @@ -266,7 +282,13 @@ export const processDeploymentStatusDetailsData = ( timeline.status.includes(TIMELINE_STATUS.ARGOCD_SYNC), ) - PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER.forEach((timelineStatusType, index) => { + // Only keep 3 steps in case of flux + const timelineOrder = + deploymentAppType === DeploymentAppTypes.FLUX + ? PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER_FLUX + : PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER_ARGO + + timelineOrder.forEach((timelineStatusType, index) => { const element = findRight(data.timelines, getPredicate(timelineStatusType)) const timelineData = deploymentData.deploymentStatusBreakdown[timelineStatusType] @@ -289,7 +311,11 @@ export const processDeploymentStatusDetailsData = ( if (hasDeploymentFailed) { const hasCurrentTimelineFailed = timelineStatusType === TIMELINE_STATUS.APP_HEALTH && - deploymentData.deploymentStatusBreakdown.KUBECTL_APPLY.icon === 'success' + deploymentData.deploymentStatusBreakdown[ + deploymentAppType === DeploymentAppTypes.FLUX + ? TIMELINE_STATUS.GIT_COMMIT + : TIMELINE_STATUS.KUBECTL_APPLY + ].icon === 'success' timelineData.displaySubText = hasCurrentTimelineFailed ? 'Failed' : '' timelineData.icon = hasCurrentTimelineFailed ? 'failed' : 'unreachable' @@ -353,8 +379,8 @@ export const processDeploymentStatusDetailsData = ( } // Moving the next timeline to inprogress - if (timelineData.icon === 'success' && index !== PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER.length - 1) { - const nextTimelineStatus = PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER[index + 1] + if (timelineData.icon === 'success' && index !== timelineOrder.length - 1) { + const nextTimelineStatus = timelineOrder[index + 1] const nextTimeline = deploymentData.deploymentStatusBreakdown[nextTimelineStatus] if (deploymentData.errorBarConfig) { @@ -367,13 +393,13 @@ export const processDeploymentStatusDetailsData = ( }) // Traversing the timeline in reverse order so that if any status is there which is inprogress or success then we will mark all the previous steps as success - for (let i = PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER.length - 1; i >= 0; i -= 1) { - const timelineStatusType = PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER[i] + for (let i = timelineOrder.length - 1; i >= 0; i -= 1) { + const timelineStatusType = timelineOrder[i] const timelineData = deploymentData.deploymentStatusBreakdown[timelineStatusType] if (timelineData.icon === 'inprogress' || timelineData.icon === 'success') { for (let j = i - 1; j >= 0; j -= 1) { - const prevTimelineStatusType = PHYSICAL_ENV_DEPLOYMENT_TIMELINE_ORDER[j] + const prevTimelineStatusType = timelineOrder[j] const prevTimelineData = deploymentData.deploymentStatusBreakdown[prevTimelineStatusType] prevTimelineData.icon = 'success' prevTimelineData.displaySubText = '' diff --git a/src/Shared/Components/StatusComponent/AppStatus.tsx b/src/Shared/Components/StatusComponent/AppStatus.tsx index e20704efc..ee366dd84 100644 --- a/src/Shared/Components/StatusComponent/AppStatus.tsx +++ b/src/Shared/Components/StatusComponent/AppStatus.tsx @@ -45,7 +45,7 @@ export const AppStatus = ({ tooltipProps={{ alwaysShowTippyOnHover: true, placement: 'top', - content: 'To fetch app status for Helm based deployments open the app detail page', + content: 'To view app status open the app detail page', }} color="N600" /> diff --git a/src/Shared/Hooks/useStickyEvent/constants.ts b/src/Shared/Hooks/useStickyEvent/constants.ts index 2e7292418..edc6822ee 100644 --- a/src/Shared/Hooks/useStickyEvent/constants.ts +++ b/src/Shared/Hooks/useStickyEvent/constants.ts @@ -14,6 +14,7 @@ * limitations under the License. */ -export const FALLBACK_SENTINEL_HEIGHT = '1px' +export const SENTINEL_HEIGHT_BUFFER = 2 +export const FALLBACK_SENTINEL_HEIGHT = `${SENTINEL_HEIGHT_BUFFER}px` export const OBSERVER_THRESHOLD = 1 -export const OBSERVER_ROOT_MARGIN = '0px' +export const OBSERVER_ROOT_MARGIN = '1px' diff --git a/src/Shared/Hooks/useStickyEvent/utils.ts b/src/Shared/Hooks/useStickyEvent/utils.ts index 55a742a73..48dcdd7f4 100644 --- a/src/Shared/Hooks/useStickyEvent/utils.ts +++ b/src/Shared/Hooks/useStickyEvent/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FALLBACK_SENTINEL_HEIGHT } from './constants' +import { FALLBACK_SENTINEL_HEIGHT, SENTINEL_HEIGHT_BUFFER } from './constants' import { UseStickyEventReturnType } from './types' export const getHeightForStickyElementTopOffset = ({ @@ -30,7 +30,7 @@ export const getHeightForStickyElementTopOffset = ({ const doesTopOffsetContainCalc = calcRegex.test(topValue) if (doesTopOffsetContainCalc) { - return topValue.replace(calcRegex, (match) => `calc(${match} + 1px)`) + return topValue.replace(calcRegex, (match) => `calc(${match} + ${SENTINEL_HEIGHT_BUFFER}px)`) } return topValue.replace(/\d+(\.\d+)?/g, (match) => { @@ -40,6 +40,6 @@ export const getHeightForStickyElementTopOffset = ({ return FALLBACK_SENTINEL_HEIGHT } - return `${nMatch + 1}` + return `${nMatch + SENTINEL_HEIGHT_BUFFER}` }) } diff --git a/src/Shared/types.ts b/src/Shared/types.ts index e8155fd35..7a70f3a87 100644 --- a/src/Shared/types.ts +++ b/src/Shared/types.ts @@ -1251,6 +1251,7 @@ export interface DeploymentStatusDetailsType { timelines: DeploymentStatusDetailsTimelineType[] wfrStatus?: WorkflowRunnerStatusDTO isDeploymentWithoutApproval: boolean + deploymentAppType: DeploymentAppTypes } export type DeploymentStatusTimelineType = @@ -1313,6 +1314,7 @@ export interface DeploymentStatusDetailsBreakdownDataType { deploymentErrorMessage: string nextTimelineToProcess: DeploymentStatusTimelineType } | null + deploymentAppType: DeploymentAppTypes } export interface IntelligenceConfig { diff --git a/src/index.ts b/src/index.ts index 4ad98de18..5939e8487 100644 --- a/src/index.ts +++ b/src/index.ts @@ -167,9 +167,14 @@ export interface customEnv { */ FEATURE_MANAGE_TRAFFIC_ENABLE?: boolean FEATURE_INFRA_PROVISION_INFO_BLOCK_HIDE?: boolean + /** + * If true, will add flux option to deployment types in devtron apps and devtron charts + * @default false + */ + FEATURE_FLUX_DEPLOYMENTS_ENABLE?: boolean + FEATURE_LINK_EXTERNAL_FLUX_ENABLE?: boolean /** * If true, online/offline connectivity banner is enabled - * * @default true */ FEATURE_INTERNET_CONNECTIVITY_ENABLE?: boolean