Skip to content

Commit 14c0746

Browse files
committed
Merge branch 'develop' of https://github.com/devtron-labs/devtron-fe-common-lib into feat/day-picker
2 parents 16c0e05 + bc1bafd commit 14c0746

45 files changed

Lines changed: 1200 additions & 502 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ src/Common/DebouncedSearch/__tests__/DebouncedSearch.test.tsx
2323
src/Common/DevtronProgressing/DevtronProgressing.tsx
2424
src/Common/Dialogs/DialogForm.tsx
2525
src/Common/DraggableWrapper/DraggableButton.tsx
26-
src/Common/DraggableWrapper/DraggableWrapper.tsx
2726
src/Common/Drawer/Drawer.tsx
2827
src/Common/Grid/Grid.tsx
2928
src/Common/Helper.tsx

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "1.21.0-beta-3",
3+
"version": "1.22.0-alpha-11",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Loading

src/Common/Constants.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ const DATA_PROTECTION_ROOT = '/data-protection-management'
6464
const DATA_PROTECTION_BACKUP_AND_SCHEDULE =
6565
`${DATA_PROTECTION_ROOT}/backup-and-schedule/:view(${Object.values(BackupAndScheduleListViewEnum).join('|')})` as const
6666
const GLOBAL_CONFIG_ROOT = '/global-configuration'
67-
const AI_RECOMMENDATIONS_ROOT = '/ai-recommendations'
68-
const OBSERVABILITY_ROOT = '/observability'
6967

