Files
dify/web/app/components/app/create-app-dropdown.tsx
T

122 lines
4.3 KiB
TypeScript

'use client'
import { Button } from '@langgenius/dify-ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@langgenius/dify-ui/dropdown-menu'
import { useTranslation } from 'react-i18next'
import {
getStepByStepTourDropdownMenuContentProps,
useStepByStepTourControlledDropdown,
} from '@/app/components/step-by-step-tour/dropdown-menu'
type CreateAppDropdownProps = {
onCreateBlank?: () => void
onCreateTemplate?: () => void
onImportDSL?: () => void
stepByStepTourControlledOpen?: boolean
stepByStepTourTarget?: string
stepByStepTourHighlightPart?: string
}
export function CreateAppDropdown({
onCreateBlank,
onCreateTemplate,
onImportDSL,
stepByStepTourControlledOpen,
stepByStepTourTarget,
stepByStepTourHighlightPart,
}: CreateAppDropdownProps) {
const { t } = useTranslation(['app', 'common'])
const menu = useStepByStepTourControlledDropdown({
controlledOpen: stepByStepTourControlledOpen,
})
return (
<DropdownMenu modal={false} open={menu.open} onOpenChange={menu.onOpenChange}>
<DropdownMenuTrigger
render={
<Button
data-step-by-step-tour-target={stepByStepTourTarget}
variant="primary"
size="medium"
className="px-2 whitespace-nowrap shadow-xs shadow-shadow-shadow-3"
>
<span aria-hidden className="i-ri-add-line size-4 shrink-0" />
<span>{t(($) => $['operation.create'], { ns: 'common' })}</span>
<span aria-hidden className="i-ri-arrow-down-s-line size-4 shrink-0" />
</Button>
}
/>
<DropdownMenuContent
placement="bottom-end"
sideOffset={4}
{...getStepByStepTourDropdownMenuContentProps({
disableMotion: menu.controlled,
highlightPart: menu.controlled ? stepByStepTourHighlightPart : undefined,
interactionMode: menu.controlled ? 'presentation' : 'interactive',
className: 'w-70 p-0',
})}
>
{(onCreateBlank || onCreateTemplate) && (
<DropdownMenuGroup className="py-1">
{onCreateBlank && (
<DropdownMenuItem
className="py-1 system-md-regular text-text-secondary"
onClick={onCreateBlank}
>
<span
aria-hidden
className="i-ri-sticky-note-add-line size-4 shrink-0 text-text-secondary"
/>
<span className="min-w-0 flex-1 truncate px-1">
{t(($) => $['newApp.startFromBlank'], { ns: 'app' })}
</span>
</DropdownMenuItem>
)}
{onCreateTemplate && (
<DropdownMenuItem
className="py-1 system-md-regular text-text-secondary"
onClick={onCreateTemplate}
>
<span
aria-hidden
className="i-ri-apps-2-add-line size-4 shrink-0 text-text-secondary"
/>
<span className="min-w-0 flex-1 truncate px-1">
{t(($) => $['newApp.startFromTemplate'], { ns: 'app' })}
</span>
</DropdownMenuItem>
)}
</DropdownMenuGroup>
)}
{onImportDSL && (onCreateBlank || onCreateTemplate) && (
<DropdownMenuSeparator className="my-0" />
)}
{onImportDSL && (
<DropdownMenuGroup className="py-1">
<DropdownMenuItem className="h-auto items-start py-1.5" onClick={onImportDSL}>
<span className="flex h-5 shrink-0 items-center py-0.5">
<span aria-hidden className="i-ri-file-upload-line size-4 text-text-secondary" />
</span>
<span className="flex min-w-0 flex-1 flex-col justify-center gap-0.5 px-1">
<span className="system-md-regular text-text-secondary">
{t(($) => $.importApp, { ns: 'app' })}
</span>
<span className="system-xs-regular text-text-tertiary">
{t(($) => $.importAppDescription, { ns: 'app' })}
</span>
</span>
</DropdownMenuItem>
</DropdownMenuGroup>
)}
</DropdownMenuContent>
</DropdownMenu>
)
}