new-app-card.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. 'use client'
  2. import React, { useMemo, useState } from 'react'
  3. import {
  4. useRouter,
  5. useSearchParams,
  6. } from 'next/navigation'
  7. import { useTranslation } from 'react-i18next'
  8. import { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-modal'
  9. import { useProviderContext } from '@/context/provider-context'
  10. // zlwu12 2025-09-18 注释
  11. // import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
  12. import { FileArrow01, FilePlus01 } from '@/app/components/base/icons/src/vender/line/files'
  13. import cn from '@/utils/classnames'
  14. import dynamic from 'next/dynamic'
  15. const CreateAppModal = dynamic(() => import('@/app/components/app/create-app-modal'), {
  16. ssr: false,
  17. })
  18. const CreateAppTemplateDialog = dynamic(() => import('@/app/components/app/create-app-dialog'), {
  19. ssr: false,
  20. })
  21. const CreateFromDSLModal = dynamic(() => import('@/app/components/app/create-from-dsl-modal'), {
  22. ssr: false,
  23. })
  24. export type CreateAppCardProps = {
  25. className?: string
  26. onSuccess?: () => void
  27. ref: React.RefObject<HTMLDivElement | null>
  28. }
  29. const CreateAppCard = ({
  30. ref,
  31. className,
  32. onSuccess,
  33. }: CreateAppCardProps) => {
  34. const { t } = useTranslation()
  35. const { onPlanInfoChanged } = useProviderContext()
  36. const searchParams = useSearchParams()
  37. const { replace } = useRouter()
  38. const dslUrl = searchParams.get('remoteInstallUrl') || undefined
  39. const [showNewAppTemplateDialog, setShowNewAppTemplateDialog] = useState(false)
  40. const [showNewAppModal, setShowNewAppModal] = useState(false)
  41. const [showCreateFromDSLModal, setShowCreateFromDSLModal] = useState(!!dslUrl)
  42. const activeTab = useMemo(() => {
  43. if (dslUrl)
  44. return CreateFromDSLModalTab.FROM_URL
  45. return undefined
  46. }, [dslUrl])
  47. return (
  48. <div
  49. ref={ref}
  50. className={cn('relative col-span-1 inline-flex h-[160px] flex-col justify-between rounded-xl border-[0.5px] border-components-card-border bg-components-card-bg', className)}
  51. >
  52. <div className='grow rounded-t-xl p-2'>
  53. <div className='px-6 pb-1 pt-2 text-xs font-medium leading-[18px] text-text-tertiary'>{t('app.createApp')}</div>
  54. <button className='mb-1 flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppModal(true)}>
  55. <FilePlus01 className='mr-2 h-4 w-4 shrink-0' />
  56. {t('app.newApp.startFromBlank')}
  57. </button>
  58. {/* zlwu12 2025-09-18 注释 */}
  59. {/* <button className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppTemplateDialog(true)}>
  60. <FilePlus02 className='mr-2 h-4 w-4 shrink-0' />
  61. {t('app.newApp.startFromTemplate')}
  62. </button> */}
  63. <button
  64. onClick={() => setShowCreateFromDSLModal(true)}
  65. className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'>
  66. <FileArrow01 className='mr-2 h-4 w-4 shrink-0' />
  67. {t('app.importDSL')}
  68. </button>
  69. </div>
  70. {showNewAppModal && (
  71. <CreateAppModal
  72. show={showNewAppModal}
  73. onClose={() => setShowNewAppModal(false)}
  74. onSuccess={() => {
  75. onPlanInfoChanged()
  76. if (onSuccess)
  77. onSuccess()
  78. }}
  79. onCreateFromTemplate={() => {
  80. setShowNewAppTemplateDialog(true)
  81. setShowNewAppModal(false)
  82. }}
  83. />
  84. )}
  85. {showNewAppTemplateDialog && (
  86. <CreateAppTemplateDialog
  87. show={showNewAppTemplateDialog}
  88. onClose={() => setShowNewAppTemplateDialog(false)}
  89. onSuccess={() => {
  90. onPlanInfoChanged()
  91. if (onSuccess)
  92. onSuccess()
  93. }}
  94. onCreateFromBlank={() => {
  95. setShowNewAppModal(true)
  96. setShowNewAppTemplateDialog(false)
  97. }}
  98. />
  99. )}
  100. {showCreateFromDSLModal && (
  101. <CreateFromDSLModal
  102. show={showCreateFromDSLModal}
  103. onClose={() => {
  104. setShowCreateFromDSLModal(false)
  105. if (dslUrl)
  106. replace('/')
  107. }}
  108. activeTab={activeTab}
  109. dslUrl={dslUrl}
  110. onSuccess={() => {
  111. onPlanInfoChanged()
  112. if (onSuccess)
  113. onSuccess()
  114. }}
  115. />
  116. )}
  117. </div>
  118. )
  119. }
  120. CreateAppCard.displayName = 'CreateAppCard'
  121. export default React.memo(CreateAppCard)