chore: add create app loading

This commit is contained in:
Joel 2026-03-03 10:06:56 +08:00
parent 4f1e12ea04
commit 997d3ec80e

View File

@ -1,7 +1,7 @@
'use client' 'use client'
import type { DocPathWithoutLang } from '@/types/doc-paths' import type { DocPathWithoutLang } from '@/types/doc-paths'
import { useDebounceFn, useKeyPress } from 'ahooks' import { useKeyPress } from 'ahooks'
import { noop } from 'es-toolkit/function' import { noop } from 'es-toolkit/function'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { useEffect, useMemo, useRef, useState } from 'react' import { useEffect, useMemo, useRef, useState } from 'react'
@ -66,6 +66,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
const [showErrorModal, setShowErrorModal] = useState(false) const [showErrorModal, setShowErrorModal] = useState(false)
const [versions, setVersions] = useState<{ importedVersion: string, systemVersion: string }>() const [versions, setVersions] = useState<{ importedVersion: string, systemVersion: string }>()
const [importId, setImportId] = useState<string>() const [importId, setImportId] = useState<string>()
const [isCreating, setIsCreating] = useState(false)
const { handleCheckPluginDependencies } = usePluginDependencies() const { handleCheckPluginDependencies } = usePluginDependencies()
const isZipFile = (file?: File) => !!file && file.name.toLowerCase().endsWith('.zip') const isZipFile = (file?: File) => !!file && file.name.toLowerCase().endsWith('.zip')
@ -92,12 +93,19 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps) const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps)
const isCreatingRef = useRef(false) const isCreatingRef = useRef(false)
const isMountedRef = useRef(true)
useEffect(() => { useEffect(() => {
if (droppedFile) if (droppedFile)
handleFile(droppedFile) handleFile(droppedFile)
}, [droppedFile]) }, [droppedFile])
useEffect(() => {
return () => {
isMountedRef.current = false
}
}, [])
const onCreate = async (_e?: React.MouseEvent) => { const onCreate = async (_e?: React.MouseEvent) => {
if (currentTab === CreateFromDSLModalTab.FROM_FILE && !currentFile) if (currentTab === CreateFromDSLModalTab.FROM_FILE && !currentFile)
return return
@ -106,6 +114,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
if (isCreatingRef.current) if (isCreatingRef.current)
return return
isCreatingRef.current = true isCreatingRef.current = true
setIsCreating(true)
try { try {
let response let response
@ -171,14 +180,16 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
catch (e) { catch (e) {
notify({ type: 'error', message: t('newApp.appCreateFailed', { ns: 'app' }) }) notify({ type: 'error', message: t('newApp.appCreateFailed', { ns: 'app' }) })
} }
isCreatingRef.current = false finally {
isCreatingRef.current = false
if (isMountedRef.current)
setIsCreating(false)
}
} }
const { run: handleCreateApp } = useDebounceFn(onCreate, { wait: 300 })
useKeyPress(['meta.enter', 'ctrl.enter'], () => { useKeyPress(['meta.enter', 'ctrl.enter'], () => {
if (show && !isAppsFull && ((currentTab === CreateFromDSLModalTab.FROM_FILE && currentFile) || (currentTab === CreateFromDSLModalTab.FROM_URL && dslUrlValue))) if (show && !isAppsFull && ((currentTab === CreateFromDSLModalTab.FROM_FILE && currentFile) || (currentTab === CreateFromDSLModalTab.FROM_URL && dslUrlValue)))
handleCreateApp(undefined) onCreate(undefined)
}) })
useKeyPress('esc', () => { useKeyPress('esc', () => {
@ -332,10 +343,11 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
{t('newApp.Cancel', { ns: 'app' })} {t('newApp.Cancel', { ns: 'app' })}
</Button> </Button>
<Button <Button
disabled={buttonDisabled} disabled={buttonDisabled || isCreating}
variant="primary" variant="primary"
onClick={handleCreateApp} onClick={onCreate}
className="gap-1" className="gap-1"
loading={isCreating}
> >
<span>{t('newApp.import', { ns: 'app' })}</span> <span>{t('newApp.import', { ns: 'app' })}</span>
<ShortcutsName keys={['ctrl', '↵']} bgColor="white" /> <ShortcutsName keys={['ctrl', '↵']} bgColor="white" />