Skip to content

feat: manual canary control & its visibility #2726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
51b9b16
feat: update loading card and use from fe-common
arunjaindev May 15, 2025
3365693
feat: add app name in cd button
arunjaindev May 18, 2025
d410bb8
chore: version bump
arunjaindev May 19, 2025
0b7b851
feat: Environment Overview
RohitRaj011 May 16, 2025
664dbe9
feat: add checkbox error state asset and class
RohitRaj011 May 20, 2025
3b034bb
feat: EnvironmentOverview - integrate ManageTraffic, code optimizations
RohitRaj011 May 20, 2025
fd4a932
feat: add strategy feasibility modal in bulk cd
arunjaindev May 20, 2025
eb0e595
Merge branch 'feat/canary-details-app' of github.com:devtron-labs/das…
RohitRaj011 May 21, 2025
9489bbe
fix: rollback and deploy modal opening together
arunjaindev May 21, 2025
5fd00b1
Merge pull request #2710 from devtron-labs/feat/canary-details-app
arunjaindev May 21, 2025
2b6e3c5
fix: EnvironmentOverview - initial loading state set to false
RohitRaj011 May 21, 2025
2c80d53
Merge pull request #2718 from devtron-labs/feat/app-group-manage-traffic
RohitRaj011 May 21, 2025
0dc27e2
feat: integrate FEATURE_MANAGE_TRAFFIC_ENABLE flag
RohitRaj011 May 22, 2025
a4a2a95
feat: add util for getting workflows which can be triggered
arunjaindev May 22, 2025
32225c0
fix: skip deployment if strategy not selected
arunjaindev May 22, 2025
2f06fec
chore: use nullish operator
arunjaindev May 22, 2025
68da4c8
chore: common-lib version bump
RohitRaj011 May 22, 2025
1dd6522
feat: filter default strategy
arunjaindev May 23, 2025
7861c44
Merge branch 'feature/canary-visibility' of https://github.com/devtro…
arunjaindev May 23, 2025
444226c
chore: add util for getting cd node
arunjaindev May 23, 2025
205f584
chore: remove redundant null check
arunjaindev May 23, 2025
01cf4db
Merge pull request #2727 from devtron-labs/feat/feasible-pipelines
arunjaindev May 23, 2025
d155bcc
feat: Move BulkManageTrafficDrawer to route
RohitRaj011 May 26, 2025
ac34dc0
Merge pull request #2733 from devtron-labs/refactor/manage-traffic
RohitRaj011 May 26, 2025
e98e308
chore: version bump
arunjaindev May 26, 2025
ed40977
chore: update z index
arunjaindev May 26, 2025
66da845
chore: update mechanical operation svg
arunjaindev May 26, 2025
4fa3e24
feat: add checkbox selected error dark asset
RohitRaj011 May 26, 2025
3a02f35
feat: add css for fit content
arunjaindev May 27, 2025
ac59e32
chore: add flex wrap on app details card
arunjaindev May 27, 2025
d0d8c06
chore: update row gap in app detail cards
arunjaindev May 27, 2025
a2fd46f
chore: dev mode - enable manage traffic flag
RohitRaj011 May 27, 2025
1a5d9e3
chore: add color in hex to fill map
arunjaindev May 29, 2025
0646195
chore: add ga event
arunjaindev May 29, 2025
3af7803
Merge branch 'main' of github.com:devtron-labs/dashboard into feature…
RohitRaj011 May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ FEATURE_DEFAULT_AUTHENTICATED_VIEW_ENABLE=false
GATEKEEPER_URL=https://license.devtron.ai/dashboard
FEATURE_AI_INTEGRATION_ENABLE=false
LOGIN_PAGE_IMAGE=
FEATURE_MANAGE_TRAFFIC_ENABLE=false
FEATURE_REDFISH_NODE_ENABLE=false
3 changes: 0 additions & 3 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ vite.config.mts
src/Pages/GlobalConfigurations/Authorization/APITokens/__tests__/ApiTokens.test.tsx
src/components/AppSelector/ChartSelector.tsx
src/components/ApplicationGroup/AppGroup.service.ts
src/components/ApplicationGroup/AppGroup.types.ts
src/components/ApplicationGroup/AppGroup.utils.ts
src/components/ApplicationGroup/AppGroupAppFilter.components.tsx
src/components/ApplicationGroup/AppGroupAppFilter.tsx
src/components/ApplicationGroup/AppGroupDetailsRoute.tsx
src/components/ApplicationGroup/AppGroupRoute.tsx
src/components/ApplicationGroup/Constants.ts
Expand All @@ -23,7 +21,6 @@ src/components/ApplicationGroup/Details/EnvCIDetails/EnvCIDetails.tsx
src/components/ApplicationGroup/Details/EnvCIDetails/__test__/EnvCIDetails.test.tsx
src/components/ApplicationGroup/Details/EnvironmentConfig/__test__/ApplicationRoutes.test.tsx
src/components/ApplicationGroup/Details/EnvironmentConfig/__test__/EnvConfig.test.tsx
src/components/ApplicationGroup/Details/EnvironmentOverview/EnvironmentOverview.tsx
src/components/ApplicationGroup/Details/EnvironmentOverview/HibernateModal.tsx
src/components/ApplicationGroup/Details/EnvironmentOverview/HibernateStatusListDrawer.tsx
src/components/ApplicationGroup/Details/EnvironmentOverview/HibernateStatusRow.tsx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ export const EnvironmentOverviewTableHeaderValues: Record<keyof typeof Environme
DEPLOYED_BY: 'DEPLOYED BY',
STATUS: null,
}

