Skip to content

Commit ce65343

Browse files
authored
Merge pull request #3034 from devtron-labs/feat/app-list-table
feat: use Table in devtron, argo & flux listings
2 parents 4a450a6 + 0c539e0 commit ce65343

File tree

27 files changed

+747
-1044
lines changed

27 files changed

+747
-1044
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.22.0-alpha-11",
7+
"@devtron-labs/devtron-fe-common-lib": "1.22.0-alpha-12",
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/InfrastructureManagement/Overview/ClusterAndNodes/NodeViewGroupList.tsx

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from 'react'
1+
import { useCallback, useMemo } from 'react'
22
import { generatePath, Link, useHistory } from 'react-router-dom'
33

44
import {
@@ -237,46 +237,49 @@ const NodeViewGroupListWrapper = ({
237237

238238
const NodeViewGroupList = ({ nodeViewGroupType }: { nodeViewGroupType: NodeViewGroupType }) => {
239239
const { push } = useHistory()
240-
const getRows: TableProps<NodeViewGroupRowType, FiltersTypeEnum.URL, {}>['getRows'] = async (
241-
{
242-
searchKey,
243-
offset,
244-
pageSize,
245-
sortBy,
246-
sortOrder,
247-
errorType,
248-
autoscalerType,
249-
schedulableType,
250-
}: Record<NodeViewGroupListFiltersTypeEnum, string> & Parameters<TableProps['getRows']>[0],
251-
abortSignal,
252-
) => {
253-
const response = await getNodeViewGroupList({
254-
searchKey,
255-
groupBy: nodeViewGroupType,
256-
offset,
257-
pageSize,
258-
sortBy,
259-
sortOrder,
260-
...(nodeViewGroupType === NodeViewGroupType.NODE_ERRORS && errorType !== 'ALL'
261-
? { errorType: errorType as NodeErrorsKeys }
262-
: {}),
263-
...(nodeViewGroupType === NodeViewGroupType.AUTOSCALER_MANAGED && autoscalerType !== 'ALL'
264-
? { autoscalerType: autoscalerType as AutoscalerTypes }
265-
: {}),
266-
...(nodeViewGroupType === NodeViewGroupType.NODE_SCHEDULING && schedulableType !== 'ALL'
267-
? { schedulableType: schedulableType as NodeSchedulingKeys }
268-
: {}),
240+
const getRows: TableProps<NodeViewGroupRowType, FiltersTypeEnum.URL, {}>['getRows'] = useCallback(
241+
async (
242+
{
243+
searchKey,
244+
offset,
245+
pageSize,
246+
sortBy,
247+
sortOrder,
248+
errorType,
249+
autoscalerType,
250+
schedulableType,
251+
}: Record<NodeViewGroupListFiltersTypeEnum, string> & Parameters<TableProps['getRows']>[0],
269252
abortSignal,
270-
})
253+
) => {
254+
const response = await getNodeViewGroupList({
255+
searchKey,
256+
groupBy: nodeViewGroupType,
257+
offset,
258+
pageSize,
259+
sortBy,
260+
sortOrder,
261+
...(nodeViewGroupType === NodeViewGroupType.NODE_ERRORS && errorType !== 'ALL'
262+
? { errorType: errorType as NodeErrorsKeys }
263+
: {}),
264+
...(nodeViewGroupType === NodeViewGroupType.AUTOSCALER_MANAGED && autoscalerType !== 'ALL'
265+
? { autoscalerType: autoscalerType as AutoscalerTypes }
266+
: {}),
267+
...(nodeViewGroupType === NodeViewGroupType.NODE_SCHEDULING && schedulableType !== 'ALL'
268+
? { schedulableType: schedulableType as NodeSchedulingKeys }
269+
: {}),
270+
abortSignal,
271+
})
271272

272-
return {
273-
rows: (response.result?.nodeList || []).map((node) => ({
274-
id: `${node.nodeName}-${node.clusterName}`,
275-
data: node,
276-
})),
277-
totalRows: response.result?.totalCount || 0,
278-
}
279-
}
273+
return {
274+
rows: (response.result?.nodeList || []).map((node) => ({
275+
id: `${node.nodeName}-${node.clusterName}`,
276+
data: node,
277+
})),
278+
totalRows: response.result?.totalCount || 0,
279+
}
280+
},
281+
[],
282+
)
280283

281284
const clearFilters = () => {
282285
push({ search: '' })
@@ -311,7 +314,7 @@ const NodeViewGroupList = ({ nodeViewGroupType }: { nodeViewGroupType: NodeViewG
311314
}}
312315
paginationVariant={PaginationEnum.PAGINATED}
313316
filtersVariant={FiltersTypeEnum.URL}
314-
filter={() => true}
317+
filter={null}
315318
additionalFilterProps={{
316319
initialSortKey: 'nodeName',
317320
parseSearchParams: (searchParams) => ({

src/Pages/ChartStore/ChartDetails/ChartDetailsDeployments.tsx

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

17-
import { useMemo, useState } from 'react'
17+
import { useCallback, useMemo, useState } from 'react'
1818
import { useParams } from 'react-router-dom'
1919

2020
import {
@@ -80,8 +80,10 @@ export const ChartDetailsDeployments = ({ chartIcon }: ChartDetailsDeploymentsPr
8080
)
8181

8282
// HANDLERS
83-
const filter: DeploymentsTableProps['filter'] = (rowData, filterData) =>
84-
rowData.data.appName.includes(filterData.searchKey.toLowerCase())
83+
const filter: DeploymentsTableProps['filter'] = useCallback(
84+
(rowData, filterData) => rowData.data.appName.includes(filterData.searchKey.toLowerCase()),
85+
[],
86+
)
8587

8688
const handleCloseDeleteConfirmationModal = () => setIsOpenDeleteConfirmationModal(false)
8789

src/Pages/ChartStore/ChartDetails/ChartDetailsPresetValues.tsx

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

17-
import { useMemo, useState } from 'react'
17+
import { useCallback, useMemo, useState } from 'react'
1818
import { generatePath, useRouteMatch } from 'react-router-dom'
1919

2020
import {
@@ -104,8 +104,10 @@ export const ChartDetailsPresetValues = () => {
104104
setDeletePresetValue(null)
105105
}
106106

107-
const filter: PresetValuesTableProps['filter'] = (rowData, filterData) =>
108-
rowData.data.name.includes(filterData.searchKey.toLowerCase())
107+
const filter: PresetValuesTableProps['filter'] = useCallback(
108+
(rowData, filterData) => rowData.data.name.includes(filterData.searchKey.toLowerCase()),
109+
[],
110+
)
109111

110112
return (
111113
<div className="mh-500 flexbox-col bg__primary border__primary br-4 w-100 dc__overflow-auto">

src/Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ const ClusterList = () => {
333333
filtersVariant={FiltersTypeEnum.STATE}
334334
paginationVariant={PaginationEnum.NOT_PAGINATED}
335335
emptyStateConfig={null}
336-
filter={() => true}
336+
filter={null}
337337
additionalFilterProps={{
338338
initialSortKey: 'clusterName',
339339
}}

src/components/ResourceBrowser/ResourceList/ClusterUpgradeCompatibilityInfo.tsx

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

17-
import { useMemo } from 'react'
17+
import { useCallback, useMemo } from 'react'
1818
import { useHistory, useLocation, useParams } from 'react-router-dom'
1919

2020
import {
@@ -105,6 +105,20 @@ const ClusterUpgradeCompatibilityInfo = ({
105105
[resourceListForCurrentData],
106106
)
107107

108+
const tableFilter: ClusterUpgradeCompatibilityInfoTableProps['filter'] = useCallback((row, filterData) => {
109+
const lowercasedSearchKey = filterData.searchKey?.toLowerCase()
110+
return (
111+
!filterData.searchKey ||
112+
Object.entries(row.data).some(
113+
([key, value]) =>
114+
key !== 'id' &&
115+
value !== null &&
116+
value !== undefined &&
117+
String(value).toLowerCase().includes(lowercasedSearchKey),
118+
)
119+
)
120+
}, [])
121+
108122
if (isLoading) {
109123
return (
110124
<div className="flex column h-100">
@@ -144,16 +158,6 @@ const ClusterUpgradeCompatibilityInfo = ({
144158
)
145159
}
146160

147-
const tableFilter: ClusterUpgradeCompatibilityInfoTableProps['filter'] = (row, filterData) =>
148-
!filterData.searchKey ||
149-
Object.entries(row.data).some(
150-
([key, value]) =>
151-
key !== 'id' &&
152-
value !== null &&
153-
value !== undefined &&
154-
String(value).toLowerCase().includes(filterData.searchKey.toLowerCase()),
155-
)
156-
157161
const clearFilters = () => {
158162
const searchParams = new URLSearchParams(location.search)
159163
searchParams.delete(URL_FILTER_KEYS.SEARCH_KEY)

src/components/ResourceBrowser/ResourceList/K8SResourceList.tsx

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

17-
import { useEffect, useMemo, useRef } from 'react'
17+
import { useCallback, useEffect, useMemo, useRef } from 'react'
1818
import { useLocation, useParams } from 'react-router-dom'
1919

2020
import {
@@ -221,33 +221,38 @@ export const K8SResourceList = ({
221221
[resourceList?.data],
222222
)
223223

224-
const tableFilter: K8sResourceListTableProps['filter'] = (row, filterData) => {
225-
let nodeFilters = true
224+
const tableFilter: K8sResourceListTableProps['filter'] = useCallback(
225+
(row, filterData) => {
226+
let nodeFilters = true
226227

227-
if (isNodeListing) {
228-
nodeFilters = isItemASearchMatchForNodeListing(row.data, filterData)
229-
}
228+
if (isNodeListing) {
229+
nodeFilters = isItemASearchMatchForNodeListing(row.data, filterData)
230+
}
230231

231-
const isSearchMatch =
232-
!filterData.searchKey ||
233-
Object.entries(row.data).some(
234-
([key, value]) =>
235-
key !== 'id' &&
236-
(!isNodeListing || NODE_LIST_HEADER_KEYS_TO_SEARCH.includes(key)) &&
237-
value !== null &&
238-
value !== undefined &&
239-
String(value).toLowerCase().includes(filterData.searchKey.toLowerCase()),
240-
)
232+
const lowercasedSearchKey = filterData.searchKey?.toLowerCase()
241233

242-
if (isEventListing) {
243-
return (
244-
(row.data.type as string)?.toLowerCase() ===
245-
((filterData as unknown as K8sResourceListFilterType).eventType || 'warning') && isSearchMatch
246-
)
247-
}
234+
const isSearchMatch =
235+
!filterData.searchKey ||
236+
Object.entries(row.data).some(
237+
([key, value]) =>
238+
key !== 'id' &&
239+
(!isNodeListing || NODE_LIST_HEADER_KEYS_TO_SEARCH.includes(key)) &&
240+
value !== null &&
241+
value !== undefined &&
242+
String(value).toLowerCase().includes(lowercasedSearchKey),
243+
)
248244

249-
return isSearchMatch && nodeFilters
250-
}
245+
if (isEventListing) {
246+
return (
247+
(row.data.type as string)?.toLowerCase() ===
248+
((filterData as unknown as K8sResourceListFilterType).eventType || 'warning') && isSearchMatch
249+
)
250+
}
251+
252+
return isSearchMatch && nodeFilters
253+
},
254+
[isNodeListing, isEventListing],
255+
)
251256

252257
const getDefaultSortKey = () => {
253258
if (isEventListing) {

src/components/app/list-new/AppList.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import { getCommonAppFilters } from '@Services/service'
4949
import { Cluster } from '@Services/service.types'
5050

5151
import { SERVER_MODE, URLS } from '../../../config'
52-
import { useAppContext } from '../../common'
5352
import { getModuleInfo } from '../../v2/devtronStackManager/DevtronStackManager.service'
5453
import DevtronAppList from '../list/DevtronAppListContainer'
5554
import AppListFilters from './AppListFilters'
@@ -80,7 +79,6 @@ const AppList = ({ isDevtronAppList }: { isDevtronAppList?: boolean }) => {
8079
const { url } = useRouteMatch()
8180
const params = useParams<{ appType: InfrastructureManagementAppListType }>()
8281
const { serverMode, isSuperAdmin } = useMainContext()
83-
const { setCurrentAppName } = useAppContext()
8482

8583
const [lastDataSyncTimeString, setLastDataSyncTimeString] = useState<string>('')
8684
const [isDataSyncing, setDataSyncing] = useState(false)
@@ -409,7 +407,6 @@ const AppList = ({ isDevtronAppList }: { isDevtronAppList?: boolean }) => {
409407
appFiltersResponseLoading={appListFiltersLoading || namespaceListLoading}
410408
isArgoInstalled={isArgoInstalled}
411409
clearAllFilters={clearFilters}
412-
setCurrentAppName={setCurrentAppName}
413410
changePage={changePage}
414411
changePageSize={changePageSize}
415412
handleSorting={handleSorting}

src/components/app/list-new/AppListType.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { getCommonAppFilters } from '@Services/service'
2828
import { Cluster } from '@Services/service.types'
2929

3030
import { DevtronAppListProps } from '../list/types'
31+
import { APP_LIST_HEADERS } from './Constants'
3132

3233
export enum FluxCDTemplateType {
3334
KUSTOMIZATION = 'Kustomization',
@@ -243,3 +244,7 @@ export interface ExportAppListDataType {
243244
namespaceId: number | string
244245
lastDeployedTime: string
245246
}
247+
248+
export type GenericAppListRowType = {
249+
detail: GenericAppType
250+
} & Record<AppListSortableKeys | keyof typeof APP_LIST_HEADERS, string | GenericAppType>

src/components/app/list-new/Constants.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@
1616

1717
import { GroupBase } from 'react-select'
1818

19-
import {
20-
ExportToCsvProps,
21-
OptionType,
22-
SelectPickerOptionType,
23-
UseUrlFiltersProps,
24-
} from '@devtron-labs/devtron-fe-common-lib'
19+
import { ExportToCsvProps, SelectPickerOptionType, UseUrlFiltersProps } from '@devtron-labs/devtron-fe-common-lib'
2520

2621
import { AppStatuses, AppStatusesDTO, ExportAppListDataType, FluxCDTemplateType } from './AppListType'
2722

@@ -92,11 +87,6 @@ export const APP_STATUS_FILTER_OPTIONS: GroupBase<SelectPickerOptionType>[] = [
9287
},
9388
]
9489

95-
export const APPS_WITH_NO_PROJECT_OPTION: OptionType = {
96-
label: 'Apps with no project',
97-
value: '0',
98-
}
99-
10090
export const DEVTRON_APP_LIST_LOCAL_STORAGE_KEY: UseUrlFiltersProps<never, never>['localStorageKey'] =
10191
'devtron-app-list__filters'
10292
export const APP_LIST_LOCAL_STORAGE_KEY: UseUrlFiltersProps<never, never>['localStorageKey'] = 'app-list__filters'

0 commit comments

Comments
 (0)