mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-03 17:15:08 +08:00
feat: memory status (#12959)
### What problem does this PR solve? Add memory status indicator and detail message dialog ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -91,6 +91,8 @@ function Root({ children }: React.PropsWithChildren) {
|
|||||||
i18n.on('languageChanged', function (lng: string) {
|
i18n.on('languageChanged', function (lng: string) {
|
||||||
storage.setLanguage(lng);
|
storage.setLanguage(lng);
|
||||||
setLocal(getLocale(lng));
|
setLocal(getLocale(lng));
|
||||||
|
// Should reflect to <html lang="...">
|
||||||
|
document.documentElement.lang = lng;
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -129,6 +129,17 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
|||||||
delMemoryWarn: `After deletion, all messages in this memory will be deleted and cannot be retrieved by agents.`,
|
delMemoryWarn: `After deletion, all messages in this memory will be deleted and cannot be retrieved by agents.`,
|
||||||
},
|
},
|
||||||
memory: {
|
memory: {
|
||||||
|
taskLogDialog: {
|
||||||
|
title: 'Memory',
|
||||||
|
startTime: 'Start time',
|
||||||
|
status: 'Status',
|
||||||
|
details: 'Details',
|
||||||
|
|
||||||
|
success: 'Success',
|
||||||
|
running: 'Running',
|
||||||
|
failed: 'Failed',
|
||||||
|
},
|
||||||
|
|
||||||
messages: {
|
messages: {
|
||||||
forget: 'Forget',
|
forget: 'Forget',
|
||||||
forgetMessageTip: 'Are you sure you want to forget?',
|
forgetMessageTip: 'Are you sure you want to forget?',
|
||||||
|
|||||||
@ -10,7 +10,17 @@ export interface IMessageInfo {
|
|||||||
invalid_at: string;
|
invalid_at: string;
|
||||||
forget_at: string;
|
forget_at: string;
|
||||||
status: boolean;
|
status: boolean;
|
||||||
extract?: IMessageInfo[];
|
extract?: Omit<IMessageInfo, 'task'>[];
|
||||||
|
task: {
|
||||||
|
chunk_ids: string;
|
||||||
|
create_time: number;
|
||||||
|
digest: string;
|
||||||
|
doc_id: string;
|
||||||
|
from_page: number;
|
||||||
|
id: string;
|
||||||
|
progress: number;
|
||||||
|
progress_msg: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessageTableProps {
|
export interface IMessageTableProps {
|
||||||
|
|||||||
@ -5,6 +5,15 @@ import {
|
|||||||
import { EmptyType } from '@/components/empty/constant';
|
import { EmptyType } from '@/components/empty/constant';
|
||||||
import Empty from '@/components/empty/empty';
|
import Empty from '@/components/empty/empty';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogClose,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@/components/ui/dialog';
|
||||||
import { Modal } from '@/components/ui/modal/modal';
|
import { Modal } from '@/components/ui/modal/modal';
|
||||||
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
@ -27,6 +36,7 @@ import {
|
|||||||
Row,
|
Row,
|
||||||
SortingState,
|
SortingState,
|
||||||
VisibilityState,
|
VisibilityState,
|
||||||
|
createColumnHelper,
|
||||||
flexRender,
|
flexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
getExpandedRowModel,
|
getExpandedRowModel,
|
||||||
@ -35,6 +45,7 @@ import {
|
|||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import {
|
import {
|
||||||
@ -57,6 +68,18 @@ export type MemoryTableProps = {
|
|||||||
setPagination: (params: { page: number; pageSize: number }) => void;
|
setPagination: (params: { page: number; pageSize: number }) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const columnHelper = createColumnHelper<IMessageInfo>();
|
||||||
|
|
||||||
|
function getTaskStatus(progress: number) {
|
||||||
|
if (progress >= 1) {
|
||||||
|
return 'success';
|
||||||
|
} else if (progress > 0 && progress < 1) {
|
||||||
|
return 'running';
|
||||||
|
} else {
|
||||||
|
return 'failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function MemoryTable({
|
export function MemoryTable({
|
||||||
messages,
|
messages,
|
||||||
total,
|
total,
|
||||||
@ -198,6 +221,98 @@ export function MemoryTable({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
columnHelper.display({
|
||||||
|
id: 'task_progress',
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const { task } = row.original;
|
||||||
|
|
||||||
|
if (!task) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskStatus = getTaskStatus(task.progress);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="transparent"
|
||||||
|
size="icon"
|
||||||
|
className="border-0 size-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cn('size-1 rounded-full', {
|
||||||
|
'bg-state-success': taskStatus === 'success',
|
||||||
|
'bg-state-error': taskStatus === 'failed',
|
||||||
|
'bg-state-warning': taskStatus === 'running',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{t('memory.taskLogDialog.title')}</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<dl className="space-y-4">
|
||||||
|
<div className="grid grid-rows-2 grid-cols-2 grid-flow-col items-center gap-x-4 gap-y-1">
|
||||||
|
<dt className="text-text-secondary">
|
||||||
|
{t('memory.taskLogDialog.startTime')}
|
||||||
|
</dt>
|
||||||
|
<dd className="text-sm">
|
||||||
|
{dayjs(task.create_time)
|
||||||
|
.locale(document.documentElement.lang)
|
||||||
|
.format('MM/DD/YYYY HH:mm:ss')}
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt className="text-text-secondary">
|
||||||
|
{t('memory.taskLogDialog.status')}
|
||||||
|
</dt>
|
||||||
|
<dd className="text-sm">
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'inline-flex items-center gap-1 text-xs rounded-full px-2 py-1',
|
||||||
|
{
|
||||||
|
'text-state-success bg-state-success-5':
|
||||||
|
taskStatus === 'success',
|
||||||
|
'text-state-error bg-state-error-5':
|
||||||
|
taskStatus === 'failed',
|
||||||
|
'text-state-warning bg-state-warning-5':
|
||||||
|
taskStatus === 'running',
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="size-1 rounded-full bg-current" />
|
||||||
|
{t(`memory.taskLogDialog.${taskStatus}`)}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-1">
|
||||||
|
<dt className="text-text-secondary">
|
||||||
|
{t('memory.taskLogDialog.details')}
|
||||||
|
</dt>
|
||||||
|
<dd className="text-sm">
|
||||||
|
<div className="bg-bg-card rounded-lg p-2 max-h-64 overflow-auto">
|
||||||
|
<pre>
|
||||||
|
<code>{task.progress_msg}</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button variant="ghost">{t('common.close')}</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
accessorKey: 'action',
|
accessorKey: 'action',
|
||||||
header: () => <span>{t('memory.messages.action')}</span>,
|
header: () => <span>{t('memory.messages.action')}</span>,
|
||||||
@ -244,7 +359,7 @@ export function MemoryTable({
|
|||||||
data: messages,
|
data: messages,
|
||||||
columns,
|
columns,
|
||||||
onExpandedChange: setExpanded,
|
onExpandedChange: setExpanded,
|
||||||
getSubRows: (row) => row.extract || undefined,
|
getSubRows: (row) => (row.extract as IMessageInfo[]) || undefined,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
|||||||
Reference in New Issue
Block a user