Skip to content

Commit e25e10d

Browse files
Merge branch 'kubecon-2025' into feat/refactor-material-view
2 parents e5f94b5 + 6aaa75a commit e25e10d

File tree

27 files changed

+604
-494
lines changed

27 files changed

+604
-494
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ FEATURE_GROUPED_APP_LIST_FILTERS_ENABLE=false
7676
FEATURE_FLUX_DEPLOYMENTS_ENABLE=false
7777
FEATURE_LINK_EXTERNAL_FLUX_ENABLE=false
7878
FEATURE_CANARY_ROLLOUT_PROGRESS_ENABLE=true
79+
COMMAND_BAR_REFETCH_INTERVAL=3600

config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@
5252
| LOGIN_PAGE_IMAGE | | Login page image url |
5353
| FEATURE_FLUX_DEPLOYMENTS_ENABLE | false | Enables flux cd deployment type for devtron apps and devtron charts |
5454
| FEATURE_LINK_EXTERNAL_FLUX_ENABLE | false | Enables external flux cd migration |
55-
55+
| COMMAND_BAR_REFETCH_INTERVAL | 3600 | Time interval in seconds to refetch command bar data - Applications List |
5656
# DASHBOARD CONFIG SECRET

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.20.0-pre-3",
7+
"@devtron-labs/devtron-fe-common-lib": "1.20.0-pre-5",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/Pages-Devtron-2.0/ApplicationManagement/Configurations/ConfigurationsRouter.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import { lazy } from 'react'
22
import { Redirect, Route, Switch } from 'react-router-dom'
33

4-
import { noop, PageHeader, SERVER_MODE, URLS as COMMON_URLS, useMainContext } from '@devtron-labs/devtron-fe-common-lib'
4+
import {
5+
noop,
6+
PageHeader,
7+
SERVER_MODE,
8+
SideNavigation,
9+
URLS as COMMON_URLS,
10+
useMainContext,
11+
} from '@devtron-labs/devtron-fe-common-lib'
512

613
import ChartRepo from '@Components/chartRepo/ChartRepo'
714
import { importComponentFromFELibrary } from '@Components/common'
15+
import { APPLICATION_MANAGEMENT_CONFIGURATIONS } from '@Components/Navigation'
816
import { AddNotification } from '@Components/notifications/AddNotification'
917
import { URLS } from '@Config/routes'
1018

