feat: add to workspace api

This commit is contained in:
金伟强 2023-05-18 13:58:10 +08:00
parent c42ccdfc6f
commit 78fbbded1a
8 changed files with 105 additions and 29 deletions

View File

@ -1,19 +1,15 @@
import type { FC } from 'react'
import React from 'react'
import Sidebar from '@/app/components/explore/sidebar'
import ExploreClient from '@/app/components/explore'
export type IAppDetail = {
children: React.ReactNode
}
const AppDetail: FC<IAppDetail> = ({ children }) => {
return (
<div className='flex h-full bg-gray-100 border-t border-gray-200'>
<Sidebar />
<div className='grow'>
<ExploreClient>
{children}
</div>
</div>
</ExploreClient>
)
}

View File

@ -1,18 +1,21 @@
'use client'
import React, { FC, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import ExploreContext from '@/context/explore-context'
import { App } from '@/models/explore'
import Category from '@/app/components/explore/category'
import AppCard from '@/app/components/explore/app-card'
import { fetchAppList } from '@/service/explore'
import { fetchAppList, installApp } from '@/service/explore'
import CreateAppModal from '@/app/components/explore/create-app-modal'
import Loading from '@/app/components/base/loading'
import s from './style.module.css'
import Toast from '../../base/toast'
const Apps: FC = ({ }) => {
const { t } = useTranslation()
const { setControlUpdateInstalledApps } = useContext(ExploreContext)
const [currCategory, setCurrCategory] = React.useState('')
const [allList, setAllList] = React.useState<App[]>([])
const [isLoaded, setIsLoaded] = React.useState(false)
@ -31,8 +34,13 @@ const Apps: FC = ({ }) => {
})()
}, [])
const handleAddToWorkspace = (appId: string) => {
console.log('handleAddToWorkspace', appId)
const handleAddToWorkspace = async (appId: string) => {
await installApp(appId)
Toast.notify({
type: 'success',
message: t('common.api.success'),
})
setControlUpdateInstalledApps(Date.now())
}
const [currApp, setCurrApp] = React.useState<any>(null)

View File

@ -0,0 +1,33 @@
'use client'
import React, { FC } from 'react'
import ExploreContext from '@/context/explore-context'
import Sidebar from '@/app/components/explore/sidebar'
export interface IExploreProps {
children: React.ReactNode
}
const Explore: FC<IExploreProps> = ({
children
}) => {
const [controlUpdateInstalledApps, setControlUpdateInstalledApps] = React.useState(0)
return (
<div className='flex h-full bg-gray-100 border-t border-gray-200'>
<ExploreContext.Provider
value={
{
controlUpdateInstalledApps,
setControlUpdateInstalledApps
}
}
>
<Sidebar controlUpdateInstalledApps={controlUpdateInstalledApps} />
<div className='grow'>
{children}
</div>
</ExploreContext.Provider>
</div>
)
}
export default React.memo(Explore)

View File

@ -2,7 +2,6 @@
import React, { FC, useEffect } from 'react'
import { App } from '@/types/app'
import ChatApp from '@/app/components/share/chat'
export interface IInstalledAppProps {
id: string
}

View File

@ -1,21 +1,12 @@
'use client'
import React, { FC } from 'react'
import React, { FC, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import { useSelectedLayoutSegments } from 'next/navigation'
import Link from 'next/link'
import Item from './app-nav-item'
const list = [
{
id: '1',
name: 'Story Bot',
},
{
id: '2',
name: 'Fancy title'
}
]
import { InstalledApp } from '@/models/explore'
import { fetchInstalledAppList as doFetchInstalledAppList } from '@/service/explore'
const SelectedDiscoveryIcon = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -29,11 +20,29 @@ const DiscoveryIcon = () => (
</svg>
)
const SideBar: FC = () => {
const SideBar: FC<{
controlUpdateInstalledApps: number
}> = ({
controlUpdateInstalledApps
}) => {
const { t } = useTranslation()
const segments = useSelectedLayoutSegments()
const lastSegment = segments.slice(-1)[0]
const isDiscoverySelected = lastSegment === 'apps'
const [installedApps, setInstalledApps] = React.useState<InstalledApp[]>([])
const fetchInstalledAppList = async () => {
const {installed_apps} : any = await doFetchInstalledAppList()
setInstalledApps(installed_apps)
}
useEffect(() => {
fetchInstalledAppList()
}, [])
useEffect(() => {
fetchInstalledAppList()
}, [controlUpdateInstalledApps])
return (
<div className='w-[216px] shrink-0 pt-6 px-4 border-r border-gray-200 cursor-pointer'>
@ -47,11 +56,11 @@ const SideBar: FC = () => {
<div className='text-sm'>{t('explore.sidebar.discovery')}</div>
</Link>
</div>
{list.length > 0 && (
{installedApps.length > 0 && (
<div className='mt-10'>
<div className='pl-2 text-xs text-gray-500 font-medium uppercase'>{t('explore.sidebar.workspace')}</div>
<div className='mt-3 space-y-1'>
{list.map(({id, name}) => {
{installedApps.map(({app : {id, name}}) => {
return (
<Item key={id} name={name} id={id} isSelected={lastSegment?.toLowerCase() === id} />
)

View File

@ -0,0 +1,13 @@
import { createContext } from 'use-context-selector'
type IExplore = {
controlUpdateInstalledApps: number
setControlUpdateInstalledApps: (controlUpdateInstalledApps: number) => void
}
const ExploreContext = createContext<IExplore>({
controlUpdateInstalledApps: 0,
setControlUpdateInstalledApps: () => { },
})
export default ExploreContext

View File

@ -20,4 +20,10 @@ export type App = {
install_count: number;
installed: boolean;
editable: boolean;
}
export type InstalledApp = {
app: AppBasicInfo;
id: string;
uninstallable: boolean
}

View File

@ -1,5 +1,17 @@
import { get } from './base'
import { get, post } from './base'
export const fetchAppList = () => {
return get('/explore/apps')
}
}
export const fetchInstalledAppList = () => {
return get('/installed-apps')
}
export const installApp = (id: string) => {
return post('/installed-apps', {
body: {
app_id: id
}
})
}