@@ -48,10 +48,6 @@ import { Heading } from './catalyst/heading'
4848
4949type ItemsType = NonNullable < PostApiClListData [ 'data' ] > [ 'items' ]
5050
51- const escapeRegExp = ( str : string ) : string => {
52- return str . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
53- }
54-
5551export default function CLView ( ) {
5652 const { scope } = useScope ( )
5753 const [ clList , setClList ] = useState < ItemsType > ( [ ] )
@@ -85,8 +81,71 @@ export default function CLView() {
8581
8682 const [ review , setReview ] = useAtom ( reviewAtom )
8783
84+ const autoGeneratedQuery = useMemo ( ( ) => {
85+ const parts : string [ ] = [ ]
86+
87+ if ( sort . Author ) {
88+ parts . push ( `author:${ sort . Author } ` )
89+ }
90+
91+ if ( sort . Assignees ) {
92+ parts . push ( `assignee:${ sort . Assignees } ` )
93+ }
94+
95+ if ( label . length > 0 ) {
96+ const labelNames = label
97+ . map ( ( id ) => labelList . find ( ( l ) => String ( l . id ) === id ) ?. name )
98+ . filter ( ( name ) : name is string => Boolean ( name ) )
99+
100+ labelNames . forEach ( ( name : string ) => {
101+ parts . push ( `label:${ name } ` )
102+ } )
103+ }
104+
105+ if ( review ) {
106+ parts . push ( `review:${ review } ` )
107+ }
108+
109+ return parts . join ( ' ' )
110+ } , [ sort , label , labelList , review ] )
111+
88112 const [ searchQuery , setSearchQuery ] = useState ( '' )
89113
114+ useEffect ( ( ) => {
115+ setSearchQuery ( autoGeneratedQuery )
116+ } , [ autoGeneratedQuery ] )
117+
118+ const parseAndApplyQuery = useCallback (
119+ ( query : string ) => {
120+ const authorMatch = query . match ( / a u t h o r : ( \S + ) / )
121+ const newAuthor = authorMatch ? authorMatch [ 1 ] : ''
122+
123+ const assigneeMatch = query . match ( / a s s i g n e e : ( \S + ) / )
124+ const newAssignee = assigneeMatch ? assigneeMatch [ 1 ] : ''
125+
126+ const labelRegex = / l a b e l : " ( [ ^ " ] + ) " | l a b e l : ( \S + ) / g
127+ const labelNames : string [ ] = [ ]
128+ let labelMatch
129+
130+ while ( ( labelMatch = labelRegex . exec ( query ) ) !== null ) {
131+ const labelName = labelMatch [ 1 ] || labelMatch [ 2 ]
132+
133+ if ( labelName ) labelNames . push ( labelName )
134+ }
135+
136+ const reviewMatch = query . match ( / r e v i e w : ( \S + ) / )
137+ const reviewValue = reviewMatch ? reviewMatch [ 1 ] : ''
138+
139+ const newLabelIds =
140+ labelNames . length > 0 ? labelList . filter ( ( l ) => labelNames . includes ( l . name ) ) . map ( ( l ) => String ( l . id ) ) : label
141+
142+ setSort ( { ...sort , Author : newAuthor , Assignees : newAssignee } )
143+ setLabel ( newLabelIds )
144+ setReview ( reviewValue )
145+ } ,
146+ [ labelList , sort , label , setSort , setLabel , setReview ]
147+ )
148+
90149 const additions = useCallback (
91150 ( labels : number [ ] ) : AdditionType => {
92151 const additional : AdditionType = { status, asc : false }
@@ -112,7 +171,8 @@ export default function CLView() {
112171 const loadClList = useCallback (
113172 ( additional ?: AdditionType ) => {
114173 setIsLoading ( true )
115- const addittion = additional ? additional : additions ( [ ] )
174+ const labelIds = label . map ( ( i ) => Number ( i ) )
175+ const addittion = additional ? additional : additions ( labelIds )
116176
117177 fetchClList (
118178 {
@@ -142,7 +202,7 @@ export default function CLView() {
142202 }
143203 )
144204 } ,
145- [ page , pageSize , fetchClList , additions ]
205+ [ page , pageSize , fetchClList , additions , label ]
146206 )
147207
148208 useEffect ( ( ) => {
@@ -227,22 +287,9 @@ export default function CLView() {
227287 onSelectFactory : ( item : Member ) => ( e : Event ) => {
228288 e . preventDefault ( )
229289 if ( item . user . username === sort [ 'Author' ] ) {
230- const escapedAuthor = escapeRegExp ( sort [ 'Author' ] )
231- const newQuery = searchQuery . replace ( new RegExp ( `author:${ escapedAuthor } \\s*` , 'g' ) , '' ) . trim ( )
232-
233- setSearchQuery ( newQuery )
234- setSort ( {
235- ...sort ,
236- Author : ''
237- } )
290+ setSort ( { ...sort , Author : '' } )
238291 } else {
239- const newQuery = searchQuery ? `${ searchQuery } author:${ item . user . username } ` : `author:${ item . user . username } `
240-
241- setSearchQuery ( newQuery )
242- setSort ( {
243- ...sort ,
244- Author : item . user . username
245- } )
292+ setSort ( { ...sort , Author : item . user . username } )
246293 }
247294 } ,
248295 className : 'overflow-hidden' ,
@@ -254,24 +301,9 @@ export default function CLView() {
254301 onSelectFactory : ( item : Member ) => ( e : Event ) => {
255302 e . preventDefault ( )
256303 if ( item . user . username === sort [ 'Assignees' ] ) {
257- const escapedAssignee = escapeRegExp ( sort [ 'Assignees' ] )
258- const newQuery = searchQuery . replace ( new RegExp ( `assignee:${ escapedAssignee } \\s*` , 'g' ) , '' ) . trim ( )
259-
260- setSearchQuery ( newQuery )
261- setSort ( {
262- ...sort ,
263- Assignees : ''
264- } )
304+ setSort ( { ...sort , Assignees : '' } )
265305 } else {
266- const newQuery = searchQuery
267- ? `${ searchQuery } assignee:${ item . user . username } `
268- : `assignee:${ item . user . username } `
269-
270- setSearchQuery ( newQuery )
271- setSort ( {
272- ...sort ,
273- Assignees : item . user . username
274- } )
306+ setSort ( { ...sort , Assignees : item . user . username } )
275307 }
276308 } ,
277309 className : 'overflow-hidden' ,
@@ -283,20 +315,11 @@ export default function CLView() {
283315 {
284316 key : 'Labels' ,
285317 isChosen : ( item ) => label ?. includes ( String ( item . id ) ) ,
286-
287318 onSelectFactory : ( item ) => ( e : Event ) => {
288319 e . preventDefault ( )
289320 if ( label ?. includes ( String ( item . id ) ) ) {
290- const escapedLabelName = escapeRegExp ( item . name )
291- const newQuery = searchQuery . replace ( new RegExp ( `label:"${ escapedLabelName } "\\s*` , 'g' ) , '' ) . trim ( )
292-
293- setSearchQuery ( newQuery )
294321 setLabel ( label . filter ( ( i ) => i !== String ( item . id ) ) )
295322 } else {
296- const escapedLabelName = escapeRegExp ( item . name )
297- const newQuery = searchQuery ? `${ searchQuery } label:"${ escapedLabelName } "` : `label:"${ escapedLabelName } "`
298-
299- setSearchQuery ( newQuery )
300323 setLabel ( [ ...label , String ( item . id ) ] )
301324 }
302325 } ,
@@ -309,21 +332,11 @@ export default function CLView() {
309332 {
310333 key : 'Review' ,
311334 isChosen : ( ) => true ,
312-
313335 onSelectFactory : ( item ) => ( e : Event ) => {
314336 e . preventDefault ( )
315337 if ( item === review ) {
316- const escapedReview = escapeRegExp ( review )
317- const newQuery = searchQuery . replace ( new RegExp ( `review:${ escapedReview } \\s*` , 'g' ) , '' ) . trim ( )
318-
319- setSearchQuery ( newQuery )
320338 setReview ( '' )
321339 } else {
322- const escapedReview = escapeRegExp ( review )
323- let newQuery = searchQuery . replace ( new RegExp ( `review:${ escapedReview } \\s*` , 'g' ) , '' ) . trim ( )
324-
325- newQuery = newQuery ? `${ newQuery } review:${ item } ` : `review:${ item } `
326- setSearchQuery ( newQuery )
327340 setReview ( item )
328341 }
329342 } ,
@@ -471,7 +484,6 @@ export default function CLView() {
471484 const router = useRouter ( )
472485
473486 const clearAllFilters = ( ) => {
474- setSearchQuery ( '' )
475487 setSort ( { ...sort , Author : '' , Assignees : '' } )
476488 setLabel ( [ ] )
477489 setReview ( '' )
@@ -497,7 +509,7 @@ export default function CLView() {
497509 onChange = { ( e ) => setSearchQuery ( e . target . value ) }
498510 onKeyDown = { ( e ) => {
499511 if ( e . key === 'Enter' ) {
500- loadClList ( )
512+ parseAndApplyQuery ( searchQuery )
501513 }
502514 } }
503515 />
0 commit comments