Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

new-app-card.tsx 4.5KB

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