mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 17:56:37 +08:00
fix(frontend): keep browser API on same-origin rewrites in dev
Document that NEXT_PUBLIC_WAVELET_BACKEND_URL must stay unset for local next dev so axios hits /api/* and Next rewrites proxy to the backend.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { toast } from 'sonner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -166,6 +167,7 @@ function DatePickerWithTime({
|
||||
}
|
||||
|
||||
export function TaskManager() {
|
||||
const t = useTranslations('admin.tasks');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [taskTypes, setTaskTypes] = useState<TaskMeta[]>([]);
|
||||
@@ -186,11 +188,13 @@ export function TaskManager() {
|
||||
const data = await services.adminTask.getTaskTypes();
|
||||
setTaskTypes(data);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err : new Error('加载任务类型失败'));
|
||||
setError(
|
||||
err instanceof Error ? err : new Error(t('loadTaskTypesFailed')),
|
||||
);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
}, [t]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTaskTypes();
|
||||
@@ -249,8 +253,11 @@ export function TaskManager() {
|
||||
|
||||
const taskID = await services.adminTask.dispatchTask(params);
|
||||
|
||||
toast.success('任务下发成功', {
|
||||
description: `已成功将任务 ${targetTask?.name || selectedTaskType} 加入队列:${taskID}`,
|
||||
toast.success(t('dispatchSuccess'), {
|
||||
description: t('dispatchSuccessDesc', {
|
||||
name: targetTask?.name || selectedTaskType,
|
||||
taskId: taskID,
|
||||
}),
|
||||
});
|
||||
setDialogOpen(false);
|
||||
|
||||
@@ -259,8 +266,8 @@ export function TaskManager() {
|
||||
setUserId('');
|
||||
setParamValues({});
|
||||
} catch (err) {
|
||||
toast.error('任务下发失败', {
|
||||
description: err instanceof Error ? err.message : '未知错误',
|
||||
toast.error(t('dispatchFailed'), {
|
||||
description: err instanceof Error ? err.message : t('unknownError'),
|
||||
});
|
||||
} finally {
|
||||
setDispatching(false);
|
||||
@@ -292,10 +299,10 @@ export function TaskManager() {
|
||||
) : loading && taskTypes.length === 0 ? (
|
||||
<LoadingStateWithBorder
|
||||
icon={Layers}
|
||||
description='加载任务类型中...'
|
||||
description={t('loadingTaskTypes')}
|
||||
/>
|
||||
) : taskTypes.length === 0 ? (
|
||||
<EmptyStateWithBorder icon={Layers} description='暂无可用任务类型' />
|
||||
<EmptyStateWithBorder icon={Layers} description={t('noTaskTypes')} />
|
||||
) : (
|
||||
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4'>
|
||||
{taskTypes.map((task, index) => {
|
||||
@@ -333,13 +340,15 @@ export function TaskManager() {
|
||||
variant='outline'
|
||||
className='text-[9px] h-4.5 bg-background/50 font-mono text-muted-foreground border-border/50 px-1'
|
||||
>
|
||||
类型:{task.type}
|
||||
{t('taskType')}
|
||||
{task.type}
|
||||
</Badge>
|
||||
<Badge
|
||||
variant='outline'
|
||||
className='text-[9px] h-4.5 bg-background/50 font-mono text-muted-foreground border-border/50 px-1'
|
||||
>
|
||||
重试:{task.max_retry}
|
||||
{t('taskRetry')}
|
||||
{task.max_retry}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
@@ -351,7 +360,7 @@ export function TaskManager() {
|
||||
onClick={() => openDispatchDialog(task.type)}
|
||||
>
|
||||
<Play className='size-3 mr-1' />
|
||||
立即执行
|
||||
{t('executeNow')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -365,15 +374,13 @@ export function TaskManager() {
|
||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||
<DialogContent className='sm:max-w-[500px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>下发任务</DialogTitle>
|
||||
<DialogDescription>
|
||||
配置任务参数并启动,任务将在后台异步执行。
|
||||
</DialogDescription>
|
||||
<DialogTitle>{t('dispatchTask')}</DialogTitle>
|
||||
<DialogDescription>{t('dispatchTaskDesc')}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className='grid gap-4 py-4'>
|
||||
<div className='grid gap-2'>
|
||||
<Label>执行任务</Label>
|
||||
<Label>{t('executeTask')}</Label>
|
||||
<div className='flex items-center gap-2 p-2 rounded-lg bg-muted/50'>
|
||||
{(() => {
|
||||
const meta = getSelectedTaskMeta();
|
||||
@@ -403,20 +410,20 @@ export function TaskManager() {
|
||||
return (
|
||||
<>
|
||||
<div className='grid gap-2'>
|
||||
<Label>开始时间</Label>
|
||||
<Label>{t('startTime')}</Label>
|
||||
<DatePickerWithTime
|
||||
date={startTime}
|
||||
setDate={setStartTime}
|
||||
/>
|
||||
<p className='text-xs text-muted-foreground'>
|
||||
选择同步的起始时间点
|
||||
{t('startTimeDesc')}
|
||||
</p>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label>结束时间</Label>
|
||||
<Label>{t('endTime')}</Label>
|
||||
<DatePickerWithTime date={endTime} setDate={setEndTime} />
|
||||
<p className='text-xs text-muted-foreground'>
|
||||
选择同步的结束时间点
|
||||
{t('endTimeDesc')}
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
@@ -474,8 +481,8 @@ export function TaskManager() {
|
||||
/>
|
||||
<span className='text-xs text-muted-foreground'>
|
||||
{paramValues[param.name] === 'true'
|
||||
? '开启'
|
||||
: '关闭'}
|
||||
? t('paramOn')
|
||||
: t('paramOff')}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
@@ -513,7 +520,7 @@ export function TaskManager() {
|
||||
return (
|
||||
<div className='flex items-center gap-2 text-sm text-muted-foreground bg-muted/50 p-3 rounded-md border border-dashed'>
|
||||
<Info className='h-4 w-4' />
|
||||
<span>此任务无需额外配置参数,确认后将直接下发。</span>
|
||||
<span>{t('noParamsHint')}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -528,7 +535,7 @@ export function TaskManager() {
|
||||
disabled={dispatching}
|
||||
className='h-8 text-xs'
|
||||
>
|
||||
取消
|
||||
{t('cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleDispatch}
|
||||
@@ -540,7 +547,7 @@ export function TaskManager() {
|
||||
) : (
|
||||
<Play className='size-3' />
|
||||
)}
|
||||
{dispatching ? '下发中' : '启动'}
|
||||
{dispatching ? t('dispatching') : t('start')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user