1- import { FormEvent , ReactNode , useEffect , useState } from 'react' ;
1+ import { FormEvent , ReactNode , useRef , useState } from 'react' ;
22import {
33 Dialog ,
44 DialogClose ,
@@ -47,12 +47,8 @@ export default function CreateDatabase({
4747 const [ open , setOpen ] = useState ( false ) ;
4848 const [ charsets , setCharsets ] = useState < string [ ] > ( [ ] ) ;
4949 const [ collations , setCollations ] = useState < string [ ] > ( [ ] ) ;
50-
51- const fetchCharsets = async ( ) => {
52- axios . get ( route ( 'databases.charsets' , server ) ) . then ( ( response ) => {
53- setCharsets ( response . data ) ;
54- } ) ;
55- } ;
50+ const fetchedServer = useRef < number | null > ( null ) ;
51+ const latestCollationRequest = useRef ( 0 ) ;
5652
5753 const form = useForm < CreateForm > ( {
5854 name : '' ,
@@ -62,14 +58,44 @@ export default function CreateDatabase({
6258 existing_user_id : '' ,
6359 } ) ;
6460
65- // Auto-load collations when modal opens with a default charset
66- useEffect ( ( ) => {
67- if ( open && form . data . charset && charsets . includes ( form . data . charset ) && collations . length === 0 ) {
68- axios . get ( route ( 'databases.collations' , { server : server , charset : form . data . charset } ) ) . then ( ( response ) => {
69- setCollations ( response . data ) ;
70- } ) ;
61+ const resolveCollation = ( list : string [ ] , defaultCollation : string | null , current : string ) : string => {
62+ if ( current && list . includes ( current ) ) {
63+ return current ;
7164 }
72- } , [ open , charsets , form . data . charset , server , collations ] ) ;
65+ if ( defaultCollation && list . includes ( defaultCollation ) ) {
66+ return defaultCollation ;
67+ }
68+ return list [ 0 ] ?? '' ;
69+ } ;
70+
71+ const fetchCollations = async ( charset : string , current : string ) : Promise < void > => {
72+ const requestId = ++ latestCollationRequest . current ;
73+ try {
74+ const response = await axios . get ( route ( 'databases.collations' , { server : server , charset } ) ) ;
75+ if ( requestId !== latestCollationRequest . current ) {
76+ return ;
77+ }
78+ setCollations ( response . data . list ) ;
79+ form . setData ( 'collation' , resolveCollation ( response . data . list , response . data . default , current ) ) ;
80+ } catch {
81+ if ( requestId !== latestCollationRequest . current ) {
82+ return ;
83+ }
84+ setCollations ( [ ] ) ;
85+ form . setData ( 'collation' , '' ) ;
86+ }
87+ } ;
88+
89+ const fetchCharsets = async ( ) => {
90+ setCollations ( [ ] ) ;
91+ const response = await axios . get ( route ( 'databases.charsets' , server ) ) ;
92+ fetchedServer . current = server ;
93+ setCharsets ( response . data ) ;
94+
95+ if ( form . data . charset && response . data . includes ( form . data . charset ) ) {
96+ await fetchCollations ( form . data . charset , form . data . collation ) ;
97+ }
98+ } ;
7399
74100 const submit = ( e : FormEvent ) => {
75101 e . preventDefault ( ) ;
@@ -89,17 +115,14 @@ export default function CreateDatabase({
89115
90116 const handleOpenChange = ( open : boolean ) => {
91117 setOpen ( open ) ;
92- if ( open && charsets . length === 0 ) {
118+ if ( open && fetchedServer . current !== server ) {
93119 fetchCharsets ( ) ;
94120 }
95121 } ;
96122
97123 const handleCharsetChange = ( value : string ) => {
98- form . setData ( 'collation' , '' ) ;
99124 form . setData ( 'charset' , value ) ;
100- axios . get ( route ( 'databases.collations' , { server : server , charset : value } ) ) . then ( ( response ) => {
101- setCollations ( response . data ) ;
102- } ) ;
125+ void fetchCollations ( value , '' ) ;
103126 } ;
104127
105128 return (
0 commit comments