@@ -35,11 +43,13 @@ export const Configurations = () => {
3543

3644
return (
3745
<>
38-
{/* TODO Rohit: Update with Application Management Header */}
46+
{/* TODO: Update with Application Management Header */}
3947
<PageHeader headerName="Application Management / Configurations" />
4048
<div className="application-management-configurations dc__grid flex-grow-1 dc__overflow-auto">
41-
<div className="border__primary--right">SidePanel</div>
42-
<div className="bg__secondary">
49+
<div className="py-12 pl-8 pr-7 border__primary--right">
50+
<SideNavigation list={APPLICATION_MANAGEMENT_CONFIGURATIONS} />
51+
</div>
52+
<div className="bg__secondary dc__overflow-auto">
4353
<Switch>
4454
{isFeatureGitOpsEnabled && (
4555
<Route
Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
11
import { useEffect } from 'react'
22

3-
import { useRegisterShortcut, UseRegisterShortcutProvider } from '@devtron-labs/devtron-fe-common-lib'
3+
import { useQuery } from '@devtron-labs/devtron-fe-common-lib'
4+
5+
import { getAppListMin } from '@Services/service'
46

57
import CommandBarBackdrop from './CommandBarBackdrop'
6-
import { SHORT_CUTS } from './constants'
78
import { CommandBarProps } from './types'
89

910
import './CommandBar.scss'
1011

1112
const CommandBar = ({ showCommandBar, setShowCommandBar }: CommandBarProps) => {
12-
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()
13-
14-
const handleOpen = () => {
15-
setShowCommandBar(true)
16-
}
13+
const { isLoading: isLoadingAppList, data: appList } = useQuery({
14+
queryKey: ['commandBar__app-list'],
15+
queryFn: () => getAppListMin(),
16+
refetchInterval: (+window._env_.COMMAND_BAR_REFETCH_INTERVAL || 3600) * 1000,
17+
select: ({ result }) => result,
18+
})
1719

1820
const handleClose = () => {
1921
setShowCommandBar(false)
2022
}
2123

2224
useEffect(() => {
23-
const { keys } = SHORT_CUTS.OPEN_COMMAND_BAR
24-
25-
registerShortcut({
26-
keys,
27-
description: SHORT_CUTS.OPEN_COMMAND_BAR.description,
28-
callback: handleOpen,
29-
})
30-
25+
const handleOpen = (e: KeyboardEvent) => {
26+
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
27+
e.preventDefault()
28+
setShowCommandBar(true)
29+
}
30+
}
31+
window.addEventListener('keydown', handleOpen)
3132
return () => {
32-
unregisterShortcut(keys)
33+
window.removeEventListener('keydown', handleOpen)
3334
}
3435
}, [])
3536

3637
if (!showCommandBar) {
3738
return null
3839
}
3940

40-
return (
41-
<UseRegisterShortcutProvider ignoreTags={[]}>
42-
<CommandBarBackdrop handleClose={handleClose} />
43-
</UseRegisterShortcutProvider>
44-
)
41+
return <CommandBarBackdrop handleClose={handleClose} appList={appList} isLoadingAppList={isLoadingAppList} />
4542
}
4643

4744
export default CommandBar

src/Pages/Shared/CommandBar/CommandBar.scss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414
&:hover {
1515
background: transparent !important;
1616
}
17+
18+
&__icon {
19+
height: 20px;
20+
width: 20px;
21+
22+
svg {
23+
height: inherit;
24+
width: inherit;
25+
}
26+
}
27+
28+
&__input {
29+
font-size: 16px;
30+
left: 8px;
31+
}
1732
}
1833
}
1934
}

src/Pages/Shared/CommandBar/CommandBarBackdrop.tsx

Lines changed: 82 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,46 @@ import { useHistory } from 'react-router-dom'
44
import {
55
API_STATUS_CODES,
66
Backdrop,
7-
GenericFilterEmptyState,
7+
GenericSectionErrorState,
88
getUserPreferences,
99
KeyboardShortcut,
1010
logExceptionToSentry,
11+
noop,
1112
ResponseType,
1213
SearchBar,
1314
stopPropagation,
1415
SupportedKeyboardKeysType,
1516
ToastManager,
1617
ToastVariantType,
1718
updateUserPreferences,
19+
useMainContext,
1820
useQuery,
1921
useRegisterShortcut,
2022
UserPreferencesType,
2123
} from '@devtron-labs/devtron-fe-common-lib'
2224

