@@ -20,11 +20,11 @@ import ReactGA from 'react-ga4'
20
20
import {
21
21
AppListConstants ,
22
22
ComponentSizeType ,
23
- FilterSelectPicker ,
23
+ GroupedFilterSelectPicker ,
24
+ GroupedFilterSelectPickerProps ,
24
25
SearchBar ,
25
26
SelectPickerOptionType ,
26
27
SERVER_MODE ,
27
- Tooltip ,
28
28
useGetUserRoles ,
29
29
} from '@devtron-labs/devtron-fe-common-lib'
30
30
@@ -33,8 +33,8 @@ import ExportToCsv from '@Components/common/ExportToCsv/ExportToCsv'
33
33
34
34
import { getDevtronAppListDataToExport } from './AppListService'
35
35
import { AppListFiltersProps , AppListUrlFilters , AppStatuses } from './AppListType'
36
- import { APP_STATUS_FILTER_OPTIONS , SELECT_CLUSTER_TIPPY , TEMPLATE_TYPE_FILTER_OPTIONS } from './Constants'
37
- import { getAppTabNameFromAppType , useFilterOptions } from './list.utils'
36
+ import { APP_STATUS_FILTER_OPTIONS , TEMPLATE_TYPE_FILTER_OPTIONS } from './Constants'
37
+ import { getAppListFilters , getAppTabNameFromAppType , useFilterOptions } from './list.utils'
38
38
39
39
const AppListFilters = ( {
40
40
filterConfig,
@@ -44,7 +44,8 @@ const AppListFilters = ({
44
44
isExternalArgo,
45
45
isExternalFlux,
46
46
appListFiltersResponse,
47
- showPulsatingDot,
47
+ // TODO: need to handle this
48
+ // showPulsatingDot,
48
49
appListFiltersError,
49
50
reloadAppListFilters,
50
51
serverMode,
@@ -122,7 +123,7 @@ const AppListFilters = ({
122
123
}
123
124
} , [ filterConfig ] )
124
125
125
- const appStatusFilters : SelectPickerOptionType [ ] = structuredClone ( APP_STATUS_FILTER_OPTIONS )
126
+ const appStatusFilters : typeof APP_STATUS_FILTER_OPTIONS = structuredClone ( APP_STATUS_FILTER_OPTIONS )
126
127
127
128
const showExportCsvButton =
128
129
isSuperAdmin && appType === AppListConstants . AppType . DEVTRON_APPS && serverMode !== SERVER_MODE . EA_ONLY
@@ -132,153 +133,123 @@ const AppListFilters = ({
132
133
updateSearchParams ( { [ filterKey ] : selectedOptions . map ( ( option ) => String ( option . value ) ) } )
133
134
}
134
135
136
+ const appListFiltersSelectPickerMap : GroupedFilterSelectPickerProps < AppListUrlFilters > [ 'filterSelectPickerPropsMap' ] =
137
+ {
138
+ [ AppListUrlFilters . appStatus ] : {
139
+ placeholder : 'App Status' ,
140
+ inputId : 'app-list-app-status-select' ,
141
+ options : appStatusFilters ,
142
+ appliedFilterOptions : selectedAppStatus ,
143
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . appStatus ) ,
144
+ isDisabled : false ,
145
+ isLoading : false ,
146
+ isOptionDisabled : getIsAppStatusDisabled ,
147
+ } ,
148
+ [ AppListUrlFilters . project ] : {
149
+ placeholder : 'Project' ,
150
+ inputId : 'app-list-project-select' ,
151
+ options : projectOptions ,
152
+ appliedFilterOptions : selectedProjects ,
153
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . project ) ,
154
+ isDisabled : appListFiltersLoading ,
155
+ isLoading : appListFiltersLoading ,
156
+ optionListError : appListFiltersError ,
157
+ reloadOptionList : reloadAppListFilters ,
158
+ } ,
159
+ [ AppListUrlFilters . environment ] : {
160
+ placeholder : 'Environment' ,
161
+ inputId : 'app-list-environment-select' ,
162
+ options : environmentOptions ,
163
+ appliedFilterOptions : selectedEnvironments ,
164
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . environment ) ,
165
+ isDisabled : appListFiltersLoading || ! ! clusterIdsCsv ,
166
+ isLoading : appListFiltersLoading ,
167
+ optionListError : appListFiltersError ,
168
+ reloadOptionList : reloadAppListFilters ,
169
+ } ,
170
+ [ AppListUrlFilters . templateType ] : {
171
+ placeholder : 'Template Type' ,
172
+ inputId : 'app-list-template-type-filter' ,
173
+ options : TEMPLATE_TYPE_FILTER_OPTIONS ,
174
+ appliedFilterOptions : selectedTemplateTypes ,
175
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . templateType ) ,
176
+ isDisabled : ! clusterIdsCsv ,
177
+ isLoading : false ,
178
+ } ,
179
+ [ AppListUrlFilters . cluster ] : {
180
+ placeholder : 'Cluster' ,
181
+ inputId : 'app-list-cluster-filter' ,
182
+ options : clusterOptions ,
183
+ appliedFilterOptions : selectedClusters ,
184
+ isDisabled : ! ( isExternalArgo || isExternalFlux ) && ! ! selectedEnvironments . length ,
185
+ isLoading : appListFiltersLoading ,
186
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . cluster ) ,
187
+ optionListError : appListFiltersError ,
188
+ reloadOptionList : reloadAppListFilters ,
189
+ isOptionDisabled : getIsClusterOptionDisabled ,
190
+ } ,
191
+ [ AppListUrlFilters . namespace ] : {
192
+ placeholder : 'Namespace' ,
193
+ inputId : 'app-list-namespace-filter' ,
194
+ options : namespaceOptions ,
195
+ appliedFilterOptions : selectedNamespaces ,
196
+ isDisabled : appListFiltersLoading || ! clusterIdsCsv ,
197
+ isLoading : appListFiltersLoading ,
198
+ handleApplyFilter : handleUpdateFilters ( AppListUrlFilters . namespace ) ,
199
+ shouldMenuAlignRight : ! showExportCsvButton ,
200
+ optionListError : appListFiltersError ,
201
+ reloadOptionList : reloadAppListFilters ,
202
+ } ,
203
+ }
204
+
135
205
return (
136
206
< div className = "search-filter-section" >
137
- < SearchBar
138
- containerClassName = "w-250"
139
- dataTestId = "search-by-app-name"
140
- initialSearchText = { searchKey }
141
- inputProps = { {
142
- placeholder : `${
143
- appType === AppListConstants . AppType . HELM_APPS
144
- ? 'Search by app or chart name'
145
- : 'Search by app name'
146
- } `,
147
- } }
148
- handleEnter = { handleSearch }
149
- size = { ComponentSizeType . medium }
150
- />
151
- < div className = "flexbox dc__gap-8 dc__align-items-center" >
152
- { ! ( isExternalArgo || isExternalFlux ) && (
153
- < >
154
- { isArgoInstalled && (
155
- < >
156
- < FilterSelectPicker
157
- placeholder = "App Status"
158
- inputId = "app-list-app-status-select"
159
- options = { appStatusFilters }
160
- appliedFilterOptions = { selectedAppStatus }
161
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . appStatus ) }
162
- isDisabled = { false }
163
- isLoading = { false }
164
- isOptionDisabled = { getIsAppStatusDisabled }
165
- />
166
- < div className = "dc__border-right h-16" />
167
- </ >
168
- ) }
169
- < FilterSelectPicker
170
- placeholder = "Project"
171
- inputId = "app-list-project-select"
172
- options = { projectOptions }
173
- appliedFilterOptions = { selectedProjects }
174
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . project ) }
175
- isDisabled = { appListFiltersLoading }
176
- isLoading = { appListFiltersLoading }
177
- optionListError = { appListFiltersError }
178
- reloadOptionList = { reloadAppListFilters }
179
- />
180
- < div className = "dc__border-right h-16" />
181
- { serverMode === SERVER_MODE . FULL && (
182
- < >
183
- < Tooltip
184
- content = "Remove cluster filters to use environment filter"
185
- alwaysShowTippyOnHover = { ! ! clusterIdsCsv }
186
- wordBreak = { false }
187
- >
188
- < div >
189
- < FilterSelectPicker
190
- placeholder = "Environment"
191
- inputId = "app-list-environment-select"
192
- options = { environmentOptions }
193
- appliedFilterOptions = { selectedEnvironments }
194
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . environment ) }
195
- isDisabled = { appListFiltersLoading || ! ! clusterIdsCsv }
196
- isLoading = { appListFiltersLoading }
197
- optionListError = { appListFiltersError }
198
- reloadOptionList = { reloadAppListFilters }
199
- />
200
- </ div >
201
- </ Tooltip >
202
- < div className = "dc__border-right h-16" />
203
- </ >
204
- ) }
205
- </ >
206
- ) }
207
- { isExternalFlux && (
208
- < >
209
- < Tooltip content = { SELECT_CLUSTER_TIPPY } alwaysShowTippyOnHover = { ! clusterIdsCsv } >
210
- < div >
211
- < FilterSelectPicker
212
- placeholder = "Template Type"
213
- inputId = "app-list-template-type-filter"
214
- options = { TEMPLATE_TYPE_FILTER_OPTIONS }
215
- appliedFilterOptions = { selectedTemplateTypes }
216
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . templateType ) }
217
- isDisabled = { ! clusterIdsCsv }
218
- isLoading = { false }
219
- />
220
- </ div >
221
- </ Tooltip >
222
- < div className = "dc__border-right h-16" />
223
- </ >
224
- ) }
225
- < Tooltip
226
- content = "Remove environment filters to use cluster filter"
227
- alwaysShowTippyOnHover = { ! ( isExternalArgo || isExternalFlux ) && ! ! selectedEnvironments . length }
228
- wordBreak = { false }
229
- >
230
- < div className = "flexbox dc__position-rel" >
231
- < FilterSelectPicker
232
- placeholder = "Cluster"
233
- inputId = "app-list-cluster-filter"
234
- options = { clusterOptions }
235
- appliedFilterOptions = { selectedClusters }
236
- isDisabled = { ! ( isExternalArgo || isExternalFlux ) && ! ! selectedEnvironments . length }
237
- isLoading = { appListFiltersLoading }
238
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . cluster ) }
239
- optionListError = { appListFiltersError }
240
- reloadOptionList = { reloadAppListFilters }
241
- isOptionDisabled = { getIsClusterOptionDisabled }
242
- />
243
- { showPulsatingDot && < div className = "dc__pulsating-dot dc__position-abs" /> }
244
- </ div >
245
- </ Tooltip >
246
- < Tooltip content = { SELECT_CLUSTER_TIPPY } alwaysShowTippyOnHover = { ! clusterIdsCsv } >
247
- < div >
248
- < FilterSelectPicker
249
- placeholder = "Namespace"
250
- inputId = "app-list-namespace-filter"
251
- options = { namespaceOptions }
252
- appliedFilterOptions = { selectedNamespaces }
253
- isDisabled = { appListFiltersLoading || ! clusterIdsCsv }
254
- isLoading = { appListFiltersLoading }
255
- handleApplyFilter = { handleUpdateFilters ( AppListUrlFilters . namespace ) }
256
- shouldMenuAlignRight = { ! showExportCsvButton }
257
- optionListError = { appListFiltersError }
258
- reloadOptionList = { reloadAppListFilters }
259
- />
260
- </ div >
261
- </ Tooltip >
262
- { showExportCsvButton && (
263
- < >
264
- < div className = "dc__border-right h-16" />
265
- < ExportToCsv
266
- apiPromise = { ( ) =>
267
- getDevtronAppListDataToExport (
268
- filterConfig ,
269
- appListFiltersResponse ?. appListFilters . result . environments ,
270
- namespaceListResponse ?. result ,
271
- appListFiltersResponse ?. appListFilters . result . clusters ,
272
- appListFiltersResponse ?. appListFilters . result . teams ,
273
- appCount ,
274
- )
275
- }
276
- fileName = { FILE_NAMES . Apps }
277
- disabled = { ! appCount }
278
- />
279
- </ >
280
- ) }
207
+ < div className = "flex left dc__gap-8" >
208
+ < SearchBar
209
+ containerClassName = "w-250"
210
+ dataTestId = "search-by-app-name"
211
+ initialSearchText = { searchKey }
212
+ inputProps = { {
213
+ placeholder : `${
214
+ appType === AppListConstants . AppType . HELM_APPS
215
+ ? 'Search by app or chart name'
216
+ : 'Search by app name'
217
+ } `,
218
+ } }
219
+ handleEnter = { handleSearch }
220
+ size = { ComponentSizeType . medium }
221
+ />
222
+ < GroupedFilterSelectPicker < AppListUrlFilters >
223
+ id = "app-list-filters"
224
+ isFilterApplied = { ! ! ( selectedAppStatus . length || selectedProjects . length ) }
225
+ options = { getAppListFilters ( {
226
+ clusterIdsCsv,
227
+ isExternalArgo,
228
+ isExternalFlux,
229
+ isArgoInstalled,
230
+ serverMode,
231
+ selectedEnvironments,
232
+ } ) }
233
+ filterSelectPickerPropsMap = { appListFiltersSelectPickerMap }
234
+ />
281
235
</ div >
236
+
237
+ { showExportCsvButton && (
238
+ < ExportToCsv
239
+ apiPromise = { ( ) =>
240
+ getDevtronAppListDataToExport (
241
+ filterConfig ,
242
+ appListFiltersResponse ?. appListFilters . result . environments ,
243
+ namespaceListResponse ?. result ,
244
+ appListFiltersResponse ?. appListFilters . result . clusters ,
245
+ appListFiltersResponse ?. appListFilters . result . teams ,
246
+ appCount ,
247
+ )
248
+ }
249
+ fileName = { FILE_NAMES . Apps }
250
+ disabled = { ! appCount }
251
+ />
252
+ ) }
282
253
</ div >
283
254
)
284
255
}
0 commit comments