Skip to content

Commit 7bc40d6

Browse files
committed
Merge branch 'kubecon-2025' of https://github.com/devtron-labs/dashboard into feat/application-management-overview
2 parents 6c39969 + a6ea722 commit 7bc40d6

Some content is hidden

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

42 files changed

+722
-366
lines changed

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.1-beta-1",
7+
"@devtron-labs/devtron-fe-common-lib": "1.20.1-pre-4",
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: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export const Configurations = () => {
5151
...getApplicationManagementBreadcrumb(),
5252
configurations: {
5353
component: <span className="cn-9 fs-16 fw-6 lh-24">Configurations</span>,
54-
linked: true,
5554
},
5655
},
5756
},

src/Pages/App/Details/ExternalFlux/ExternalFluxAppDetailsRoute.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ const ExternalFluxAppDetailsRoute = () => {
3232
title={AppListConstants.AppTabs.FLUX_APPS}
3333
redirectURL={`${URLS.APPLICATION_MANAGEMENT_APP}/${URLS.APP_LIST}/${AppListConstants.AppType.FLUX_APPS}`}
3434
showAppDetailsOnly
35+
breadCrumbConfig={{
36+
':namespace': null,
37+
'external-flux': null,
38+
':templateType': null,
39+
}}
3540
/>
3641
<Suspense fallback={<Progressing pageLoader />}>
3742
<Switch>

src/Pages/ChartStore/ChartDetails/ChartDetails.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ export const ChartDetails = () => {
8585
{
8686
alias: {
8787
...getApplicationManagementBreadcrumb(),
88+
discover: {
89+
component: 'Chart Store',
90+
linked: true,
91+
},
8892
':chartSegment?': null,
8993
':chartId': {
9094
component: (

src/Pages/Shared/CommandBar/CommandBar.component.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ import { useEffect } from 'react'
22

33
import { useQuery } from '@devtron-labs/devtron-fe-common-lib'
44

5-
import { getAppListMin } from '@Services/service'
6-
75
import CommandBarBackdrop from './CommandBarBackdrop'
8-
import { CommandBarProps } from './types'
6+
import { getCommandBarResourceLists } from './service'
7+
import { CommandBarBackdropProps, CommandBarProps } from './types'
98

109
import './CommandBar.scss'
1110

1211
const CommandBar = ({ showCommandBar, setShowCommandBar }: CommandBarProps) => {
13-
const { isLoading: isLoadingAppList, data: appList } = useQuery({
12+
const { isLoading: isResourceListLoading, data: resourceList } = useQuery<
13+
CommandBarBackdropProps['resourceList'],
14+
CommandBarBackdropProps['resourceList'],
15+
[string],
16+
false
17+
>({
1418
queryKey: ['commandBar__app-list'],
15-
queryFn: () => getAppListMin(),
19+
queryFn: () => getCommandBarResourceLists(),
1620
refetchInterval: (+window._env_.COMMAND_BAR_REFETCH_INTERVAL || 3600) * 1000,
17-
select: ({ result }) => result,
1821
})
1922

2023
const handleClose = () => {
@@ -38,7 +41,13 @@ const CommandBar = ({ showCommandBar, setShowCommandBar }: CommandBarProps) => {
3841
return null
3942
}
4043

41-
return <CommandBarBackdrop handleClose={handleClose} appList={appList} isLoadingAppList={isLoadingAppList} />
44+
return (
45+
<CommandBarBackdrop
46+
handleClose={handleClose}
47+
resourceList={resourceList}
48+
isLoadingResourceList={isResourceListLoading}
49+
/>
50+
)
4251
}
4352

4453
export default CommandBar

src/Pages/Shared/CommandBar/CommandBarBackdrop.tsx

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useMemo, useRef, useState } from 'react'
1+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
22
import { useHistory } from 'react-router-dom'
33

44
import {
@@ -30,10 +30,13 @@ import {
3030
getNavigationGroups,
3131
getNewSelectedIndex,
3232
parseAppListToNavItems,
33+
parseChartListToNavItems,
34+
parseClusterListToNavItems,
35+
parseHelmAppListToNavItems,
3336
sanitizeItemId,
3437
} from './utils'
3538

36-
const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandBarBackdropProps) => {
39+
const CommandBarBackdrop = ({ handleClose, isLoadingResourceList, resourceList }: CommandBarBackdropProps) => {
3740
const history = useHistory()
3841
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()
3942

@@ -44,20 +47,16 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
4447

4548
const navigationGroups = useMemo(() => getNavigationGroups(serverMode, isSuperAdmin), [serverMode, isSuperAdmin])
4649

47-
const { data: recentActionsGroup, isLoading } = useQuery({
48-
queryFn: ({ signal }) =>
49-
getUserPreferences(signal).then((response) => {
50-
const responseData: ResponseType<typeof response> = {
51-
code: API_STATUS_CODES.OK,
52-
status: 'OK',
53-
result: response,
54-
}
55-
return responseData
56-
}),
57-
queryKey: ['recentNavigationActions'],
58-
select: ({ result }) =>
50+
const parseRecentActionsGroup = useCallback(
51+
({ result }: ResponseType<Awaited<ReturnType<typeof getUserPreferences>>>) =>
5952
result.commandBar.recentNavigationActions.reduce<CommandBarGroupType>((acc, action) => {
60-
const allGroups = [...navigationGroups, ...parseAppListToNavItems(appList)]
53+
const allGroups = [
54+
...navigationGroups,
55+
...parseAppListToNavItems(resourceList?.appList),
56+
...parseHelmAppListToNavItems(resourceList?.helmAppList),
57+
...parseChartListToNavItems(resourceList?.chartList),
58+
...parseClusterListToNavItems(resourceList?.clusterList),
59+
]
6160

6261
const requiredGroup = allGroups.find((group) => group.items.some((item) => item.id === action.id))
6362

@@ -70,6 +69,22 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
7069
}
7170
return acc
7271
}, structuredClone(RECENT_ACTIONS_GROUP)),
72+
[resourceList],
73+
)
74+
75+
const { data: recentActionsGroup, isLoading } = useQuery({
76+
queryFn: ({ signal }) =>
77+
getUserPreferences(signal).then((response) => {
78+
const responseData: ResponseType<typeof response> = {
79+
code: API_STATUS_CODES.OK,
80+
status: 'OK',
81+
result: response,
82+
}
83+
return responseData
84+
}),
85+
queryKey: ['recentNavigationActions', isLoadingResourceList],
86+
enabled: !isLoadingResourceList,
87+
select: parseRecentActionsGroup,
7388
})
7489

7590
const areFiltersApplied = !!searchText
@@ -95,7 +110,7 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
95110
return navigationGroups
96111
}
97112

98-
const additionalGroups = getAdditionalNavGroups(searchText, appList)
113+
const additionalGroups = getAdditionalNavGroups(searchText, resourceList)
99114
const parsedGroups = navigationGroups.reduce<typeof navigationGroups>((acc, group) => {
100115
const filteredItems = group.items.filter(
101116
(item) =>
@@ -150,25 +165,17 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
150165
const item = itemFlatList[newIndex]
151166
const itemElement = itemRefMap.current[item.id]
152167
if (itemElement) {
153-
itemElement.scrollIntoView({ block: 'nearest', inline: 'nearest' })
168+
itemElement.scrollIntoView({ block: 'center', inline: 'nearest' })
154169
}
155170
return newIndex
156171
})
157172
}
158173

159-
const onItemClick = async (item: CommandBarGroupType['items'][number]) => {
160-
if (!item.href) {
161-
logExceptionToSentry(new Error(`CommandBar item with id ${item.id} does not have a valid href`))
162-
ToastManager.showToast({
163-
variant: ToastVariantType.error,
164-
description: `CommandBar item with id ${item.id} does not have a valid href`,
165-
})
174+
const pushItemToRecent = async (item: CommandBarGroupType['items'][number]) => {
175+
if (item.excludeFromRecent) {
166176
return
167177
}
168178

169-
history.push(item.href)
170-
handleClose()
171-
172179
const currentItemId = sanitizeItemId(item)
173180

174181
// In this now we will put the id as first item in the list and keep first 5 items then
@@ -190,6 +197,22 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
190197
})
191198
}
192199

200+
const onItemClick = async (item: CommandBarGroupType['items'][number]) => {
201+
if (!item.href) {
202+
logExceptionToSentry(new Error(`CommandBar item with id ${item.id} does not have a valid href`))
203+
ToastManager.showToast({
204+
variant: ToastVariantType.error,
205+
description: `CommandBar item with id ${item.id} does not have a valid href`,
206+
})
207+
return
208+
}
209+
210+
history.push(item.href)
211+
handleClose()
212+
213+
await pushItemToRecent(item)
214+
}
215+
193216
const handleEnterSelectedItem = async () => {
194217
const selectedItem = itemFlatList[selectedItemIndex]
195218

@@ -330,7 +353,7 @@ const CommandBarBackdrop = ({ handleClose, isLoadingAppList, appList }: CommandB
330353
handleSearchChange={handleSearchChange}
331354
noBackgroundAndBorder
332355
shouldDebounce
333-
isLoading={isLoadingAppList}
356+
isLoading={isLoadingResourceList}
334357
/>
335358
</div>
336359

src/Pages/Shared/CommandBar/CommandGroup.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const CommandGroup = ({
3838

3939
return (
4040
<div
41-
className={`flexbox px-16 py-12 cursor dc__align-items-center dc__gap-12 dc__content-space br-8 bg__hover ${getIsItemSelected(index) ? 'command-bar__container--selected-item' : ''}`}
41+
className={`flexbox px-16 ${item.subText ? 'py-8' : 'py-12'} cursor dc__align-items-center dc__gap-12 dc__content-space br-8 bg__hover ${getIsItemSelected(index) ? 'command-bar__container--selected-item' : ''}`}
4242
role="option"
4343
id={item.id}
4444
aria-selected={getIsItemSelected(index)}
@@ -47,12 +47,19 @@ const CommandGroup = ({
4747
tabIndex={0}
4848
>
4949
<div className="flexbox dc__align-items-center dc__gap-12">
50-
<Icon
51-
name={item.icon}
52-
size={20}
53-
color={iconColorWithFallback === 'none' ? null : iconColorWithFallback}
54-
/>
55-
<h3 className="m-0 cn-9 fs-14 fw-4 lh-20 dc__truncate">{item.title}</h3>
50+
{item.iconElement ? (
51+
item.iconElement
52+
) : (
53+
<Icon
54+
name={item.icon}
55+
size={20}
56+
color={iconColorWithFallback === 'none' ? null : iconColorWithFallback}
57+
/>
58+
)}
59+
<div className="flexbox-col">
60+
<h3 className="m-0 cn-9 fs-14 fw-4 lh-20 dc__truncate">{item.title}</h3>
61+
{item.subText && <p className="m-0 cn-7 fs-13 fw-4 lh-20 dc__truncate">{item.subText}</p>}
62+
</div>
5663
</div>
5764

5865
{getIsItemSelected(index) && <Icon name="ic-key-enter" color="N700" size={20} />}

src/Pages/Shared/CommandBar/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export const RECENT_ACTIONS_GROUP: CommandBarGroupType = {
1010

1111
export const RECENT_NAVIGATION_ITEM_ID_PREFIX = 'recent-navigation-' as const
1212
export const DEVTRON_APPLICATIONS_COMMAND_GROUP_ID = 'devtron-applications-command-group' as const
13+
export const CHART_LIST_COMMAND_GROUP_ID = 'chart-list-command-group' as const
14+
export const CLUSTER_LIST_COMMAND_GROUP_ID = 'cluster-list-command-group' as const
15+
export const HELM_APP_LIST_COMMAND_GROUP_ID = 'helm-app-list-command-group' as const
1316

1417
export const SHORT_CUTS: Record<
1518
'NAVIGATE_UP' | 'NAVIGATE_DOWN' | 'ENTER_ITEM',
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { getClusterOptions } from '@devtron-labs/devtron-fe-common-lib'
2+
3+
import { getDevtronInstalledHelmApps } from '@Components/app/list-new/AppListService'
4+
import { getAppListMin, getAvailableCharts } from '@Services/service'
5+
6+
import { CommandBarResourceListType } from './types'
7+
8+
export const getCommandBarResourceLists = async (): Promise<CommandBarResourceListType> => {
9+
const promiseResponse = await Promise.allSettled([
10+
getAppListMin(),
11+
getAvailableCharts(),
12+
getClusterOptions(),
13+
getDevtronInstalledHelmApps(null, null),
14+
])
15+
16+
const appList = promiseResponse[0].status === 'fulfilled' ? promiseResponse[0].value.result : []
17+
const chartList = promiseResponse[1].status === 'fulfilled' ? promiseResponse[1].value.result : []
18+
const clusterList = promiseResponse[2].status === 'fulfilled' ? promiseResponse[2].value : []
19+
const helmAppList = promiseResponse[3].status === 'fulfilled' ? promiseResponse[3].value.result.helmApps : []
20+
21+
return { appList, chartList, clusterList: (clusterList || []).filter((cluster) => !cluster.isVirtual), helmAppList }
22+
}

src/Pages/Shared/CommandBar/types.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Dispatch, SetStateAction } from 'react'
22

3-
import { IconBaseColorType, IconsProps, UserPreferencesType } from '@devtron-labs/devtron-fe-common-lib'
3+
import { ClusterType, IconBaseColorType, IconsProps, UserPreferencesType } from '@devtron-labs/devtron-fe-common-lib'
44

5+
import { HelmApp } from '@Components/app/list-new/AppListType'
6+
import { Chart } from '@Components/charts/charts.types'
57
import { NavigationItemType } from '@Components/Navigation/types'
68
import { AppListMinDTO } from '@Services/service.types'
79

@@ -12,10 +14,13 @@ export type CommandBarActionIdType = UserPreferencesType['commandBar']['recentNa
1214
export type CommandBarItemType = {
1315
id: CommandBarActionIdType | `${typeof RECENT_NAVIGATION_ITEM_ID_PREFIX}${CommandBarActionIdType}`
1416
title: string
15-
icon: IconsProps['name']
1617
keywords: string[]
1718
href: NavigationItemType['href']
18-
iconColor?: IconBaseColorType | 'none'
19+
/**
20+
* @default false
21+
*/
22+
excludeFromRecent?: boolean
23+
subText?: string
1924
} & (
2025
| {
2126
onSelect?: never
@@ -24,7 +29,19 @@ export type CommandBarItemType = {
2429
href?: never
2530
onSelect: (e: React.MouseEvent<HTMLButtonElement>) => void
2631
}
27-
)
32+
) &
33+
(
34+
| {
35+
icon: IconsProps['name']
36+
iconColor?: IconBaseColorType | 'none'
37+
iconElement?: never
38+
}
39+
| {
40+
iconElement: JSX.Element
41+
icon?: never
42+
iconColor?: never
43+
}
44+
)
2845

2946
export interface CommandBarGroupType {
3047
/**
@@ -43,9 +60,16 @@ export interface CommandGroupProps extends CommandBarGroupType {
4360
onItemClick: (item: CommandBarItemType) => void
4461
}
4562

46-
export interface CommandBarBackdropProps {
47-
isLoadingAppList: boolean
63+
export interface CommandBarResourceListType {
4864
appList: AppListMinDTO[]
65+
chartList: Chart[]
66+
clusterList: ClusterType[]
67+
helmAppList: HelmApp[]
68+
}
69+
70+
export interface CommandBarBackdropProps {
71+
isLoadingResourceList: boolean
72+
resourceList: CommandBarResourceListType
4973
handleClose: () => void
5074
}
5175

0 commit comments

Comments
 (0)