2325
import CommandGroup from './CommandGroup'
24-
import { NAVIGATION_GROUPS, RECENT_ACTIONS_GROUP, RECENT_NAVIGATION_ITEM_ID_PREFIX, SHORT_CUTS } from './constants'
26+
import { RECENT_ACTIONS_GROUP, RECENT_NAVIGATION_ITEM_ID_PREFIX, SHORT_CUTS } from './constants'
2527
import { CommandBarBackdropProps, CommandBarGroupType } from './types'
26-
import { getNewSelectedIndex, sanitizeItemId } from './utils'
27-
28-
const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
28+
import {
29+
getAdditionalNavGroups,
30+
getNavigationGroups,
31+
getNewSelectedIndex,
32+
parseAppListToNavItems,
33+
sanitizeItemId,
34+
} from './utils'
35+
36+
const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandBarBackdropProps) => {
2937
const history = useHistory()
3038
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()
3139

3240
const [searchText, setSearchText] = useState('')
3341
const [selectedItemIndex, setSelectedItemIndex] = useState(0)
3442

43+
const { serverMode, isSuperAdmin } = useMainContext()
44+
45+
const navigationGroups = useMemo(() => getNavigationGroups(serverMode, isSuperAdmin), [serverMode, isSuperAdmin])
46+
3547
const { data: recentActionsGroup, isLoading } = useQuery({
3648
queryFn: ({ signal }) =>
3749
getUserPreferences(signal).then((response) => {
@@ -45,14 +57,16 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
4557
queryKey: ['recentNavigationActions'],
4658
select: ({ result }) =>
4759
result.commandBar.recentNavigationActions.reduce<CommandBarGroupType>((acc, action) => {
48-
const requiredGroup = structuredClone(NAVIGATION_GROUPS).find((group) =>
49-
group.items.some((item) => item.id === action.id),
50-
)
60+
const allGroups = [...navigationGroups, ...parseAppListToNavItems(appList)]
61+
62+
const requiredGroup = allGroups.find((group) => group.items.some((item) => item.id === action.id))
5163

5264
if (requiredGroup) {
5365
const requiredItem = requiredGroup.items.find((item) => item.id === action.id)
54-
requiredItem.id = `${RECENT_NAVIGATION_ITEM_ID_PREFIX}${action.id}`
55-
acc.items.push(requiredItem)
66+
acc.items.push({
67+
...requiredItem,
68+
id: `${RECENT_NAVIGATION_ITEM_ID_PREFIX}${action.id}`,
69+
})
5670
}
5771
return acc
5872
}, structuredClone(RECENT_ACTIONS_GROUP)),
@@ -78,10 +92,11 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
7892
const lowerCaseSearchText = searchText.toLowerCase()
7993

8094
if (!searchText) {
81-
return NAVIGATION_GROUPS
95+
return navigationGroups
8296
}
8397

84-
return NAVIGATION_GROUPS.reduce<typeof NAVIGATION_GROUPS>((acc, group) => {
98+
const additionalGroups = getAdditionalNavGroups(searchText, appList)
99+
const parsedGroups = navigationGroups.reduce<typeof navigationGroups>((acc, group) => {
85100
const filteredItems = group.items.filter((item) => item.title.toLowerCase().includes(lowerCaseSearchText))
86101

87102
if (filteredItems.length > 0) {
@@ -93,31 +108,28 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
93108

94109
return acc
95110
}, [])
111+
112+
const combinedGroups = [...additionalGroups, ...parsedGroups]
113+
114+
return combinedGroups
96115
}, [searchText])
97116

117+
const showEmptyState = areFiltersApplied && !filteredGroups.length
118+
98119
const itemFlatList: CommandBarGroupType['items'] = useMemo(() => {
99120
if (areFiltersApplied) {
100121
return filteredGroups.flatMap((group) => group.items)
101122
}
102123

103124
return recentActionsGroup
104-
? [...recentActionsGroup.items, ...NAVIGATION_GROUPS.flatMap((group) => group.items)]
105-
: [...NAVIGATION_GROUPS.flatMap((group) => group.items)]
125+
? [...recentActionsGroup.items, ...navigationGroups.flatMap((group) => group.items)]
126+
: [...navigationGroups.flatMap((group) => group.items)]
106127
}, [areFiltersApplied, recentActionsGroup, filteredGroups])
107128

108129
const handleClearFilters = () => {
109130
setSearchText('')
110131
}
111132

112-
const handleEscape = () => {
113-
if (searchText) {
114-
handleClearFilters()
115-
return
116-
}
117-
118-
handleClose()
119-
}
120-
121133
const focusSearchBar = () => {
122134
if (searchBarRef.current) {
123135
searchBarRef.current.focus()
@@ -199,18 +211,27 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
199211
}, [isLoading, recentActionsGroup])
200212

201213
useEffect(() => {
202-
const { keys, description } = SHORT_CUTS.FOCUS_SEARCH_BAR
214+
const handleKeyDown = (e: KeyboardEvent) => {
215+
if (e.key === 'Escape') {
216+
e.stopPropagation()
217+
218+
if (searchText) {
219+
handleClearFilters()
220+
setTimeout(() => {
221+
focusSearchBar()
222+
}, 100)
223+
} else {
224+
handleClose()
225+
}
226+
}
227+
}
203228

204-
registerShortcut({
205-
keys,
206-
description,
207-
callback: focusSearchBar,
208-
})
229+
window.addEventListener('keydown', handleKeyDown)
209230

210231
return () => {
211-
unregisterShortcut(keys)
232+
window.removeEventListener('keydown', handleKeyDown)
212233
}
213-
}, [])
234+
}, [searchText])
214235

215236
useEffect(() => {
216237
const { keys, description } = SHORT_CUTS.ENTER_ITEM
@@ -283,13 +304,18 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
283304
)
284305

285306
return (
286-
<Backdrop onEscape={handleEscape} onClick={handleClose} deactivateFocusOnEscape={!!searchText}>
307+
<Backdrop
308+
onEscape={noop}
309+
onClick={handleClose}
310+
deactivateFocusOnEscape={!!searchText}
311+
returnFocusOnDeactivate={false}
312+
>
287313
<div
288314
onClick={stopPropagation}
289-
className="dc__mxw-800 mxh-450 flexbox-col dc__overflow-hidden dc__content-space br-12 bg__modal--primary command-bar__container w-100 h-100"
315+
className="dc__mxw-720 mxh-500 flexbox-col dc__overflow-hidden dc__content-space br-12 bg__modal--primary command-bar__container w-100 h-100"
290316
>
291-
<div className="flexbox-col dc__overflow-hidden">
292-
<div className="px-20 py-8">
317+
<div className="flexbox-col dc__overflow-hidden flex-grow-1">
318+
<div className="px-16 py-12">
293319
<SearchBar
294320
inputProps={{
295321
autoFocus: true,
@@ -299,14 +325,22 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
299325
initialSearchText={searchText}
300326
handleSearchChange={handleSearchChange}
301327
noBackgroundAndBorder
328+
shouldDebounce
329+
isLoading={isLoadingAppList}
302330
/>
303331
</div>
304332

305-
{areFiltersApplied && !filteredGroups.length ? (
306-
<GenericFilterEmptyState handleClearFilters={handleClearFilters} />
333+
{showEmptyState ? (
334+
<GenericSectionErrorState
335+
title="No results found"
336+
subTitle=""
337+
description=""
338+
useInfoIcon
339+
rootClassName="flex-grow-1"
340+
/>
307341
) : (
308342
<div
309-
className="flexbox-col dc__overflow-auto border__primary--top pt-8"
343+
className="flexbox-col dc__overflow-auto border__primary--top"
310344
role="listbox"
311345
aria-label="Command Menu"
312346
aria-activedescendant={itemFlatList[selectedItemIndex]?.id}
@@ -331,12 +365,17 @@ const CommandBarBackdrop = ({ handleClose }: CommandBarBackdropProps) => {
331365
</div>
332366

333367
<div className="flexbox dc__content-space dc__align-items-center px-20 py-12 border__primary--top bg__secondary">
334-
<div className="flexbox dc__gap-20 dc__align-items-center">
335-
{renderKeyboardShortcuts(['ArrowUp', 'ArrowDown'], 'to navigate')}
336-
{renderKeyboardShortcuts(['Enter'], 'to select')}
337-
{renderKeyboardShortcuts(['Escape'], 'to close')}
368+
<div
369+
className={`flexbox dc__gap-20 dc__align-items-center flex-grow-1 ${showEmptyState ? 'dc__content-center' : ''}`}
370+
>
371+
{!showEmptyState && (
372+
<>
373+
{renderKeyboardShortcuts(['ArrowUp', 'ArrowDown'], 'to navigate')}
374+
{renderKeyboardShortcuts(['Enter'], 'to select')}
375+
</>
376+
)}
377+
{renderKeyboardShortcuts(['Escape'], searchText ? 'to clear search' : 'to close')}
338378
</div>
339-
{renderKeyboardShortcuts(['>'], 'to search actions')}
340379
</div>
341380
</div>
342381
</Backdrop>

0 commit comments

Comments
 (0)