7068
export const URLS = {
7169
LOGIN: '/login',
@@ -154,14 +152,7 @@ export const URLS = {
154152
GLOBAL_CONFIG_DOCKER: `${GLOBAL_CONFIG_ROOT}/docker`,
155153
GLOBAL_CONFIG_EDIT_CLUSTER: `${GLOBAL_CONFIG_ROOT}/cluster-env/edit/:clusterId`,
156154
PERMISSION_GROUPS: `${GLOBAL_CONFIG_ROOT}/auth/groups`,
157-
// AI RECOMMENDATIONS
158-
AI_RECOMMENDATIONS: AI_RECOMMENDATIONS_ROOT,
159-
AI_RECOMMENDATIONS_OVERVIEW: `${AI_RECOMMENDATIONS_ROOT}/overview`,
160155
EXTERNAL_APPS: 'ea',
161-
// OBSERVABILITY
162-
OBSERVABILITY: OBSERVABILITY_ROOT,
163-
OBSERVABILITY_OVERVIEW: `${OBSERVABILITY_ROOT}/overview`,
164-
OBSERVABILITY_CUSTOMER_LIST: `${OBSERVABILITY_ROOT}/tenants`,
165156
} as const
166157

167158
export const ROUTES = {
@@ -232,6 +223,7 @@ export const ROUTES = {
232223
LICENSE_DATA: 'license/data',
233224
ENV: 'env',
234225
APP_METADATA: 'app-metadata',
226+
RESOURCE_CONFLICTS_LIST: 'app/:appId/cd-pipeline/:pipelineId/history/:wfrId/helm-ownership-conflicts',
235227
} as const
236228

237229
export enum KEY_VALUE {

src/Common/DraggableWrapper/DraggableWrapper.tsx

Lines changed: 49 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,37 @@
1515
*/
1616

1717
import { useEffect, useRef, useState } from 'react'
18-
import Draggable, { ControlPosition, DraggableData } from 'react-draggable'
19-
import { DraggableWrapperProps, DraggablePositionVariant } from './types'
20-
import { useWindowSize } from '../Hooks'
18+
import Draggable, { ControlPosition } from 'react-draggable'
19+
20+
import { DEVTRON_BASE_MAIN_ID } from '@Shared/constants'
21+
2122
import { MAX_Z_INDEX } from '../Constants'
23+
import { useWindowSize } from '../Hooks'
24+
import { DraggablePositionVariant, DraggableWrapperProps } from './types'
2225

2326
/**
2427
* TODO: import it as lazy, after it is supported in common
2528
* 1. If using react select please use menuPlacement='auto'
2629
* 2. dragSelector will be used to identify the grabbable button that will grab the div to drag
27-
* 3. parentRef is the reference point from which we will derive the base top:0 ,left: 0 position
30+
* 3. The wrapper is positioned at the viewport's top-left (top: 0, left: 0) using fixed positioning; parentRef is an optional
31+
* reference that may be used for position calculations but is not the base origin for the coordinate system.
2832
*/
29-
export default function DraggableWrapper({
33+
const DraggableWrapper = ({
3034
children,
3135
zIndex = MAX_Z_INDEX,
3236
positionVariant,
3337
dragSelector,
3438
parentRef,
35-
boundaryGap = 16,
39+
boundaryGap = { x: 16, y: 16 },
3640
childDivProps = {},
37-
layoutFixDelta = 0,
38-
}: DraggableWrapperProps) {
41+
}: DraggableWrapperProps) => {
3942
const windowSize = useWindowSize()
4043
const nodeRef = useRef<HTMLDivElement>(null)
4144

42-
const [position, setPosition] = useState<ControlPosition>({
43-
x: 0,
44-
y: 0,
45-
})
45+
// letting the dom render the element without displaying it so that we know it's dimensions
46+
const [initialRenderDone, setInitialRenderDone] = useState(false)
4647

47-
const getDefaultPosition = (positionVariant: DraggablePositionVariant): ControlPosition => {
48+
const getDefaultPosition = (): ControlPosition => {
4849
// if this return x: 0, y: 0 then it will be top left corner of parentDiv
4950
const parentRect =
5051
parentRef?.current?.getBoundingClientRect() ??
@@ -60,73 +61,62 @@ export default function DraggableWrapper({
6061

6162
switch (positionVariant) {
6263
case DraggablePositionVariant.PARENT_BOTTOM_CENTER: {
63-
// currently at parentRect.x and need to start to the center of its width and half of node should lie on left of center and other half on right
64-
const x = (parentRect.width - nodeRefWidth) / 2
65-
// TODO (v3): Temp fix. Revisit
66-
const parentRectTop = parentRect.top > 0 ? parentRect.top : layoutFixDelta
67-
// currently at parentRect.y now parent height can be greater than windowSize.height so taking min
68-
// subtracting parentRect.top since window height already contains that
69-
const baseY =
70-
parentRect.height > windowSize.height ? windowSize.height - parentRectTop : parentRect.height
71-
const y = baseY - nodeRefHeight - boundaryGap
64+
// center div to middle of the parent rect and then add the left offset of the parent rect
65+
const x = (parentRect.width - nodeRefWidth) / 2 + parentRect.left
66+
if (parentRect.height > windowSize.height) {
67+
// since the parent itself overflows, we use windowSize for calculations
68+
return { x, y: windowSize.height - boundaryGap.y - nodeRefHeight }
69+
}
70+
// y = parentRect.bottom will place the widget at the extreme bottom of the parent,
71+
// therefore need to offset it to the top by boundary and its own height
72+
const y = parentRect.bottom - nodeRefHeight - boundaryGap.y
7273
return { x, y }
7374
}
7475
case DraggablePositionVariant.SCREEN_BOTTOM_RIGHT: {
75-
const x = windowSize.width - parentRect.left - nodeRefWidth - boundaryGap
76-
const y = windowSize.height - parentRect.top - nodeRefHeight - boundaryGap
76+
// x = windowSize.width will place the widget at the extreme right,
77+
// therefore need to offset it to the left by boundary and its own width
78+
const x = windowSize.width - nodeRefWidth - boundaryGap.x
79+
// y = windowSize.height will place the widget at the extreme bottom,
80+
// therefore need to offset it to the top by boundary and its own height
81+
const y = windowSize.height - nodeRefHeight - boundaryGap.y
7782

7883
return { x, y }
7984
}
8085
// Add more cases for other variants if needed
8186
default: {
82-
// Since need node to be in center of screen so subtracting width/2 by left of parentRect it will start the node from center but want node's midpoint at center so subtracting node's width from it.
83-
const x = windowSize.width / 2 - parentRect.left - nodeRefWidth / 2
84-
// subtracting top since windowSize already contains that
85-
const y = windowSize.height - parentRect.top - nodeRefHeight - boundaryGap
87+
// we need to first place the start of the widget at (windowSize.width / 2)
88+
// followed by moving it half of its own width to the left such that center of widget
89+
// aligns with the central axis of the screen
90+
const x = (windowSize.width - nodeRefWidth) / 2
91+
// y = windowSize.height will place the widget at the extreme bottom,
92+
// therefore need to offset it to the top by boundary and its own height
93+
const y = windowSize.height - nodeRefHeight - boundaryGap.y
8694

8795
return { x, y }
8896
}
8997
}
9098
}
9199

92-
// On change of windowSize we will reset the position to default
93100
useEffect(() => {
94-
const defaultPosition = getDefaultPosition(positionVariant)
95-
setPosition(defaultPosition)
96-
}, [nodeRef, positionVariant, windowSize])
97-
98-
// Would be called on drag and will not update the state if the new position is out of window screen
99-
function handlePositionChange(e, data: DraggableData) {
100-
const offsetX = parentRef?.current?.getBoundingClientRect().left ?? 0
101-
const offsetY = parentRef?.current?.getBoundingClientRect().top ?? 0
102-
103-
const nodeRefHeight = nodeRef.current?.getBoundingClientRect().height ?? 0
104-
const nodeRefWidth = nodeRef.current?.getBoundingClientRect().width ?? 0
105-
106-
if (
107-
offsetX + data.x + nodeRefWidth + boundaryGap > windowSize.width ||
108-
offsetY + data.y + nodeRefHeight + boundaryGap > windowSize.height ||
109-
offsetX + data.x < 0 ||
110-
offsetY + data.y < 0
111-
) {
112-
return
113-
}
114-
115-
setPosition({
116-
x: data.x,
117-
y: data.y,
118-
})
119-
}
101+
// make the element visible after the initial render
102+
setInitialRenderDone(true)
103+
}, [])
120104

121105
return (
122106
// Since we are using position fixed so we need to disable click on the div so that it does not interfere with the click of other elements
123107
<div
124-
className="dc__position-fixed dc__disable-click"
108+
className={`dc__position-fixed dc__disable-click dc__top-0 dc__left-0 ${initialRenderDone ? '' : 'dc__visibility-hidden'}`}
125109
style={{
126110
zIndex,
127111
}}
128112
>
129-
<Draggable handle={dragSelector} nodeRef={nodeRef} position={position} onDrag={handlePositionChange}>
113+
<Draggable
114+
key={`${windowSize.height}-${windowSize.width}-${initialRenderDone}`}
115+
handle={dragSelector}
116+
defaultPosition={getDefaultPosition()}
117+
bounds={`#${DEVTRON_BASE_MAIN_ID}`}
118+
nodeRef={nodeRef}
119+
>
130120
<div
131121
ref={nodeRef}
132122
{...childDivProps}
@@ -141,3 +131,5 @@ export default function DraggableWrapper({
141131
</div>
142132
)
143133
}
134+
135+
export default DraggableWrapper

src/Common/DraggableWrapper/types.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { HTMLAttributes, ReactNode, RefObject } from 'react'
1818

1919
export enum DraggablePositionVariant {
2020
PARENT_BOTTOM_CENTER = 'PARENT_BOTTOM_CENTER',
21+
PARENT_BOTTOM_RIGHT = 'PARENT_BOTTOM_RIGHT',
2122
SCREEN_BOTTOM_CENTER = 'SCREEN_BOTTOM_CENTER',
2223
SCREEN_BOTTOM_RIGHT = 'SCREEN_BOTTOM_RIGHT',
2324
// Can add more based on requirement
@@ -35,13 +36,8 @@ export interface DraggableWrapperProps {
3536
*/
3637
dragSelector: string
3738
parentRef?: RefObject<HTMLDivElement>
38-
boundaryGap?: number
39+
boundaryGap?: Record<'x' | 'y', number>
3940
childDivProps?: HTMLAttributes<HTMLDivElement>
40-
/**
41-
* Delta for fixing the scrollable layout positioning
42-
* @deprecated
43-
*/
44-
layoutFixDelta?: number
4541
}
4642

4743
/**
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './types'
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { customEnv, Never } from 'src'
2+
3+
import { IconsProps } from '@Shared/Components'
4+
5+
export type NavigationItemID =
6+
| 'application-management-overview'
7+
| 'application-management-devtron-applications'
8+
| 'application-management-application-groups'
9+
| 'application-management-bulk-edit'
10+
| 'application-management-application-templates'
11+
| 'application-management-projects'
12+
| 'application-management-configurations'
13+
| 'application-management-policies'
14+
| 'infrastructure-management-overview'
15+
| 'infrastructure-management-applications'
16+
| 'infrastructure-management-chart-store'
17+
| 'infrastructure-management-resource-browser'
18+
| 'infrastructure-management-resource-watcher'
19+
| 'infrastructure-management-catalog-framework'
20+
| 'software-release-management-overview'
21+
| 'software-release-management-release-hub'
22+
| 'software-release-management-tenants'
23+
| 'cost-visibility-overview'
24+
| 'cost-visibility-cost-breakdown'
25+
| 'cost-visibility-configurations'
26+
| 'security-center-overview'
27+
| 'security-center-security-vulnerabilities'
28+
| 'security-center-security-enablement'
29+
| 'security-center-security-policy'
30+
| 'automation-and-enablement-jobs'
31+
| 'automation-and-enablement-alerting'
32+
| 'automation-and-enablement-incident-response'
33+
| 'automation-and-enablement-api-portal'
34+
| 'automation-and-enablement-runbook-automation'
35+
| 'global-configuration-sso-login-services'
36+
| 'global-configuration-host-urls'
37+
| 'global-configuration-external-links'
38+
| 'global-configuration-chart-repository'
39+
| 'global-configuration-cluster-and-environments'
40+
| 'global-configuration-container-oci-registry'
41+
| 'global-configuration-authorization'
42+
| 'data-protection-overview'
43+
| 'data-protection-backup-and-schedule'
44+
| 'data-protection-restores'
45+
| 'data-protection-backup-repositories'
46+
| 'data-protection-backup-locations'
47+
| 'data-protection-history-and-logs'
48+
49+
export type NavigationSubMenuItemID =
50+
| 'application-management-configurations-gitops'
51+
| 'application-management-configurations-git-accounts'
52+
| 'application-management-configurations-deployment-charts'
53+
| 'application-management-configurations-notifications'
54+
| 'application-management-configurations-catalog-frameworks'
55+
| 'application-management-configurations-scoped-variables'
56+
| 'application-management-configurations-build-infra'
57+
| 'application-management-policies-deployment-window'
58+
| 'application-management-policies-approval-policy'
59+
| 'application-management-policies-plugin-policy'
60+
| 'application-management-policies-pull-image-digest'
61+
| 'application-management-policies-tag-policy'
62+
| 'application-management-policies-filter-conditions'
63+
| 'application-management-policies-image-promotion'
64+
| 'application-management-policies-lock-deployment-configuration'
65+
| 'cost-visibility-cost-breakdown-clusters'
66+
| 'cost-visibility-cost-breakdown-environments'
67+
| 'cost-visibility-cost-breakdown-projects'
68+
| 'cost-visibility-cost-breakdown-applications'
69+
| 'global-configuration-authorization-user-permissions'
70+
| 'global-configuration-authorization-permission-groups'
71+
| 'global-configuration-authorization-api-tokens'
72+
73+
export type NavigationRootItemID =
74+
| 'application-management'
75+
| 'infrastructure-management'
76+
| 'software-release-management'
77+
| 'cost-visibility'
78+
| 'security-center'
79+
| 'automation-and-enablement'
80+
| 'data-protection-management'
81+
| 'global-configuration'
82+
83+
export type CommonNavigationItemType = {
84+
title: string
85+
dataTestId: string
86+
icon: IconsProps['name']
87+
href: string
88+
disabled?: boolean
89+
keywords?: string[]
90+
forceHideEnvKey?: keyof customEnv
91+
hideNav?: boolean
92+
isAvailableInEA?: boolean
93+
}
94+
95+
export type NavigationItemType = Pick<
96+
CommonNavigationItemType,
97+
'dataTestId' | 'title' | 'disabled' | 'keywords' | 'hideNav' | 'forceHideEnvKey' | 'isAvailableInEA'
98+
> & {
99+
id: NavigationItemID
100+
} & (
101+
| (Pick<CommonNavigationItemType, 'icon' | 'href'> & {
102+
hasSubMenu?: false
103+
subItems?: never
104+
})
105+
| (Never<Pick<CommonNavigationItemType, 'icon' | 'href'>> & {
106+
hasSubMenu: true
107+
subItems: (Omit<CommonNavigationItemType, 'icon'> & { id: NavigationSubMenuItemID })[]
108+
})
109+
)
110+
111+
export interface NavigationGroupType
112+
extends Pick<CommonNavigationItemType, 'title' | 'icon' | 'hideNav' | 'forceHideEnvKey' | 'isAvailableInEA'> {
113+
id: NavigationRootItemID
114+
items: NavigationItemType[]
115+
disabled?: boolean
116+
}

0 commit comments

Comments
 (0)