export const ENVIRONMENT_OVERVIEW_DRAG_SELECTOR_IDENTIFIER = 'environment-overview-drag-selector'
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2024. Devtron Inc.
*/

import { useEffect } from 'react'

import {
Button,
ButtonStyleType,
ButtonVariantType,
ComponentSizeType,
DraggableButton,
DraggablePositionVariant,
DraggableWrapper,
Icon,
useRegisterShortcut,
} from '@devtron-labs/devtron-fe-common-lib'

import { ENVIRONMENT_OVERVIEW_DRAG_SELECTOR_IDENTIFIER } from './EnvironmentOverview.constants'
import { EnvironmentOverviewPopupMenu } from './EnvironmentOverviewPopupMenu'
import { EnvironmentOverviewBulkSelectionWidgetProps } from './EnvironmentOverviewTable.types'

export const EnvironmentOverviewBulkSelectionWidget = ({
count,
onClose,
parentRef,
popUpMenuItems,
children,
}: EnvironmentOverviewBulkSelectionWidgetProps) => {
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()

useEffect(() => {
registerShortcut({ keys: ['Escape'], callback: onClose })

return () => {
unregisterShortcut(['Escape'])
}
}, [])

return (
<DraggableWrapper
dragSelector={`.${ENVIRONMENT_OVERVIEW_DRAG_SELECTOR_IDENTIFIER}`}
positionVariant={DraggablePositionVariant.PARENT_BOTTOM_CENTER}
zIndex="calc(var(--modal-index) - 1)"
parentRef={parentRef}
>
<div className="bulk-selection-widget br-8 pl-7 pr-11 py-11 flex dc__gap-8">
<DraggableButton dragClassName={ENVIRONMENT_OVERVIEW_DRAG_SELECTOR_IDENTIFIER} />
<div className="flex dc__gap-8 fs-13 lh-20 fw-6">
<span className="bcb-5 br-4 px-6 cn-0">{count}</span>
<span className="cn-9">Selected</span>
</div>
<div className="w-1 h-20 bcb-1" />
{children}
{popUpMenuItems.length > 0 && <EnvironmentOverviewPopupMenu popUpMenuItems={popUpMenuItems} />}
<div className="w-1 h-20 bcb-1" />
<Button
icon={<Icon name="ic-close-large" color={null} />}
dataTestId="environment-overview-table-action-widget-close"
style={ButtonStyleType.negativeGrey}
variant={ButtonVariantType.borderLess}
ariaLabel="Clear selection(s)"
size={ComponentSizeType.small}
onClick={onClose}
showAriaLabelInTippy={false}
/>
</div>
</DraggableWrapper>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// TODO: Replace this with ActionMenu component
import {
Button,
ButtonStyleType,
ButtonVariantType,
ComponentSizeType,
Icon,
PopupMenu,
} from '@devtron-labs/devtron-fe-common-lib'

import { EnvironmentOverviewTableRow } from './EnvironmentOverviewTable.types'

export const EnvironmentOverviewPopupMenu = ({
popUpMenuItems,
}: Pick<EnvironmentOverviewTableRow, 'popUpMenuItems'>) => (
<PopupMenu autoClose>
<PopupMenu.Button isKebab rootClassName="p-0 dc__no-border cursor">
<Button
icon={<Icon name="ic-more-vertical" color={null} />}

Check failure on line 19 in src/Pages/Shared/EnvironmentOverviewTable/EnvironmentOverviewPopupMenu.tsx

View workflow job for this annotation

GitHub Actions / ci

Type '"ic-more-vertical"' is not assignable to type '"ic-arrow-clockwise" | "ic-73strings" | "ic-aborted" | "ic-add" | "ic-amazon-eks" | "ic-apica" | "ic-app-group" | "ic-arrow-right" | "ic-arrow-square-out" | "ic-arrows-left-right" | ... 142 more ... | "ic-wifi-slash"'.
dataTestId="environment-overview-pop-up-menu"
style={ButtonStyleType.neutral}
variant={ButtonVariantType.borderLess}
ariaLabel="environment-overview-pop-up-menu"
size={ComponentSizeType.xs}
showAriaLabelInTippy={false}
/>
</PopupMenu.Button>
<PopupMenu.Body rootClassName="dc__border py-4 w-180">
{popUpMenuItems.map((popUpMenuItem) => {
if ('label' in popUpMenuItem) {
const { label, onClick, disabled, iconName } = popUpMenuItem

return (
<button
key={label}
type="button"
className={`dc__transparent w-100 py-6 px-8 flexbox dc__align-items-center dc__gap-8 ${disabled ? ' dc__opacity-0_5 cursor-not-allowed' : 'dc__hover-n50'}`}
onClick={onClick}
disabled={disabled}
>
{iconName && <Icon name={iconName} color="N800" />}
<span className="dc__truncate cn-9 fs-13 lh-20">{label}</span>
</button>
)
}

return popUpMenuItem
})}
</PopupMenu.Body>
</PopupMenu>
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
getRandomColor,
handleRelativeDateSorting,
ImageChipCell,
PopupMenu,
processDeployedTime,
RegistryType,
SortableTableHeaderCell,
Expand All @@ -38,56 +37,18 @@ import {
import { ReactComponent as ICActivity } from '@Icons/ic-activity.svg'
import { ReactComponent as ICArrowLineDown } from '@Icons/ic-arrow-line-down.svg'
import { ReactComponent as DevtronIcon } from '@Icons/ic-devtron-app.svg'
import { ReactComponent as ICMoreOption } from '@Icons/ic-more-option.svg'

import {
EnvironmentOverviewTableHeaderFixedKeys,
EnvironmentOverviewTableHeaderValues,
EnvironmentOverviewTableHeaderVariableKeys,
EnvironmentOverviewTableSortableKeys,
} from './EnvironmentOverview.constants'
import {
EnvironmentOverviewTableProps,
EnvironmentOverviewTableRow,
EnvironmentOverviewTableRowData,
} from './EnvironmentOverviewTable.types'
import { EnvironmentOverviewPopupMenu } from './EnvironmentOverviewPopupMenu'
import { EnvironmentOverviewTableProps, EnvironmentOverviewTableRowData } from './EnvironmentOverviewTable.types'

import './EnvironmentOverviewTable.scss'

const renderPopUpMenu = (items: EnvironmentOverviewTableRow['popUpMenuItems']) => (
<PopupMenu autoClose>
<PopupMenu.Button isKebab rootClassName="p-4 flex dc__no-border cursor">
<ICMoreOption className="icon-dim-16 fcn-6 rotateBy--90" />
</PopupMenu.Button>
<PopupMenu.Body rootClassName="dc__border py-4 w-180">
{items.map((popUpMenuItem) => {
if ('label' in popUpMenuItem) {
const { label, onClick, disabled, Icon, iconType = 'fill' } = popUpMenuItem

return (
<button
key={label}
type="button"
className={`dc__transparent w-100 py-6 px-8 flexbox dc__align-items-center dc__gap-8 ${disabled ? ' dc__opacity-0_5 cursor-not-allowed' : 'dc__hover-n50'}`}
onClick={onClick}
disabled={disabled}
>
{Icon && (
<Icon
className={`icon-dim-16 ${iconType === 'fill' ? 'fcn-7' : ''} ${iconType === 'stroke' ? 'scn-7' : ''}`}
/>
)}
<span className="dc__truncate cn-9 fs-13 lh-20">{label}</span>
</button>
)
}

return popUpMenuItem
})}
</PopupMenu.Body>
</PopupMenu>
)

export const EnvironmentOverviewTable = ({
rows = [],
isVirtualEnv,
Expand All @@ -108,10 +69,10 @@ export const EnvironmentOverviewTable = ({
() =>
rows.sort((a, b) => {
if (sortBy === EnvironmentOverviewTableSortableKeys.DEPLOYED_AT) {
return handleRelativeDateSorting(a.environment.deployedAt, b.environment.deployedAt, sortOrder)
return handleRelativeDateSorting(a.app.deployedAt, b.app.deployedAt, sortOrder)
}

return stringComparatorBySortOrder(a.environment.name, b.environment.name, sortOrder)
return stringComparatorBySortOrder(a.app.name, b.app.name, sortOrder)
}),
[rows, sortBy, sortOrder],
)
Expand Down Expand Up @@ -202,15 +163,15 @@ export const EnvironmentOverviewTable = ({
)

const renderRow = ({
environment,
app,
isChecked,
deployedAtLink,
redirectLink,
onCommitClick,
onLastDeployedImageClick,
popUpMenuItems = [],
}: EnvironmentOverviewTableProps['rows'][0]) => {
const { id, name, status, commits, deployedAt, deployedBy, deploymentStatus, lastDeployedImage } = environment
const { id, name, status, commits, deployedAt, deployedBy, deploymentStatus, lastDeployedImage } = app

return (
<div className={`environment-overview-table__row ${isChecked ? isCheckedRowClassName : ''}`}>
Expand All @@ -231,7 +192,7 @@ export const EnvironmentOverviewTable = ({
{name}
</Link>
</Tooltip>
{!!popUpMenuItems?.length && renderPopUpMenu(popUpMenuItems)}
{!!popUpMenuItems?.length && <EnvironmentOverviewPopupMenu popUpMenuItems={popUpMenuItems} />}
</div>
</div>
<div
Expand Down Expand Up @@ -283,7 +244,7 @@ export const EnvironmentOverviewTable = ({
<div className="environment-overview-table dc__border br-4 bg__primary w-100">
{renderHeaderRow()}
{sortedRows.map((row) => (
<Fragment key={row.environment.id}>{renderRow(row)}</Fragment>
<Fragment key={row.app.id}>{renderRow(row)}</Fragment>
))}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

import { FunctionComponent, MouseEvent, ReactElement, SVGProps } from 'react'
import { MouseEvent, MutableRefObject, PropsWithChildren, ReactElement } from 'react'

import { IconName } from '@devtron-labs/devtron-fe-common-lib'

import { EnvironmentOverviewTableHeaderKeys } from './EnvironmentOverview.constants'

Expand All @@ -32,15 +34,14 @@ export interface EnvironmentOverviewTableRowData {
export type EnvironmentOverviewTablePopUpMenuItem =
| {
label: string
Icon?: FunctionComponent<SVGProps<SVGSVGElement>>
iconType?: 'fill' | 'stroke'
iconName?: IconName
disabled?: boolean
onClick?: (event: MouseEvent<HTMLButtonElement>) => void
}
| ReactElement

export interface EnvironmentOverviewTableRow {
environment: EnvironmentOverviewTableRowData
app: EnvironmentOverviewTableRowData
isChecked?: boolean
onLastDeployedImageClick: (event: MouseEvent<HTMLButtonElement>) => void
onCommitClick: (event: MouseEvent<HTMLButtonElement>) => void
Expand All @@ -54,3 +55,11 @@ export interface EnvironmentOverviewTableProps {
isVirtualEnv?: boolean
onCheckboxSelect: (id: EnvironmentOverviewTableRowData['id'], isChecked: boolean, isAllChecked: boolean) => void
}

export interface EnvironmentOverviewBulkSelectionWidgetProps
extends PropsWithChildren<{
count: number
onClose: () => void
parentRef: MutableRefObject<HTMLDivElement>
}>,
Pick<EnvironmentOverviewTableRow, 'popUpMenuItems'> {}
1 change: 1 addition & 0 deletions src/Pages/Shared/EnvironmentOverviewTable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
*/

export { EnvironmentOverviewTableSortableKeys } from './EnvironmentOverview.constants'
export * from './EnvironmentOverviewBulkSelectionActionWidget'
export * from './EnvironmentOverviewTable.component'
export * from './EnvironmentOverviewTable.types'
4 changes: 4 additions & 0 deletions src/assets/icons/dark/ic-checkbox-selected-error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/assets/icons/ic-checkbox-selected-error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading