11import React , {
2- useState , useRef , FC ,
3- useEffect ,
2+ FC ,
3+ useRef ,
44} from 'react' ;
55import { useIntl } from 'react-intl' ;
66import styled from 'styled-components' ;
77import { FormikErrors } from 'formik' ;
8+ import { useQuery } from 'react-query' ;
89
910import {
10- TextInput , Popover , Flex , Box , Loader , Typography ,
11+ TextInput , Popover , Box , Loader , Typography ,
1112 Field ,
1213} from '@strapi/design-system' ;
1314import { getFetchClient } from '@strapi/strapi/admin' ;
1415import { PatternFormValues } from '../../types/url-patterns' ;
1516import { Theme } from '../../types/theme' ;
17+ import useActiveElement from '../../helpers/useActiveElement' ;
1618
1719type Props = {
1820 uid : string ;
@@ -27,37 +29,15 @@ const PatternField: FC<Props> = ({
2729 error = null ,
2830 setFieldValue,
2931} ) => {
30- const patternRef = useRef < HTMLDivElement > ( null ) ;
31- const [ loading , setLoading ] = useState ( false ) ;
32- const [ loadingError , setLoadingError ] = useState ( false ) ;
33- const [ allowedFields , setAllowedFields ] = useState < Record < string , string [ ] > | null > ( null ) ;
34- const { formatMessage } = useIntl ( ) ;
3532 const { get } = getFetchClient ( ) ;
36-
37- const [ popoverDismissed , setPopoverDismissed ] = useState ( false ) ;
38-
39- useEffect ( ( ) => {
40- const fetchAllowedFields = async ( ) => {
41- try {
42- setLoading ( true ) ;
43- const data = await get < Record < string , string [ ] > > ( '/webtools/url-pattern/allowed-fields' ) ;
44- setAllowedFields ( data . data ) ;
45- setLoading ( false ) ;
46- } catch ( err ) {
47- setLoading ( false ) ;
48- setLoadingError ( true ) ;
49- }
50- } ;
51-
52- fetchAllowedFields ( ) . catch ( ( ) => {
53- console . error ( 'Failed to fetch allowed fields:' , error ) ;
54- setLoadingError ( true ) ;
55- setLoading ( false ) ;
56- } ) ;
57- } , [ error ] ) ;
33+ const fields = useQuery ( 'fields' , async ( ) => get < Record < string , string [ ] > > ( '/webtools/url-pattern/allowed-fields' ) ) ;
34+ const { formatMessage } = useIntl ( ) ;
35+ const inputRef = useRef < HTMLInputElement > ( ) ;
36+ const popoverRef = useRef ( ) ;
5837
5938 const HoverBox = styled ( Box ) `
6039 cursor: pointer;
40+ font-size: 16px;
6141 &:hover:not([aria-disabled="true"]) {
6242 background: ${ ( { theme } : { theme : Theme } ) => theme . colors . primary100 } ;
6343 }
@@ -69,15 +49,15 @@ const PatternField: FC<Props> = ({
6949 defaultMessage : 'Create a URL alias pattern' ,
7050 } ) ;
7151 let suffix = '' ;
72- if ( allowedFields ?. [ uid ] ) {
52+ if ( fields . data . data ?. [ uid ] ) {
7353 suffix = ` ${ formatMessage ( {
7454 id : 'webtools.settings.form.pattern.description_2' ,
7555 defaultMessage : 'using' ,
7656 } ) } `;
77- allowedFields [ uid ] . forEach ( ( fieldName , i ) => {
57+ fields . data . data [ uid ] . forEach ( ( fieldName , i ) => {
7858 if ( i === 0 ) {
7959 suffix = `${ suffix } [${ fieldName } ]` ;
80- } else if ( allowedFields [ uid ] . length !== i + 1 ) {
60+ } else if ( fields . data . data [ uid ] . length !== i + 1 ) {
8161 suffix = `${ suffix } , [${ fieldName } ]` ;
8262 } else {
8363 suffix = `${ suffix } ${ formatMessage ( {
@@ -92,66 +72,58 @@ const PatternField: FC<Props> = ({
9272 } ;
9373
9474
95- if ( loading ) {
75+ if ( fields . isLoading ) {
9676 return < Loader > { formatMessage ( { id : 'webtools.settings.loading' , defaultMessage : 'Loading content...' } ) } </ Loader > ;
9777 }
9878
99- if ( loadingError || ! allowedFields ) {
79+ if ( fields . isError || ! fields . data ) {
10080 return < div > { formatMessage ( { id : 'webtools.pattern.allowedFields.fetchError' , defaultMessage : 'An error occurred while fetching allowed fields' } ) } </ div > ;
10181 }
10282
10383 return (
10484 < div >
105- < Typography variant = "pi" > { patternHint ( ) } </ Typography >
106- { values . pattern . endsWith ( '[' ) && ! popoverDismissed && (
107- < Popover . Root >
108- < Popover . Trigger >
109- < div >
110- < Field . Root
111- // @ts -ignore
112- error = { error }
113- >
114- < Field . Label >
115- { formatMessage ( {
116- id : 'webtools.settings.form.pattern.label' ,
117- defaultMessage : 'Pattern' ,
118- } ) }
119- </ Field . Label >
120- < TextInput
121- name = "pattern"
122- value = { values . pattern }
123- placeholder = "/en/pages/[id]"
124- onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) => {
125- setPopoverDismissed ( false ) ;
126- if ( e . target . value . match ( / ^ [ A - Z a - z 0 - 9 - _ .~ [ \] / ] * $ / ) ) {
127- return setFieldValue ( 'pattern' , e . target . value ) ;
128- }
85+ < Popover . Root open = { values . pattern . endsWith ( '[' ) } >
86+ < Popover . Trigger >
87+ < Field . Root error = { error } hint = { patternHint ( ) } >
88+ < Field . Label >
89+ { formatMessage ( {
90+ id : 'webtools.settings.form.pattern.label' ,
91+ defaultMessage : 'Pattern' ,
92+ } ) }
93+ </ Field . Label >
94+ < TextInput
95+ ref = { inputRef }
96+ name = "pattern"
97+ value = { values . pattern }
98+ placeholder = "/en/pages/[id]"
99+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
100+ onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) => {
101+ if ( e . target . value . match ( / ^ [ A - Z a - z 0 - 9 - _ .~ [ \] / ] * $ / ) ) {
102+ return setFieldValue ( 'pattern' , e . target . value ) ;
103+ }
129104
130- return null ;
131- } }
132- />
133- < Field . Error />
134- </ Field . Root >
135- </ div >
136- </ Popover . Trigger >
137- < Popover . Content >
138- < Flex >
139- { allowedFields [ uid ] . map ( ( fieldName ) => (
140- < HoverBox
141- key = { fieldName }
142- padding = { 2 }
143- onClick = { ( ) => {
144- const newPattern = `${ values . pattern } ${ fieldName } ]` ;
145- return setFieldValue ( 'pattern' , newPattern ) ;
146- } }
147- >
148- { fieldName }
149- </ HoverBox >
150- ) ) }
151- </ Flex >
152- </ Popover . Content >
153- </ Popover . Root >
154- ) }
105+ return null ;
106+ } }
107+ />
108+ < Field . Hint />
109+ < Field . Error />
110+ </ Field . Root >
111+ </ Popover . Trigger >
112+ < Popover . Content ref = { popoverRef } >
113+ { fields . data . data [ uid ] . map ( ( fieldName ) => (
114+ < HoverBox
115+ key = { fieldName }
116+ padding = { 2 }
117+ onClick = { ( ) => {
118+ const newPattern = `${ values . pattern } ${ fieldName } ]` ;
119+ return setFieldValue ( 'pattern' , newPattern ) ;
120+ } }
121+ >
122+ { fieldName }
123+ </ HoverBox >
124+ ) ) }
125+ </ Popover . Content >
126+ </ Popover . Root >
155127 </ div >
156128 ) ;
157129} ;
0 commit comments