diff --git a/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx b/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx
index 08f56b220..115cab8cf 100644
--- a/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx
+++ b/src/Shared/Components/CICDHistory/DeploymentDetailSteps.tsx
@@ -43,6 +43,7 @@ const DeploymentDetailSteps = ({
isVirtualEnvironment,
processVirtualEnvironmentDeploymentData,
renderDeploymentApprovalInfo,
+ isDeploymentWithoutApproval,
}: DeploymentDetailStepsType) => {
const history = useHistory()
const { url } = useRouteMatch()
@@ -51,6 +52,8 @@ const DeploymentDetailSteps = ({
deploymentStatus?.toUpperCase() !== TIMELINE_STATUS.ABORTED,
)
const isVirtualEnv = useRef(isVirtualEnvironment)
+ const isDeploymentWithoutApprovalRef = useRef(isDeploymentWithoutApproval)
+
const processedData =
isVirtualEnv.current && processVirtualEnvironmentDeploymentData
? processVirtualEnvironmentDeploymentData()
@@ -69,7 +72,10 @@ const DeploymentDetailSteps = ({
.then((deploymentStatusDetailRes) => {
if (deploymentStatus !== 'Aborted') {
// eslint-disable-next-line no-use-before-define
- processDeploymentStatusData(deploymentStatusDetailRes.result)
+ processDeploymentStatusData({
+ ...deploymentStatusDetailRes.result,
+ isDeploymentWithoutApproval: isDeploymentWithoutApprovalRef.current,
+ })
}
})
.catch(() => {
@@ -97,6 +103,10 @@ const DeploymentDetailSteps = ({
isVirtualEnv.current = isVirtualEnvironment
}, [isVirtualEnvironment])
+ useEffect(() => {
+ isDeploymentWithoutApprovalRef.current = isDeploymentWithoutApproval
+ }, [isDeploymentWithoutApproval])
+
const processDeploymentStatusData = (deploymentStatusDetailRes: DeploymentStatusDetailsType): void => {
const processedDeploymentStatusDetailsData =
isVirtualEnv.current && processVirtualEnvironmentDeploymentData
diff --git a/src/Shared/Components/CICDHistory/DeploymentStatusDetailRow.tsx b/src/Shared/Components/CICDHistory/DeploymentStatusDetailRow.tsx
index d55511dbd..56417d711 100644
--- a/src/Shared/Components/CICDHistory/DeploymentStatusDetailRow.tsx
+++ b/src/Shared/Components/CICDHistory/DeploymentStatusDetailRow.tsx
@@ -176,7 +176,9 @@ export const DeploymentStatusDetailRow = ({
>
{renderIcon(statusBreakDownType.icon)}
- {statusBreakDownType.displayText}
+
+ {statusBreakDownType.displayText}
+
{statusBreakDownType.displaySubText && (
{statusBreakDownType.displaySubText}
diff --git a/src/Shared/Components/CICDHistory/History.components.tsx b/src/Shared/Components/CICDHistory/History.components.tsx
index 779bf2872..712a6d8d2 100644
--- a/src/Shared/Components/CICDHistory/History.components.tsx
+++ b/src/Shared/Components/CICDHistory/History.components.tsx
@@ -138,6 +138,7 @@ export const GitChanges = ({
selectedEnvironmentName,
renderCIListHeader,
targetPlatforms,
+ isDeploymentWithoutApproval,
}: GitChangesType) => {
const { isSuperAdmin } = useGetUserRoles()
@@ -202,6 +203,7 @@ export const GitChanges = ({
selectedEnvironmentName={selectedEnvironmentName}
renderCIListHeader={renderCIListHeader}
targetPlatforms={targetPlatforms}
+ isDeploymentWithoutApproval={isDeploymentWithoutApproval}
>
diff --git a/src/Shared/Components/CICDHistory/TriggerOutput.tsx b/src/Shared/Components/CICDHistory/TriggerOutput.tsx
index 404129be8..79690560d 100644
--- a/src/Shared/Components/CICDHistory/TriggerOutput.tsx
+++ b/src/Shared/Components/CICDHistory/TriggerOutput.tsx
@@ -133,6 +133,7 @@ const HistoryLogs: React.FC
= ({
isVirtualEnvironment={triggerDetails.IsVirtualEnvironment}
processVirtualEnvironmentDeploymentData={processVirtualEnvironmentDeploymentData}
renderDeploymentApprovalInfo={renderDeploymentApprovalInfo}
+ isDeploymentWithoutApproval={triggerDetails.isDeploymentWithoutApproval ?? false}
/>
)}
@@ -156,6 +157,7 @@ const HistoryLogs: React.FC = ({
promotionApprovalMetadata={triggerDetails?.promotionApprovalMetadata}
renderCIListHeader={renderCIListHeader}
targetPlatforms={targetPlatforms}
+ isDeploymentWithoutApproval={triggerDetails.isDeploymentWithoutApproval ?? false}
/>
{triggerDetails.stage === 'DEPLOY' && (
diff --git a/src/Shared/Components/CICDHistory/types.tsx b/src/Shared/Components/CICDHistory/types.tsx
index f34a00765..417f5ed8b 100644
--- a/src/Shared/Components/CICDHistory/types.tsx
+++ b/src/Shared/Components/CICDHistory/types.tsx
@@ -187,6 +187,7 @@ export interface History extends Pick, Wo
triggerMetadata?: string
runSource?: RunSourceType
targetConfig?: TargetConfigType
+ isDeploymentWithoutApproval?: boolean
}
export interface ExecutionInfoType {
@@ -389,7 +390,7 @@ export interface DeploymentStatusDetailsTimelineType {
statusTime: string
resourceDetails?: SyncStageResourceDetail[]
}
-export interface DeploymentStatusDetailsType {
+export interface DeploymentStatusDetailsType extends Pick {
deploymentFinishedOn: string
deploymentStartedOn: string
triggeredBy: string
@@ -405,7 +406,7 @@ export interface DeploymentStatusDetailsResponse extends ResponseType {
interface DeploymentStatusDetailRow {
icon: string
- displayText: string
+ displayText: ReactNode
displaySubText: string
time: string
resourceDetails?: any
@@ -431,7 +432,7 @@ export interface DeploymentStatusDetailsBreakdownDataType {
}
}
-export interface DeploymentDetailStepsType {
+export interface DeploymentDetailStepsType extends Pick {
deploymentStatus?: string
deploymentAppType?: DeploymentAppTypes
isHelmApps?: boolean
@@ -445,7 +446,7 @@ export interface DeploymentDetailStepsType {
renderDeploymentApprovalInfo: (userApprovalMetadata: UserApprovalMetadataType) => JSX.Element
}
-export interface RenderCIListHeaderProps {
+export interface RenderCIListHeaderProps extends Required> {
userApprovalMetadata: UserApprovalMetadataType
triggeredBy: string
appliedFilters: FilterConditionsListType[]
@@ -465,7 +466,7 @@ export interface VirtualHistoryArtifactProps {
}
}
-export type CIListItemType = Pick & {
+export type CIListItemType = Pick & {
userApprovalMetadata?: UserApprovalMetadataType
triggeredBy?: string
children: ReactNode
@@ -737,6 +738,7 @@ export type GitChangesType = {
appliedFilters?: never
appliedFiltersTimestamp?: never
renderCIListHeader?: never
+ isDeploymentWithoutApproval?: never
}
| {
artifact: string
@@ -755,6 +757,7 @@ export type GitChangesType = {
appliedFilters?: FilterConditionsListType[]
appliedFiltersTimestamp?: string
renderCIListHeader: (renderCIListHeaderProps: RenderCIListHeaderProps) => JSX.Element
+ isDeploymentWithoutApproval?: History['isDeploymentWithoutApproval']
}
)
diff --git a/src/Shared/Components/Icon/Icon.tsx b/src/Shared/Components/Icon/Icon.tsx
index 0cef854e7..16c5e2585 100644
--- a/src/Shared/Components/Icon/Icon.tsx
+++ b/src/Shared/Components/Icon/Icon.tsx
@@ -23,6 +23,7 @@ import { ReactComponent as ICCaretLeft } from '@IconsV2/ic-caret-left.svg'
import { ReactComponent as ICCd } from '@IconsV2/ic-cd.svg'
import { ReactComponent as ICChatCircleDots } from '@IconsV2/ic-chat-circle-dots.svg'
import { ReactComponent as ICCheck } from '@IconsV2/ic-check.svg'
+import { ReactComponent as ICChecks } from '@IconsV2/ic-checks.svg'
import { ReactComponent as ICCiLinked } from '@IconsV2/ic-ci-linked.svg'
import { ReactComponent as ICCiWebhook } from '@IconsV2/ic-ci-webhook.svg'
import { ReactComponent as ICCircleLoader } from '@IconsV2/ic-circle-loader.svg'
@@ -69,6 +70,7 @@ import { ReactComponent as ICInfoFilled } from '@IconsV2/ic-info-filled.svg'
import { ReactComponent as ICInfoOutline } from '@IconsV2/ic-info-outline.svg'
import { ReactComponent as ICJobColor } from '@IconsV2/ic-job-color.svg'
import { ReactComponent as ICK8sJob } from '@IconsV2/ic-k8s-job.svg'
+import { ReactComponent as ICKey } from '@IconsV2/ic-key.svg'
import { ReactComponent as ICLdap } from '@IconsV2/ic-ldap.svg'
import { ReactComponent as ICLightning } from '@IconsV2/ic-lightning.svg'
import { ReactComponent as ICLightningFill } from '@IconsV2/ic-lightning-fill.svg'
@@ -93,6 +95,7 @@ import { ReactComponent as ICPencil } from '@IconsV2/ic-pencil.svg'
import { ReactComponent as ICQuay } from '@IconsV2/ic-quay.svg'
import { ReactComponent as ICQuote } from '@IconsV2/ic-quote.svg'
import { ReactComponent as ICRocketLaunch } from '@IconsV2/ic-rocket-launch.svg'
+import { ReactComponent as ICSelected } from '@IconsV2/ic-selected.svg'
import { ReactComponent as ICShieldCheck } from '@IconsV2/ic-shield-check.svg'
import { ReactComponent as ICSlidersVertical } from '@IconsV2/ic-sliders-vertical.svg'
import { ReactComponent as ICSortAscending } from '@IconsV2/ic-sort-ascending.svg'
@@ -105,7 +108,7 @@ import { ReactComponent as ICSuccess } from '@IconsV2/ic-success.svg'
import { ReactComponent as ICSuspended } from '@IconsV2/ic-suspended.svg'
import { ReactComponent as ICTata1mg } from '@IconsV2/ic-tata1mg.svg'
import { ReactComponent as ICTerminalFill } from '@IconsV2/ic-terminal-fill.svg'
-import { ReactComponent as ICTimeoutTwoDash } from '@IconsV2/ic-timeout-two-dash.svg'
+import { ReactComponent as ICTimeoutDash } from '@IconsV2/ic-timeout-dash.svg'
import { ReactComponent as ICTimer } from '@IconsV2/ic-timer.svg'
import { ReactComponent as ICTravclan } from '@IconsV2/ic-travclan.svg'
import { ReactComponent as ICUnknown } from '@IconsV2/ic-unknown.svg'
@@ -141,6 +144,7 @@ export const iconMap = {
'ic-cd': ICCd,
'ic-chat-circle-dots': ICChatCircleDots,
'ic-check': ICCheck,
+ 'ic-checks': ICChecks,
'ic-ci-linked': ICCiLinked,
'ic-ci-webhook': ICCiWebhook,
'ic-circle-loader': ICCircleLoader,
@@ -187,6 +191,7 @@ export const iconMap = {
'ic-info-outline': ICInfoOutline,
'ic-job-color': ICJobColor,
'ic-k8s-job': ICK8sJob,
+ 'ic-key': ICKey,
'ic-ldap': ICLdap,
'ic-lightning-fill': ICLightningFill,
'ic-lightning': ICLightning,
@@ -211,6 +216,7 @@ export const iconMap = {
'ic-quay': ICQuay,
'ic-quote': ICQuote,
'ic-rocket-launch': ICRocketLaunch,
+ 'ic-selected': ICSelected,
'ic-shield-check': ICShieldCheck,
'ic-sliders-vertical': ICSlidersVertical,
'ic-sort-ascending': ICSortAscending,
@@ -223,7 +229,7 @@ export const iconMap = {
'ic-suspended': ICSuspended,
'ic-tata1mg': ICTata1mg,
'ic-terminal-fill': ICTerminalFill,
- 'ic-timeout-two-dash': ICTimeoutTwoDash,
+ 'ic-timeout-dash': ICTimeoutDash,
'ic-timer': ICTimer,
'ic-travclan': ICTravclan,
'ic-unknown': ICUnknown,
diff --git a/src/Shared/Components/StatusComponent/utils.ts b/src/Shared/Components/StatusComponent/utils.ts
index eddd95a1e..b6303d7c8 100644
--- a/src/Shared/Components/StatusComponent/utils.ts
+++ b/src/Shared/Components/StatusComponent/utils.ts
@@ -70,7 +70,7 @@ export const getIconName = (status: string, showAnimatedIcon: boolean): IconName
return 'ic-hibernate'
case 'timedout':
case 'timed_out':
- return 'ic-timeout-two-dash'
+ return 'ic-timeout-dash'
default:
return null
}
diff --git a/src/Shared/Components/TabGroup/TabGroup.component.tsx b/src/Shared/Components/TabGroup/TabGroup.component.tsx
index d7bcba5f8..eb8059cb9 100644
--- a/src/Shared/Components/TabGroup/TabGroup.component.tsx
+++ b/src/Shared/Components/TabGroup/TabGroup.component.tsx
@@ -76,12 +76,14 @@ const Tab = ({
const getTabComponent = () => {
const content = (
<>
-
+
{getTabIcon({ className: iconClassName, icon, showError, showWarning, size, active })}
- {label}
+
+ {label}
+
{getTabBadge(badge, badgeClassName)}
{getTabIndicator(showIndicator)}
-
+
{getTabDescription(description)}
>
)
diff --git a/src/Shared/Components/TabGroup/TabGroup.helpers.tsx b/src/Shared/Components/TabGroup/TabGroup.helpers.tsx
index 9aec1c1da..1f41d6338 100644
--- a/src/Shared/Components/TabGroup/TabGroup.helpers.tsx
+++ b/src/Shared/Components/TabGroup/TabGroup.helpers.tsx
@@ -49,7 +49,7 @@ export const getTabIcon = ({
}
export const getTabBadge = (badge: TabProps['badge'], className: string) =>
- badge !== null && {badge}
+ badge !== null && {badge}
export const getTabIndicator = (showIndicator: TabProps['showIndicator']) =>
showIndicator &&
diff --git a/src/Shared/Components/UserIdentifier/UserIdentifier.tsx b/src/Shared/Components/UserIdentifier/UserIdentifier.tsx
new file mode 100644
index 000000000..8e9318cc2
--- /dev/null
+++ b/src/Shared/Components/UserIdentifier/UserIdentifier.tsx
@@ -0,0 +1,77 @@
+import { getAlphabetIcon } from '@Common/Helper'
+import { Tooltip } from '@Common/Tooltip'
+import { API_TOKEN_PREFIX } from '@Shared/constants'
+import { useUserEmail } from '@Shared/Providers'
+
+import { Icon } from '../Icon'
+import { UserIdentifierProps } from './types'
+
+const UserIdentifierTooltip = ({
+ children,
+ tooltipContent,
+}: Pick) => (
+
+ {children}
+
+)
+
+export const UserIdentifier = ({
+ identifier,
+ children,
+ rootClassName,
+ tooltipContent,
+ isUserGroup = false,
+}: UserIdentifierProps) => {
+ // HOOKS
+ const { email: currentUserEmail } = useUserEmail()
+
+ if (!identifier) {
+ return null
+ }
+
+ // CONSTANTS
+ const isCurrentUser = identifier === currentUserEmail
+ const isApiToken = identifier.startsWith(API_TOKEN_PREFIX)
+
+ const renderIcon = () => {
+ if (isApiToken) {
+ return
+ }
+
+ return isUserGroup ? (
+
+ ) : (
+ getAlphabetIcon(identifier, 'dc__no-shrink m-0-imp')
+ )
+ }
+
+ const renderText = () => {
+ if (isCurrentUser) {
+ return 'You'
+ }
+
+ if (isApiToken) {
+ return identifier.split(':')?.[1] || '-'
+ }
+
+ return identifier
+ }
+
+ return (
+
+
+ {renderIcon()}
+
+
+ {renderText()}
+
+ {children}
+
+
+
+ )
+}
diff --git a/src/Shared/Components/UserIdentifier/index.ts b/src/Shared/Components/UserIdentifier/index.ts
new file mode 100644
index 000000000..0b3e4d0e6
--- /dev/null
+++ b/src/Shared/Components/UserIdentifier/index.ts
@@ -0,0 +1,2 @@
+export * from './types'
+export * from './UserIdentifier'
diff --git a/src/Shared/Components/UserIdentifier/types.ts b/src/Shared/Components/UserIdentifier/types.ts
new file mode 100644
index 000000000..7a2e3b8dc
--- /dev/null
+++ b/src/Shared/Components/UserIdentifier/types.ts
@@ -0,0 +1,12 @@
+import { ReactNode } from 'react'
+
+export interface UserIdentifierProps {
+ identifier: string
+ children?: ReactNode
+ isUserGroup?: boolean
+ rootClassName?: string
+ /**
+ * @description - If given, would show tooltip on div containing avatar, email and children
+ */
+ tooltipContent?: string
+}
diff --git a/src/Shared/Components/index.ts b/src/Shared/Components/index.ts
index 75d7f961e..365a95270 100644
--- a/src/Shared/Components/index.ts
+++ b/src/Shared/Components/index.ts
@@ -96,5 +96,6 @@ export * from './ThemeSwitcher'
export * from './ToggleResolveScopedVariables'
export * from './UnsavedChanges'
export * from './UnsavedChangesDialog'
+export * from './UserIdentifier'
export * from './VirtualizedList'
export * from './WorkflowOptionsModal'
diff --git a/src/Shared/types.ts b/src/Shared/types.ts
index 4b837338d..aaef6adc4 100644
--- a/src/Shared/types.ts
+++ b/src/Shared/types.ts
@@ -298,6 +298,8 @@ export interface WorkflowType {
showTippy?: boolean
appId?: number
isSelected?: boolean
+ isExceptionUser?: boolean
+ canApproverDeploy?: boolean
approvalConfiguredIdsMap?: Record
imageReleaseTags: string[]
appReleaseTags?: string[]