mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 06:28:05 +08:00
chore: import app ui
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import type { MouseEventHandler } from 'react'
|
||||
import { RiCloseLine, RiCommandLine, RiCornerDownLeftLine } from '@remixicon/react'
|
||||
import { RiCloseLine, RiExternalLinkLine } from '@remixicon/react'
|
||||
import { useDebounceFn, useKeyPress } from 'ahooks'
|
||||
import { noop } from 'es-toolkit/function'
|
||||
import { useRouter } from 'next/navigation'
|
||||
@ -17,6 +17,7 @@ import AppsFull from '@/app/components/billing/apps-full-in-dialog'
|
||||
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import {
|
||||
DSLImportMode,
|
||||
@ -47,6 +48,7 @@ export enum CreateFromDSLModalTab {
|
||||
const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDSLModalTab.FROM_FILE, dslUrl = '', droppedFile }: CreateFromDSLModalProps) => {
|
||||
const { push } = useRouter()
|
||||
const { t } = useTranslation()
|
||||
const docLink = useDocLink()
|
||||
const { notify } = useContext(ToastContext)
|
||||
const [currentFile, setDSLFile] = useState<File | undefined>(droppedFile)
|
||||
const [fileContent, setFileContent] = useState<string>()
|
||||
@ -223,6 +225,10 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
return !dslUrlValue
|
||||
return false
|
||||
}, [isAppsFull, currentTab, currentFile, dslUrlValue])
|
||||
const learnMoreLabel = t('importFromDSLModal.learnMore', {
|
||||
ns: 'app',
|
||||
defaultValue: t('newApp.learnMore', { ns: 'app' }),
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -231,18 +237,20 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
isShow={show}
|
||||
onClose={noop}
|
||||
>
|
||||
<div className="title-2xl-semi-bold flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary">
|
||||
{t('importFromDSL', { ns: 'app' })}
|
||||
<div className="flex items-start justify-between pb-3 pl-6 pr-5 pt-6">
|
||||
<div className="title-2xl-semi-bold text-text-primary">
|
||||
{t('importFromDSL', { ns: 'app' })}
|
||||
</div>
|
||||
<div
|
||||
className="flex h-8 w-8 cursor-pointer items-center"
|
||||
className="flex h-8 w-8 cursor-pointer items-center justify-center"
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
|
||||
<RiCloseLine className="h-[18px] w-[18px] text-text-tertiary" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="system-md-semibold flex h-9 items-center space-x-6 border-b border-divider-subtle px-6 text-text-tertiary">
|
||||
{
|
||||
tabs.map(tab => (
|
||||
<div className="border-b border-divider-subtle px-6">
|
||||
<div className="system-md-semibold flex h-9 items-center gap-6 text-text-tertiary">
|
||||
{tabs.map(tab => (
|
||||
<div
|
||||
key={tab.key}
|
||||
className={cn(
|
||||
@ -252,57 +260,61 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
onClick={() => setCurrentTab(tab.key)}
|
||||
>
|
||||
{tab.label}
|
||||
{
|
||||
currentTab === tab.key && (
|
||||
<div className="absolute bottom-0 h-[2px] w-full bg-util-colors-blue-brand-blue-brand-600"></div>
|
||||
)
|
||||
}
|
||||
{currentTab === tab.key && (
|
||||
<div className="absolute bottom-0 h-[2px] w-full bg-util-colors-blue-brand-blue-brand-600"></div>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-6 py-4">
|
||||
{
|
||||
currentTab === CreateFromDSLModalTab.FROM_FILE && (
|
||||
<Uploader
|
||||
className="mt-0"
|
||||
file={currentFile}
|
||||
updateFile={handleFile}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
currentTab === CreateFromDSLModalTab.FROM_URL && (
|
||||
<div>
|
||||
<div className="system-md-semibold mb-1 text-text-secondary">DSL URL</div>
|
||||
<Input
|
||||
placeholder={t('importFromDSLUrlPlaceholder', { ns: 'app' }) || ''}
|
||||
value={dslUrlValue}
|
||||
onChange={e => setDslUrlValue(e.target.value)}
|
||||
/>
|
||||
{currentTab === CreateFromDSLModalTab.FROM_FILE && (
|
||||
<Uploader
|
||||
className="mt-0"
|
||||
file={currentFile}
|
||||
updateFile={handleFile}
|
||||
/>
|
||||
)}
|
||||
{currentTab === CreateFromDSLModalTab.FROM_URL && (
|
||||
<div>
|
||||
<div className="system-md-semibold mb-1 text-text-secondary">
|
||||
{t('importFromDSLUrl', { ns: 'app' })}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<Input
|
||||
placeholder={t('importFromDSLUrlPlaceholder', { ns: 'app' }) || ''}
|
||||
value={dslUrlValue}
|
||||
onChange={e => setDslUrlValue(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{isAppsFull && (
|
||||
<div className="px-6">
|
||||
<AppsFull className="mt-0" loc="app-create-dsl" />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-end px-6 py-5">
|
||||
<Button className="mr-2" onClick={onClose}>{t('newApp.Cancel', { ns: 'app' })}</Button>
|
||||
<Button
|
||||
disabled={buttonDisabled}
|
||||
variant="primary"
|
||||
onClick={handleCreateApp}
|
||||
className="gap-1"
|
||||
<div className="flex items-center justify-between px-6 pb-6 pt-5">
|
||||
<a
|
||||
className="system-xs-regular flex items-center gap-1 text-text-accent"
|
||||
href={docLink('/use-dify/workspace/app-management#app-export-and-import')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span>{t('newApp.Create', { ns: 'app' })}</span>
|
||||
<div className="flex gap-0.5">
|
||||
<RiCommandLine size={14} className="system-kbd rounded-sm bg-components-kbd-bg-white p-0.5" />
|
||||
<RiCornerDownLeftLine size={14} className="system-kbd rounded-sm bg-components-kbd-bg-white p-0.5" />
|
||||
</div>
|
||||
</Button>
|
||||
{learnMoreLabel}
|
||||
<RiExternalLinkLine className="h-[12px] w-[12px]" />
|
||||
</a>
|
||||
<div className="flex items-center gap-3">
|
||||
<Button variant="secondary" onClick={onClose}>
|
||||
{t('newApp.Cancel', { ns: 'app' })}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={buttonDisabled}
|
||||
variant="primary"
|
||||
onClick={handleCreateApp}
|
||||
>
|
||||
{t('newApp.import', { ns: 'app' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
|
||||
@ -109,12 +109,19 @@ const Uploader: FC<Props> = ({
|
||||
/>
|
||||
<div ref={dropRef}>
|
||||
{!file && (
|
||||
<div className={cn('flex h-12 items-center rounded-[10px] border border-dashed border-components-dropzone-border bg-components-dropzone-bg text-sm font-normal', dragging && 'border-components-dropzone-border-accent bg-components-dropzone-bg-accent')}>
|
||||
<div className="flex w-full items-center justify-center space-x-2">
|
||||
<RiUploadCloud2Line className="h-6 w-6 text-text-tertiary" />
|
||||
<div className="text-text-tertiary">
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex items-center justify-center rounded-[10px] border border-dashed border-components-dropzone-border bg-components-dropzone-bg px-4 py-[14px]',
|
||||
dragging && 'border-components-dropzone-border-accent bg-components-dropzone-bg-accent',
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<RiUploadCloud2Line className="h-5 w-5 text-text-tertiary" />
|
||||
<div className="text-[13px] font-medium leading-4 text-text-secondary">
|
||||
{t('dslUploader.button', { ns: 'app' })}
|
||||
<span className="cursor-pointer pl-1 text-text-accent" onClick={selectHandle}>{t('dslUploader.browse', { ns: 'app' })}</span>
|
||||
<span className="cursor-pointer pl-1 text-text-accent" onClick={selectHandle}>
|
||||
{t('dslUploader.browse', { ns: 'app' })}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{dragging && <div ref={dragRef} className="absolute left-0 top-0 h-full w-full" />}
|
||||
|
||||
@ -37,8 +37,8 @@
|
||||
"createFromConfigFile": "Create from DSL file",
|
||||
"deleteAppConfirmContent": "Deleting the app is irreversible. Users will no longer be able to access your app, and all prompt configurations and logs will be permanently deleted.",
|
||||
"deleteAppConfirmTitle": "Delete this app?",
|
||||
"dslUploader.browse": "Browse",
|
||||
"dslUploader.button": "Drag and drop file, or",
|
||||
"dslUploader.browse": "browse",
|
||||
"dslUploader.button": "Drag a DSL(.yml) or .zip file here, ",
|
||||
"duplicate": "Duplicate",
|
||||
"duplicateTitle": "Duplicate App",
|
||||
"editApp": "Edit Info",
|
||||
@ -119,8 +119,9 @@
|
||||
"iconPicker.ok": "OK",
|
||||
"importBundleFailed": "Import bundle failed.",
|
||||
"importDSL": "Import DSL file",
|
||||
"importFromDSL": "Import from DSL",
|
||||
"importFromDSLFile": "From DSL file",
|
||||
"importFromDSL": "Import App",
|
||||
"importFromDSLFile": "Local File",
|
||||
"importFromDSLModal.learnMore": "Learn about DSL and ZIP formats",
|
||||
"importFromDSLUrl": "From URL",
|
||||
"importFromDSLUrlPlaceholder": "Paste DSL link here",
|
||||
"join": "Join the community",
|
||||
|
||||
Reference in New Issue
Block a user