feat: support app rename and make app card ui better (#766)
Co-authored-by: Gillian97 <jinling.sunshine@gmail.com>
This commit is contained in:
@@ -7,31 +7,21 @@ import useSWR, { useSWRConfig } from 'swr'
|
||||
import AppCard from '@/app/components/app/overview/appCard'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { fetchAppDetail, updateAppApiStatus, updateAppSiteAccessToken, updateAppSiteConfig, updateAppSiteStatus } from '@/service/apps'
|
||||
import type { IToastProps } from '@/app/components/base/toast'
|
||||
import {
|
||||
fetchAppDetail,
|
||||
updateAppSiteAccessToken,
|
||||
updateAppSiteConfig,
|
||||
updateAppSiteStatus,
|
||||
} from '@/service/apps'
|
||||
import type { App } from '@/types/app'
|
||||
import type { UpdateAppSiteCodeResponse } from '@/models/app'
|
||||
import { asyncRunSafe } from '@/utils'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
|
||||
export type ICardViewProps = {
|
||||
appId: string
|
||||
}
|
||||
|
||||
type IParams = {
|
||||
url: string
|
||||
body?: Record<string, any>
|
||||
}
|
||||
|
||||
export async function asyncRunSafe<T>(func: (val: IParams) => Promise<T>, params: IParams, callback: (props: IToastProps) => void, dict?: any): Promise<[string?, T?]> {
|
||||
try {
|
||||
const res = await func(params)
|
||||
callback && callback({ type: 'success', message: dict('common.actionMsg.modifiedSuccessfully') })
|
||||
return [undefined, res]
|
||||
}
|
||||
catch (err) {
|
||||
callback && callback({ type: 'error', message: dict('common.actionMsg.modificationFailed') })
|
||||
return [(err as Error).message, undefined]
|
||||
}
|
||||
}
|
||||
|
||||
const CardView: FC<ICardViewProps> = ({ appId }) => {
|
||||
const detailParams = { url: '/apps', id: appId }
|
||||
const { data: response } = useSWR(detailParams, fetchAppDetail)
|
||||
@@ -42,44 +32,78 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
|
||||
if (!response)
|
||||
return <Loading />
|
||||
|
||||
const onChangeSiteStatus = async (value: boolean) => {
|
||||
const [err] = await asyncRunSafe<App>(updateAppSiteStatus as any, { url: `/apps/${appId}/site-enable`, body: { enable_site: value } }, notify, t)
|
||||
if (!err)
|
||||
const handleError = (err: Error | null) => {
|
||||
if (!err) {
|
||||
notify({
|
||||
type: 'success',
|
||||
message: t('common.actionMsg.modifiedSuccessfully'),
|
||||
})
|
||||
mutate(detailParams)
|
||||
}
|
||||
else {
|
||||
notify({
|
||||
type: 'error',
|
||||
message: t('common.actionMsg.modificationFailed'),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onChangeSiteStatus = async (value: boolean) => {
|
||||
const [err] = await asyncRunSafe<App>(
|
||||
updateAppSiteStatus({
|
||||
url: `/apps/${appId}/site-enable`,
|
||||
body: { enable_site: value },
|
||||
}) as Promise<App>,
|
||||
)
|
||||
handleError(err)
|
||||
}
|
||||
|
||||
const onChangeApiStatus = async (value: boolean) => {
|
||||
const [err] = await asyncRunSafe<App>(updateAppApiStatus as any, { url: `/apps/${appId}/api-enable`, body: { enable_api: value } }, notify, t)
|
||||
if (!err)
|
||||
mutate(detailParams)
|
||||
const [err] = await asyncRunSafe<App>(
|
||||
updateAppSiteStatus({
|
||||
url: `/apps/${appId}/api-enable`,
|
||||
body: { enable_api: value },
|
||||
}) as Promise<App>,
|
||||
)
|
||||
handleError(err)
|
||||
}
|
||||
|
||||
const onSaveSiteConfig = async (params: any) => {
|
||||
const [err] = await asyncRunSafe<App>(updateAppSiteConfig as any, { url: `/apps/${appId}/site`, body: params }, notify, t)
|
||||
const [err] = await asyncRunSafe<App>(
|
||||
updateAppSiteConfig({
|
||||
url: `/apps/${appId}/site`,
|
||||
body: params,
|
||||
}) as Promise<App>,
|
||||
)
|
||||
if (!err)
|
||||
mutate(detailParams)
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
|
||||
handleError(err)
|
||||
}
|
||||
|
||||
const onGenerateCode = async () => {
|
||||
const [err] = await asyncRunSafe<App>(updateAppSiteAccessToken as any, { url: `/apps/${appId}/site/access-token-reset` }, notify, t)
|
||||
if (!err)
|
||||
mutate(detailParams)
|
||||
const [err] = await asyncRunSafe<UpdateAppSiteCodeResponse>(
|
||||
updateAppSiteAccessToken({
|
||||
url: `/apps/${appId}/site/access-token-reset`,
|
||||
}) as Promise<UpdateAppSiteCodeResponse>,
|
||||
)
|
||||
handleError(err)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex flex-row justify-between w-full mb-6'>
|
||||
<div className="min-w-max grid gap-6 grid-cols-1 xl:grid-cols-2 w-full mb-6">
|
||||
<AppCard
|
||||
className='mr-3 flex-1'
|
||||
appInfo={response}
|
||||
cardType='webapp'
|
||||
cardType="webapp"
|
||||
onChangeStatus={onChangeSiteStatus}
|
||||
onGenerateCode={onGenerateCode}
|
||||
onSaveSiteConfig={onSaveSiteConfig} />
|
||||
onSaveSiteConfig={onSaveSiteConfig}
|
||||
/>
|
||||
<AppCard
|
||||
className='ml-3 flex-1'
|
||||
cardType='api'
|
||||
cardType="api"
|
||||
appInfo={response}
|
||||
onChangeStatus={onChangeApiStatus} />
|
||||
onChangeStatus={onChangeApiStatus}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,35 +46,23 @@ export default function ChartView({ appId }: IChartViewProps) {
|
||||
defaultValue={7}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex flex-row w-full mb-6'>
|
||||
<div className='flex-1 mr-3'>
|
||||
<ConversationsChart period={period} id={appId} />
|
||||
</div>
|
||||
<div className='flex-1 ml-3'>
|
||||
<EndUsersChart period={period} id={appId} />
|
||||
</div>
|
||||
<div className='grid gap-6 grid-cols-1 xl:grid-cols-2 w-full mb-6'>
|
||||
<ConversationsChart period={period} id={appId} />
|
||||
<EndUsersChart period={period} id={appId} />
|
||||
</div>
|
||||
<div className='flex flex-row w-full mb-6'>
|
||||
<div className='flex-1 mr-3'>
|
||||
{isChatApp
|
||||
? (
|
||||
<AvgSessionInteractions period={period} id={appId} />
|
||||
)
|
||||
: (
|
||||
<AvgResponseTime period={period} id={appId} />
|
||||
)}
|
||||
</div>
|
||||
<div className='flex-1 ml-3'>
|
||||
<TokenPerSecond period={period} id={appId} />
|
||||
</div>
|
||||
<div className='grid gap-6 grid-cols-1 xl:grid-cols-2 w-full mb-6'>
|
||||
{isChatApp
|
||||
? (
|
||||
<AvgSessionInteractions period={period} id={appId} />
|
||||
)
|
||||
: (
|
||||
<AvgResponseTime period={period} id={appId} />
|
||||
)}
|
||||
<TokenPerSecond period={period} id={appId} />
|
||||
</div>
|
||||
<div className='flex flex-row w-full mb-6'>
|
||||
<div className='flex-1 ml-3'>
|
||||
<UserSatisfactionRate period={period} id={appId} />
|
||||
</div>
|
||||
<div className='flex-1 ml-3'>
|
||||
<CostChart period={period} id={appId} />
|
||||
</div>
|
||||
<div className='grid gap-6 grid-cols-1 xl:grid-cols-2 w-full mb-6'>
|
||||
<UserSatisfactionRate period={period} id={appId} />
|
||||
<CostChart period={period} id={appId} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user