Skip to content

Commit

Permalink
Merge branch 'feat/new-studio' into deploy/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
douxc committed Dec 4, 2024
2 parents 2acc20f + e4b4689 commit 36940ec
Show file tree
Hide file tree
Showing 54 changed files with 1,300 additions and 532 deletions.
25 changes: 4 additions & 21 deletions web/app/(commonLayout)/apps/AppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import Divider from '@/app/components/base/divider'
import { getRedirection } from '@/utils/app-redirection'
import { useProviderContext } from '@/context/provider-context'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { AiText, ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel'
import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal'
import EditAppModal from '@/app/components/explore/create-app-modal'
import SwitchAppModal from '@/app/components/app/switch-app-modal'
Expand All @@ -31,6 +29,7 @@ import TagSelector from '@/app/components/base/tag-management/selector'
import type { EnvironmentVariable } from '@/app/components/workflow/types'
import DSLExportConfirmModal from '@/app/components/workflow/dsl-export-confirm-modal'
import { fetchWorkflowDraft } from '@/service/workflow'
import { AppTypeIcon } from '@/app/components/app/type-selector'

export type AppCardProps = {
app: App
Expand Down Expand Up @@ -257,7 +256,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
e.preventDefault()
getRedirection(isCurrentWorkspaceEditor, app, push)
}}
className='relative group col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg'
className='relative h-[160px] group col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm inline-flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg'
>
<div className='flex pt-[14px] px-[14px] pb-3 h-[66px] items-center gap-3 grow-0 shrink-0'>
<div className='relative shrink-0'>
Expand All @@ -268,30 +267,14 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
background={app.icon_background}
imageUrl={app.icon_url}
/>
<span className='absolute bottom-[-3px] right-[-3px] w-4 h-4 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm'>
{app.mode === 'advanced-chat' && (
<ChatBot className='w-3 h-3 text-[#1570EF]' />
)}
{app.mode === 'agent-chat' && (
<CuteRobot className='w-3 h-3 text-indigo-600' />
)}
{app.mode === 'chat' && (
<ChatBot className='w-3 h-3 text-[#1570EF]' />
)}
{app.mode === 'completion' && (
<AiText className='w-3 h-3 text-[#0E9384]' />
)}
{app.mode === 'workflow' && (
<Route className='w-3 h-3 text-[#f79009]' />
)}
</span>
<AppTypeIcon type={app.mode} wrapperClassName='absolute -bottom-0.5 -right-0.5 w-4 h-4 shadow-sm' className='w-3 h-3' />
</div>
<div className='grow w-0 py-[1px]'>
<div className='flex items-center text-sm leading-5 font-semibold text-gray-800'>
<div className='truncate' title={app.name}>{app.name}</div>
</div>
<div className='flex items-center text-[10px] leading-[18px] text-gray-500 font-medium'>
{app.mode === 'advanced-chat' && <div className='truncate'>{t('app.types.chatbot').toUpperCase()}</div>}
{app.mode === 'advanced-chat' && <div className='truncate'>{t('app.types.advanced').toUpperCase()}</div>}
{app.mode === 'chat' && <div className='truncate'>{t('app.types.chatbot').toUpperCase()}</div>}
{app.mode === 'agent-chat' && <div className='truncate'>{t('app.types.agent').toUpperCase()}</div>}
{app.mode === 'workflow' && <div className='truncate'>{t('app.types.workflow').toUpperCase()}</div>}
Expand Down
40 changes: 32 additions & 8 deletions web/app/(commonLayout)/apps/Apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,20 @@ const Apps = () => {
/>
</div>
</div>
<nav className='grid content-start grid-cols-1 gap-4 px-12 pt-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0'>
{isCurrentWorkspaceEditor
&& <NewAppCard onSuccess={mutate} />}
{data?.map(({ data: apps }) => apps.map(app => (
<AppCard key={app.id} app={app} onRefresh={mutate} />
)))}
<CheckModal />
</nav>
{(data && data[0].total > 0)
? <div className='grid content-start grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-4 px-12 pt-2 grow relative'>
{isCurrentWorkspaceEditor
&& <NewAppCard onSuccess={mutate} />}
{data.map(({ data: apps }) => apps.map(app => (
<AppCard key={app.id} app={app} onRefresh={mutate} />
)))}
</div>
: <div className='grid content-start grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-4 px-12 pt-2 grow relative overflow-hidden'>
{isCurrentWorkspaceEditor
&& <NewAppCard className='z-10' onSuccess={mutate} />}
<NoAppsFound />
</div>}
<CheckModal />
<div ref={anchorRef} className='h-0'> </div>
{showTagManagementModal && (
<TagManagementModal type='app' show={showTagManagementModal} />
Expand All @@ -160,3 +166,21 @@ const Apps = () => {
}

export default Apps

function NoAppsFound() {
const { t } = useTranslation()
function renderDefaultCard() {
const defaultCards = Array.from({ length: 36 }, (_, index) => (
<div key={index} className='h-[160px] inline-flex rounded-xl bg-background-default-lighter'></div>
))
return defaultCards
}
return (
<>
{renderDefaultCard()}
<div className='absolute top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-gradient-to-t from-background-body to-transparent'>
<span className='system-md-medium text-text-tertiary'>{t('app.newApp.noAppsFound')}</span>
</div>
</>
)
}
18 changes: 14 additions & 4 deletions web/app/(commonLayout)/apps/NewAppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import CreateAppModal from '@/app/components/app/create-app-modal'
import CreateFromDSLModal, { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-modal'
import { useProviderContext } from '@/context/provider-context'
import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import cn from '@/utils/classnames'

export type CreateAppCardProps = {
className?: string
onSuccess?: () => void
}

// eslint-disable-next-line react/display-name
const CreateAppCard = forwardRef<HTMLAnchorElement, CreateAppCardProps>(({ onSuccess }, ref) => {
const CreateAppCard = forwardRef<HTMLDivElement, CreateAppCardProps>(({ className, onSuccess }, ref) => {
const { t } = useTranslation()
const { onPlanInfoChanged } = useProviderContext()
const searchParams = useSearchParams()
Expand All @@ -36,9 +38,9 @@ const CreateAppCard = forwardRef<HTMLAnchorElement, CreateAppCardProps>(({ onSuc
}, [dslUrl])

return (
<a
<div
ref={ref}
className='relative col-span-1 flex flex-col justify-between min-h-[160px] bg-gray-200 rounded-xl border-[0.5px] border-black/5'
className={cn('relative col-span-1 inline-flex flex-col justify-between h-[160px] bg-gray-200 rounded-xl border-[0.5px] border-black/5', className)}
>
<div className='grow p-2 rounded-t-xl'>
<div className='px-6 pt-2 pb-1 text-xs font-medium leading-[18px] text-gray-500'>{t('app.createApp')}</div>
Expand Down Expand Up @@ -68,6 +70,10 @@ const CreateAppCard = forwardRef<HTMLAnchorElement, CreateAppCardProps>(({ onSuc
if (onSuccess)
onSuccess()
}}
onCreateFromTemplate={() => {
setShowNewAppTemplateDialog(true)
setShowNewAppModal(false)
}}
/>
<CreateAppTemplateDialog
show={showNewAppTemplateDialog}
Expand All @@ -77,6 +83,10 @@ const CreateAppCard = forwardRef<HTMLAnchorElement, CreateAppCardProps>(({ onSuc
if (onSuccess)
onSuccess()
}}
onCreateFromBlank={() => {
setShowNewAppModal(true)
setShowNewAppTemplateDialog(false)
}}
/>
<CreateFromDSLModal
show={showCreateFromDSLModal}
Expand All @@ -94,7 +104,7 @@ const CreateAppCard = forwardRef<HTMLAnchorElement, CreateAppCardProps>(({ onSuc
onSuccess()
}}
/>
</a>
</div>
)
})

Expand Down
59 changes: 59 additions & 0 deletions web/app/components/app/create-app-dialog/app-card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client'
import { useTranslation } from 'react-i18next'
import { PlusIcon } from '@heroicons/react/20/solid'
import { AppTypeIcon, AppTypeLabel } from '../../type-selector'
import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
import type { App } from '@/models/explore'
import AppIcon from '@/app/components/base/app-icon'

export type AppCardProps = {
app: App
canCreate: boolean
onCreate: () => void
}

const AppCard = ({
app,
onCreate,
}: AppCardProps) => {
const { t } = useTranslation()
const { app: appBasicInfo } = app
return (
<div className={cn('p-4 h-[132px] relative overflow-hidden flex flex-col group bg-components-panel-on-panel-item-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xs hover:shadow-lg cursor-pointer')}>
<div className='flex items-center gap-3 pb-2 grow-0 shrink-0'>
<div className='relative shrink-0'>
<AppIcon
size='large'
iconType={app.app.icon_type}
icon={app.app.icon}
background={app.app.icon_background}
imageUrl={app.app.icon_url}
/>
<AppTypeIcon wrapperClassName='absolute -bottom-0.5 -right-0.5 w-4 h-4' className='w-3 h-3' type={appBasicInfo.mode} />
</div>
<div className='grow flex flex-col gap-1'>
<div className='line-clamp-1'>
<span className='system-md-semibold text-text-secondary' title={appBasicInfo.name}>{appBasicInfo.name}</span>
</div>
<AppTypeLabel className='system-2xs-medium-uppercase text-text-tertiary' type={app.app.mode} />
</div>
</div>
<div className="py-1 system-xs-regular text-text-tertiary">
<div className='line-clamp-3'>
{app.description}
</div>
</div>
<div className={cn('hidden absolute bottom-0 left-0 right-0 p-4 pt-8 group-hover:flex bg-gradient-to-t from-[60.27%] from-components-panel-gradient-2 to-transparent')}>
<div className={cn('flex items-center w-full space-x-2 h-8')}>
<Button variant='primary' className='grow' onClick={() => onCreate()}>
<PlusIcon className='w-4 h-4 mr-1' />
<span className='text-xs'>{t('app.newApp.useTemplate')}</span>
</Button>
</div>
</div>
</div>
)
}

export default AppCard
Loading

0 comments on commit 36940ec

Please sign in to comment.