Skip to content

Commit fbb3975

Browse files
authored
Merge pull request #804 from devtron-labs/fix/rb-table
fix: rb table
2 parents a30adde + ec6a4c9 commit fbb3975

19 files changed

Lines changed: 257 additions & 168 deletions

File tree

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.16.0-pre-4",
3+
"version": "1.16.0-beta-6",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Common/Checkbox/Checkbox.tsx

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { forwardRef } from 'react'
18+
19+
import { stopPropagation } from '@Common/Helper'
20+
1721
import { CheckboxProps } from '../Types'
1822

1923
import './Checkbox.scss'
@@ -28,38 +32,32 @@ Valid States of Checkbox:
2832
6. disabled: false, checked: true, value: CHECKED
2933
*/
3034
// TODO: Associate label with input element
31-
export const Checkbox = ({
32-
rootClassName,
33-
onClick,
34-
name,
35-
disabled,
36-
value,
37-
onChange,
38-
tabIndex,
39-
isChecked,
40-
id,
41-
dataTestId,
42-
children,
43-
}: CheckboxProps) => {
44-
const rootClass = `${rootClassName || ''}`
35+
export const Checkbox = forwardRef<HTMLLabelElement, CheckboxProps>(
36+
(
37+
{ rootClassName, onClick, name, disabled, value, onChange, tabIndex, isChecked, id, dataTestId, children },
38+
forwardedRef,
39+
) => {
40+
const rootClass = `${rootClassName || ''}`
4541

46-
return (
47-
// eslint-disable-next-line jsx-a11y/label-has-associated-control
48-
<label className={`dc__position-rel flex left cursor ${rootClass}`} onClick={onClick}>
49-
<input
50-
{...(name ? { name } : {})}
51-
type="checkbox"
52-
className="form__checkbox"
53-
disabled={disabled}
54-
value={value}
55-
onChange={onChange}
56-
tabIndex={tabIndex}
57-
checked={isChecked}
58-
id={id}
59-
data-testid={dataTestId}
60-
/>
61-
<span className="form__checkbox-container" data-testid={`${dataTestId}-chk-span`} />
62-
<span className="form__checkbox-label">{children}</span>
63-
</label>
64-
)
65-
}
42+
return (
43+
// eslint-disable-next-line jsx-a11y/label-has-associated-control
44+
<label ref={forwardedRef} className={`dc__position-rel flex left cursor ${rootClass}`} onClick={onClick}>
45+
<input
46+
{...(name ? { name } : {})}
47+
type="checkbox"
48+
className="form__checkbox"
49+
disabled={disabled}
50+
value={value}
51+
onChange={onChange}
52+
tabIndex={tabIndex}
53+
checked={isChecked}
54+
id={id}
55+
data-testid={dataTestId}
56+
onClick={stopPropagation}
57+
/>
58+
<span className="form__checkbox-container" data-testid={`${dataTestId}-chk-span`} />
59+
<span className="form__checkbox-label">{children}</span>
60+
</label>
61+
)
62+
},
63+
)

src/Common/Hooks/UseRegisterShortcut/UseRegisterShortcutProvider.tsx

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { useCallback, useEffect, useMemo, useRef } from 'react'
17+
import { KeyboardEvent, useCallback, useEffect, useMemo, useRef } from 'react'
1818
import { deepEquals } from '@rjsf/utils'
1919

20+
import { noop } from '@Common/Helper'
21+
2022
import { ShortcutType, UseRegisterShortcutContextType, UseRegisterShortcutProviderType } from './types'
2123
import { UseRegisterShortcutContext } from './UseRegisterShortcutContext'
2224
import { preprocessKeys, verifyCallbackStack } from './utils'
@@ -25,7 +27,7 @@ const IGNORE_TAGS_FALLBACK = ['input', 'textarea', 'select']
2527
const DEFAULT_TIMEOUT = 300
2628

