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) {
|
||||
storage.setLanguage(lng);
|
||||
setLocal(getLocale(lng));
|
||||
// Should reflect to <html lang="...">
|
||||
document.documentElement.lang = lng;
|
||||
});
|
||||
|
||||
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.`,
|
||||
},
|
||||
memory: {
|
||||
taskLogDialog: {
|
||||
title: 'Memory',
|
||||
startTime: 'Start time',
|
||||
status: 'Status',
|
||||
details: 'Details',
|
||||
|
||||
success: 'Success',
|
||||
running: 'Running',
|
||||
failed: 'Failed',
|
||||
},
|
||||
|
||||
messages: {
|
||||
forget: 'Forget',
|
||||
forgetMessageTip: 'Are you sure you want to forget?',
|
||||
|
||||
@ -10,7 +10,17 @@ export interface IMessageInfo {
|
||||
invalid_at: string;
|
||||
forget_at: string;
|
||||
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 {
|
||||
|
||||
@ -5,6 +5,15 @@ import {
|
||||
import { EmptyType } from '@/components/empty/constant';
|
||||
import Empty from '@/components/empty/empty';
|
||||
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 { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
@ -27,6 +36,7 @@ import {
|
||||
Row,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
createColumnHelper,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getExpandedRowModel,
|
||||
@ -35,6 +45,7 @@ import {
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import dayjs from 'dayjs';
|
||||
import { t } from 'i18next';
|
||||
import { pick } from 'lodash';
|
||||
import {
|
||||
@ -57,6 +68,18 @@ export type MemoryTableProps = {
|
||||
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({
|
||||
messages,
|
||||
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',
|
||||
header: () => <span>{t('memory.messages.action')}</span>,
|
||||
@ -244,7 +359,7 @@ export function MemoryTable({
|
||||
data: messages,
|
||||
columns,
|
||||
onExpandedChange: setExpanded,
|
||||
getSubRows: (row) => row.extract || undefined,
|
||||
getSubRows: (row) => (row.extract as IMessageInfo[]) || undefined,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
|
||||
Reference in New Issue
Block a user