11import * as React from 'react' ;
22import {
3+ Alert , AlertActionCloseButton ,
34 Button ,
45 Label ,
56 LabelGroup ,
89 Toolbar ,
910 ToolbarContent ,
1011 ToolbarGroup ,
11- ToolbarItem
12+ ToolbarItem ,
1213} from '@patternfly/react-core' ;
1314import { AddEditView , BaseDropdown , DateRangePicker , MultiChoiceDropdown } from '@app/Components' ;
1415import { FilterComponentProps , FilterOption , FilterOptionWithId , FilterProps , RequestFilter } from '@app/Types' ;
@@ -32,6 +33,7 @@ import {
3233} from '@app/Store/commonSelectors' ;
3334import { useRef } from 'react' ;
3435import { useAuthStore } from '@app/Store/authStore' ;
36+ import { ExclamationCircleIcon } from '@patternfly/react-icons' ;
3537
3638export const Filters : React . FunctionComponent < FilterComponentProps > = ( props : FilterComponentProps ) => {
3739 const filterOptionsList = useFilterStore ( ( state ) => state . filterOptions ) ;
@@ -44,6 +46,7 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
4446 const filterChoicesDataByOption = useFilterChoicesDataById ( ) ;
4547 const fetchOneFilterOption = fetchOneOption ( ) ;
4648 const fetchNextPageData = useFetchNextPage ( ) ;
49+ const [ errors , setErrors ] = React . useState < string [ ] > ( [ ] ) ;
4750 const [ filterSelection , selectFilter ] = React . useState < FilterProps > ( {
4851 organization : [ ] ,
4952 job_template : [ ] ,
@@ -68,11 +71,17 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
6871 await fetchTemplateOptions ( ) ;
6972 await Promise . all ( filterOptionsList . map ( async ( option ) => {
7073 if ( fetchFilterOptionsData [ option . key ] ) {
71- await fetchFilterOptionsData [ option . key ] ( ) ;
74+ try {
75+ await fetchFilterOptionsData [ option . key ] ( ) ;
76+ } catch ( e ) {
77+ setErrors ( ( errors ) => [ ...errors , ( e as { message ?: string } ) ?. message ?? 'Something went wrong. Please try again later.' ] ) ;
78+ }
7279 }
7380 } ) ) ;
7481 } ;
7582
83+ const dateChoices = useFilterStore ( ( state ) => state . dateRangeOptions ) ;
84+
7685 React . useEffect ( ( ) => {
7786 const execute = async ( ) => {
7887 await fetchFilters ( ) ;
@@ -133,13 +142,21 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
133142 } ;
134143
135144 const clearFilters = ( ) => {
136- selectFilter ( ( prevState ) => ( {
137- ...prevState ,
138- [ 'organization' ] : [ ] ,
139- [ 'job_template' ] : [ ] ,
140- [ 'project' ] : [ ] ,
141- [ 'label' ] : [ ]
142- } ) ) ;
145+ let range : string | null = null ;
146+ if ( dateChoices ?. length ) {
147+ const index = dateChoices . findIndex ( ( v ) => v . key === 'month_to_date' ) ;
148+ range = ( index > - 1 ? dateChoices [ index ] . key : dateChoices [ 0 ] . key ) . toString ( ) ;
149+ }
150+ const filters = {
151+ organization : [ ] ,
152+ job_template : [ ] ,
153+ label : [ ] ,
154+ project : [ ] ,
155+ date_range : range ,
156+ start_date : undefined ,
157+ end_date : undefined
158+ } as FilterProps ;
159+ selectFilter ( ( ) => filters ) ;
143160 setView ( null ) ;
144161 } ;
145162
@@ -153,14 +170,18 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
153170 const viewOptions = { } ;
154171 await Promise . all ( filterOptions . map ( async ( option ) => {
155172 viewOptions [ option ] = [ ] ;
156- if ( view . filters ?. [ option ] ?. length ) {
157- await Promise . all ( view . filters [ option ] . map ( async ( key : number ) => {
173+ if ( view . filters ?. [ option ] ?. length ) {
174+ await Promise . all ( view . filters [ option ] . map ( async ( key : number ) => {
158175 let value = filterChoicesDataByOption [ option ] [ key ] ;
159- if ( value ) {
176+ if ( value ) {
160177 viewOptions [ option ] . push ( value ) ;
161178 } else {
162- value = await fetchOneFilterOption [ option ] ( key ) ;
163- if ( value ) {
179+ try {
180+ value = await fetchOneFilterOption [ option ] ( key ) ;
181+ } catch ( e ) {
182+ setErrors ( ( errors ) => [ ...errors , ( e as { message ?: string } ) ?. message ?? 'Something went wrong. Please try again later.' ] ) ;
183+ }
184+ if ( value ) {
164185 viewOptions [ option ] . push ( value ) ;
165186 }
166187 }
@@ -240,6 +261,12 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
240261 }
241262 } ;
242263
264+ const closeAlert = ( errorIndex :number ) :void => {
265+ const newList = [ ...errors ] ;
266+ newList . splice ( errorIndex , 1 ) ;
267+ setErrors ( newList ) ;
268+ } ;
269+
243270 const filterSelector = (
244271 < div className = "pf-v6-u-mr-xs" >
245272 < BaseDropdown
@@ -322,6 +349,23 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
322349 </ ToolbarGroup >
323350 ) ;
324351
352+ const errorElements = (
353+ < div
354+ style = { {
355+ marginTop : '16px' ,
356+ } } >
357+ { errors . map ( ( error : string , i :number ) => (
358+ < Alert
359+ style = { {
360+ marginBottom : '16px' ,
361+ } }
362+ key = { i }
363+ title = { error }
364+ variant = { 'danger' }
365+ actionClose = { < AlertActionCloseButton onClose = { ( ) => closeAlert ( i ) } /> } >
366+ </ Alert > ) ) }
367+ </ div >
368+ ) ;
325369 const toolBar = (
326370 < Toolbar id = "filter-toolbar" clearAllFilters = { clearFilters } className = "pf-v6-l-flex pf-m-row-gap-md pf-v6-u-pb-0" >
327371 < ToolbarContent >
@@ -349,7 +393,8 @@ export const Filters: React.FunctionComponent<FilterComponentProps> = (props: Fi
349393
350394 return (
351395 < div >
352- < React . Fragment > { ! error && toolBar } </ React . Fragment >
396+ < React . Fragment > { ! error && ( toolBar ) } </ React . Fragment >
397+ { errorElements }
353398 </ div >
354399 ) ;
355400} ;
0 commit comments