2729
const UseRegisterShortcutProvider = ({
28-
containerRef,
30+
shouldHookOntoWindow = true,
2931
ignoreTags,
3032
preventDefault = false,
3133
shortcutTimeout,
@@ -117,13 +119,12 @@ const UseRegisterShortcutProvider = ({
117119
}
118120
}, [])
119121

120-
const handleKeydownEvent = useCallback((event: KeyboardEvent) => {
122+
const handleKeydownEvent = useCallback((event: KeyboardEvent<HTMLElement>) => {
121123
if (
122124
// NOTE: in case of custom events generated by password managers autofill, the event.key is not set
123125
!event.key ||
124-
(ignoredTags.map((tag) => tag.toUpperCase()).indexOf((event.target as HTMLElement).tagName?.toUpperCase()) >
125-
-1 &&
126-
(!containerRef || containerRef.current?.contains(event.target as HTMLElement))) ||
126+
ignoredTags.map((tag) => tag.toUpperCase()).indexOf((event.target as HTMLElement).tagName?.toUpperCase()) >
127+
-1 ||
127128
(event.target as HTMLElement)?.role === 'textbox' ||
128129
disableShortcutsRef.current
129130
) {
@@ -161,29 +162,48 @@ const UseRegisterShortcutProvider = ({
161162
}, [])
162163

163164
useEffect(() => {
164-
window.addEventListener('keydown', handleKeydownEvent)
165+
if (!shouldHookOntoWindow) {
166+
return noop
167+
}
168+
169+
window.addEventListener('keydown', handleKeydownEvent as unknown as (event: globalThis.KeyboardEvent) => void)
165170
window.addEventListener('keyup', handleKeyupEvent)
166171
window.addEventListener('blur', handleBlur)
167172

168173
return () => {
169-
window.removeEventListener('keydown', handleKeydownEvent)
174+
window.removeEventListener(
175+
'keydown',
176+
handleKeydownEvent as unknown as (event: globalThis.KeyboardEvent) => void,
177+
)
170178
window.removeEventListener('keyup', handleKeyupEvent)
171179
window.removeEventListener('blur', handleBlur)
172180

173181
if (keyDownTimeoutRef.current > -1) {
174182
clearTimeout(keyDownTimeoutRef.current)
175183
}
176184
}
177-
}, [handleKeyupEvent, handleKeydownEvent, handleBlur])
185+
}, [handleKeyupEvent, handleKeydownEvent, handleBlur, shouldHookOntoWindow])
178186

179187
const providerValue: UseRegisterShortcutContextType = useMemo(
180188
() => ({
181189
registerShortcut,
182190
unregisterShortcut,
183191
setDisableShortcuts,
184192
triggerShortcut,
193+
...(!shouldHookOntoWindow
194+
? { targetProps: { onKeyDown: handleKeydownEvent, onKeyUp: handleKeyupEvent, onBlur: handleBlur } }
195+
: {}),
185196
}),
186-
[registerShortcut, unregisterShortcut, setDisableShortcuts, triggerShortcut],
197+
[
198+
registerShortcut,
199+
unregisterShortcut,
200+
setDisableShortcuts,
201+
triggerShortcut,
202+
shouldHookOntoWindow,
203+
handleKeydownEvent,
204+
handleKeyupEvent,
205+
handleBlur,
206+
],
187207
)
188208

189209
return <UseRegisterShortcutContext.Provider value={providerValue}>{children}</UseRegisterShortcutContext.Provider>

src/Common/Hooks/UseRegisterShortcut/types.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { RefObject } from 'react'
17+
import { FocusEvent, KeyboardEvent } from 'react'
1818

1919
import { IS_PLATFORM_MAC_OS } from '@Common/Constants'
2020

@@ -80,10 +80,26 @@ export interface UseRegisterShortcutContextType {
8080
* Programmatically trigger a shortcut if already registered
8181
*/
8282
triggerShortcut: (keys: ShortcutType['keys']) => void
83+
/**
84+
* If shouldHookOntoWindow is false, these props need to be hooked onto
85+
* the component that needs to listen to the shortcuts
86+
*/
87+
targetProps?: {
88+
onKeyDown: (event: KeyboardEvent<HTMLElement>) => void
89+
onKeyUp: (event: KeyboardEvent<HTMLElement>) => void
90+
onBlur: (event: FocusEvent<HTMLElement>) => void
91+
}
8392
}
8493

8594
export interface UseRegisterShortcutProviderType {
86-
containerRef?: RefObject<HTMLElement>
95+
/**
96+
* If false, the shortcuts will not be registered to the window object
97+
* instead onKeyDown, onKeyUp and onBlur will be exposed as context methods
98+
* which need to be hooked onto the component that needs to listen to the shortcuts
99+
*
100+
* defaults to true
101+
*/
102+
shouldHookOntoWindow?: boolean
87103
children: React.ReactNode
88104
/**
89105
* Defines how long after holding the keys down do we trigger the callback in milliseconds

src/Common/Modals/VisibleModal.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class VisibleModal extends React.Component<{
2727
onEscape?: (e) => void
2828
}> {
2929
modalRef = document.getElementById('visible-modal')
30+
previousActiveElement: HTMLElement | null = null
3031

3132
constructor(props) {
3233
super(props)
@@ -50,6 +51,8 @@ export class VisibleModal extends React.Component<{
5051
this.modalRef.classList.add(this.props.noBackground ? 'show' : 'show-with-bg')
5152
preventBodyScroll(true)
5253

54+
this.previousActiveElement = document.activeElement as HTMLElement
55+
5356
if (this.props.parentClassName) {
5457
this.modalRef.classList.add(this.props.parentClassName)
5558
}
@@ -61,6 +64,8 @@ export class VisibleModal extends React.Component<{
6164
this.modalRef.classList.remove('show-with-bg')
6265
preventBodyScroll(false)
6366

67+
this.previousActiveElement?.focus({ preventScroll: true })
68+
6469
if (this.props.parentClassName) {
6570
this.modalRef.classList.remove(this.props.parentClassName)
6671
}

src/Common/Modals/VisibleModal2.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { stopPropagation } from '../Helper'
2121

2222
export class VisibleModal2 extends React.Component<{ className?: string; close?: (e) => void }> {
2323
modalRef = document.getElementById('visible-modal-2')
24+
previousActiveElement: HTMLElement | null = null
2425

2526
constructor(props) {
2627
super(props)
@@ -38,12 +39,14 @@ export class VisibleModal2 extends React.Component<{ className?: string; close?:
3839
document.addEventListener('keydown', this.escFunction)
3940
this.modalRef.classList.add('show-with-bg')
4041
preventBodyScroll(true)
42+
this.previousActiveElement = document.activeElement as HTMLElement
4143
}
4244

4345
componentWillUnmount() {
4446
document.removeEventListener('keydown', this.escFunction)
4547
this.modalRef.classList.remove('show-with-bg')
4648
preventBodyScroll(false)
49+
this.previousActiveElement?.focus({ preventScroll: true })
4750
}
4851

4952
handleBodyClick = (e: SyntheticEvent) => {

src/Pages/ResourceBrowser/constants.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import { ReactComponent as ICCleanBrush } from '@Icons/ic-medium-clean-brush.svg'
1818
import { ReactComponent as ICMediumPause } from '@Icons/ic-medium-pause.svg'
1919
import { ReactComponent as ICMediumPlay } from '@Icons/ic-medium-play.svg'
20+
import { URLS } from '@Common/Constants'
2021
import { SelectPickerOptionType } from '@Shared/Components'
2122

2223
import { NodeDrainRequest } from './types'
@@ -114,3 +115,18 @@ export const NODE_DRAIN_OPTIONS_CHECKBOX_CONFIG: {
114115

115116
export const GVK_FILTER_KIND_QUERY_PARAM_KEY = 'gvkFilterKind'
116117
export const GVK_FILTER_API_VERSION_QUERY_PARAM_KEY = 'gvkFilterApiVersion'
118+
119+
export const DUMMY_RESOURCE_GVK_VERSION = 'v1'
120+
121+
export const RESOURCE_BROWSER_ROUTES = {
122+
OVERVIEW: `${URLS.RESOURCE_BROWSER}/:clusterId/overview`,
123+
MONITORING_DASHBOARD: `${URLS.RESOURCE_BROWSER}/:clusterId/monitoring-dashboard`,
124+
TERMINAL: `${URLS.RESOURCE_BROWSER}/:clusterId/terminal`,
125+
CLUSTER_UPGRADE: `${URLS.RESOURCE_BROWSER}/:clusterId/cluster-upgrade`,
126+
NODE_DETAIL: `${URLS.RESOURCE_BROWSER}/:clusterId/node/:name`,
127+
K8S_RESOURCE_DETAIL: `${URLS.RESOURCE_BROWSER}/:clusterId/:namespace/:kind/:group/:version/:name`,
128+
K8S_RESOURCE_LIST: `${URLS.RESOURCE_BROWSER}/:clusterId/:kind/:group/:version`,
129+
RESOURCE_RECOMMENDER: `${URLS.RESOURCE_BROWSER}/:clusterId/resource-recommender`,
130+
} as const
131+
132+
export const K8S_EMPTY_GROUP = 'k8sEmptyGroup'

src/Pages/ResourceBrowser/types.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,22 @@ export interface InstallationClusterConfigType
150150
status: InstallationClusterStatus
151151
correspondingClusterId: number | 0
152152
}
153+
154+
export enum NodeActionMenuOptionIdEnum {
155+
terminal = 'terminal',
156+
cordon = 'cordon',
157+
uncordon = 'uncordon',
158+
drain = 'drain',
159+
editTaints = 'edit-taints',
160+
editYaml = 'edit-yaml',
161+
delete = 'delete',
162+
}
163+
164+
export enum ResourceBrowserActionMenuEnum {
165+
manifest = 'manifest',
166+
events = 'events',
167+
logs = 'logs',
168+
terminal = 'terminal',
169+
delete = 'delete',
170+
vulnerability = 'vulnerability',
171+
}

src/Shared/Components/ActionMenu/useActionMenu.hook.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,10 @@ export const useActionMenu = <T extends string | number>({
7979
}
8080
}
8181

82-
const handleTriggerKeyDown: UsePopoverProps['onTriggerKeyDown'] = (e, openState, closePopover) => {
82+
const handleTriggerKeyDown: UsePopoverProps['onTriggerKeyDown'] = (e, openState) => {
8383
if (!openState && (e.key === 'Enter' || e.key === ' ')) {
8484
setFocusedIndex(0)
8585
}
86-
87-
handlePopoverKeyDown(e, openState, closePopover)
8886
}
8987

9088
// POPOVER HOOK

0 commit comments

Comments
 (0)