mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-05-03 08:47:48 +08:00
Feat: Modify the style of the release confirmation box. (#13542)
### What problem does this PR solve? Feat: Modify the style of the release confirmation box. ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Co-authored-by: Yingfeng <yingfeng.zhang@gmail.com> Co-authored-by: balibabu <assassin_cike@163.com> Co-authored-by: 6ba3i <isbaaoui09@gmail.com>
This commit is contained in:
@ -17,12 +17,11 @@ interface IProps {
|
||||
sharedBadge?: ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
testId?: string;
|
||||
showReleaseTime?: boolean;
|
||||
}
|
||||
|
||||
function Time({ time }: { time: string | number | undefined }) {
|
||||
return (
|
||||
<p className="text-sm opacity-80 whitespace-nowrap">{formatDate(time)}</p>
|
||||
);
|
||||
return <p className="text-sm whitespace-nowrap">{formatDate(time)}</p>;
|
||||
}
|
||||
export function HomeCard({
|
||||
data,
|
||||
@ -31,6 +30,7 @@ export function HomeCard({
|
||||
sharedBadge,
|
||||
icon,
|
||||
testId,
|
||||
showReleaseTime = false,
|
||||
}: IProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -82,16 +82,18 @@ export function HomeCard({
|
||||
{data.description}
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
{data.release_time ? (
|
||||
<section>
|
||||
<div className="flex items-center gap-2 text-sm opacity-80">
|
||||
{showReleaseTime ? (
|
||||
<section className="text-sm text-text-secondary space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
{`${t('flow.lastSavedAt')}:`}
|
||||
<Time time={data.update_time}></Time>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm opacity-80">
|
||||
{`${t('flow.publishedAt')}:`}
|
||||
<Time time={data.release_time}></Time>
|
||||
</div>
|
||||
{data.release_time && (
|
||||
<div className="flex items-center gap-2">
|
||||
{`${t('flow.publishedAt')}:`}
|
||||
<Time time={data.release_time}></Time>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
) : (
|
||||
<Time time={data.update_time}></Time>
|
||||
|
||||
@ -33,6 +33,7 @@ export interface ISwitchForm {
|
||||
import { AgentCategory } from '@/constants/agent';
|
||||
import { Edge, Node } from '@xyflow/react';
|
||||
import { IReference, Message } from './chat';
|
||||
import { IKnowledge } from './knowledge';
|
||||
|
||||
export type DSLComponents = Record<string, IOperator>;
|
||||
|
||||
@ -80,6 +81,7 @@ export declare interface IFlow {
|
||||
release?: boolean;
|
||||
release_time?: number;
|
||||
last_publish_time?: number;
|
||||
datasets?: Pick<IKnowledge, 'id' | 'name' | 'avatar'>[];
|
||||
}
|
||||
|
||||
export interface IFlowTemplate {
|
||||
|
||||
@ -2196,9 +2196,11 @@ This process aggregates variables from multiple branches into a single variable
|
||||
production: 'Production',
|
||||
productionTooltip:
|
||||
'This version is published to production. Access it via the API or the embedded page.',
|
||||
confirmPublish: 'Confirm Publish',
|
||||
publishDescription: 'You are about to publish this data pipeline.',
|
||||
linkedDataset: 'Linked dataset',
|
||||
confirmPublish: 'Confirm publish',
|
||||
publishIngestionPipeline:
|
||||
'You are about to publish this Ingestion pipeline.',
|
||||
publishAgent: 'You are about to publish this agent',
|
||||
linkedDataset: 'Linked dataset:',
|
||||
lastPublished: 'Last published',
|
||||
createFromBlank: 'Create from blank',
|
||||
createFromTemplate: 'Create from template',
|
||||
|
||||
@ -202,7 +202,7 @@ export default {
|
||||
// editMetadataForDataset: '查看和编辑元数据 ',
|
||||
restrictDefinedValues: '限制为已定义的值',
|
||||
metadataGenerationSettings: '元数据生成设置',
|
||||
// manageMetadataForDataset: '管理此数据集的元数据',
|
||||
// manageMetadataForDataset: '管理此知识库的元数据',
|
||||
manageMetadata: '管理元数据',
|
||||
metadata: '元数据',
|
||||
values: '值',
|
||||
@ -247,7 +247,7 @@ export default {
|
||||
startDate: '开始时间',
|
||||
source: '来源',
|
||||
fileName: '文件名',
|
||||
datasetLogs: '数据集',
|
||||
datasetLogs: '知识库',
|
||||
fileLogs: '文件',
|
||||
overview: '日志',
|
||||
success: '成功',
|
||||
@ -390,7 +390,7 @@ export default {
|
||||
knowledgeConfiguration: {
|
||||
randomSeedTip:
|
||||
'种子是伪随机算法的起点,它确保在不同运行中产生相同的输出,从而保证可重复性。',
|
||||
datasetDescription: '你的数据集描述。',
|
||||
datasetDescription: '你的知识库描述。',
|
||||
overlappedPercentTip: '相邻两个块之间的重叠百分比',
|
||||
settings: '设置',
|
||||
autoMetadataTip:
|
||||
@ -430,13 +430,13 @@ export default {
|
||||
baseInfo: '基础信息',
|
||||
globalIndex: '全局索引',
|
||||
dataSource: '数据源',
|
||||
linkSourceSetTip: '管理与此数据集的数据源链接',
|
||||
linkSourceSetTip: '管理与此知识库的数据源链接',
|
||||
linkDataSource: '链接数据源',
|
||||
tocExtractionTip:
|
||||
'对于已有的chunk生成层级结构的目录信息(每个文件一个目录)。在查询时,激活`Page Index`后,系统会用大模型去判断用户问题和哪些目录项相关,从而找到相关的chunk。',
|
||||
deleteGenerateModalContent: `
|
||||
<p>删除生成的 <strong class='text-text-primary'>{{type}}</strong> 结果
|
||||
将从此数据集中移除所有派生实体和关系。
|
||||
将从此知识库中移除所有派生实体和关系。
|
||||
您的原始文件将保持不变。<p>
|
||||
<br/>
|
||||
是否要继续?
|
||||
@ -449,7 +449,7 @@ export default {
|
||||
setDefaultTip: '',
|
||||
setDefault: '设置默认',
|
||||
editLinkDataPipeline: '编辑pipeline',
|
||||
linkPipelineSetTip: '管理与此数据集的数据管道链接',
|
||||
linkPipelineSetTip: '管理与此知识库的数据管道链接',
|
||||
default: '默认',
|
||||
dataPipeline: '切换或配置 ingestion pipeline。',
|
||||
linkDataPipeline: '关联pipeline',
|
||||
@ -630,7 +630,7 @@ export default {
|
||||
tagSetTip: `
|
||||
<p> 请选择一个或多个标签集或标签知识库,用于对知识库中的每个文本块进行标记。</p>
|
||||
<p>对这些文本块的查询也将自动关联相应标签。 </p>
|
||||
<p>此功能基于文本相似度,能够为数据集的文本块批量添加更多领域知识,从而显著提高检索准确性。该功能还能提升大量文本块的操作效率。</p>
|
||||
<p>此功能基于文本相似度,能够为知识库的文本块批量添加更多领域知识,从而显著提高检索准确性。该功能还能提升大量文本块的操作效率。</p>
|
||||
<p>为了更好地理解标签集的作用,以下是标签集和关键词之间的主要区别:</p>
|
||||
<ul>
|
||||
<li>标签集是一个由用户定义和管理的封闭集,而自动生成的关键词属于开放集合。 </li>
|
||||
@ -704,7 +704,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
assistantAvatar: '助理头像',
|
||||
language: '语言',
|
||||
emptyResponse: '空回复',
|
||||
emptyResponsePlaceholder: '在数据集中未找到您要寻找的答案!',
|
||||
emptyResponsePlaceholder: '在知识库中未找到您要寻找的答案!',
|
||||
emptyResponseTip: `如果在知识库中没有检索到用户的问题,它将使用它作为答案。 如果您希望 LLM 在未检索到任何内容时提出自己的意见,请将此留空。`,
|
||||
emptyResponseMessage: `当知识库中未检索到任何相关信息时,将触发空响应。由于未选择任何知识库,因此请清除“空响应”。`,
|
||||
setAnOpener: '设置开场白',
|
||||
@ -719,7 +719,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
systemPlaceholder: `你是一个智能助手,主要功能是基于提供的知识库严格回答问题。
|
||||
|
||||
**重要规则:**
|
||||
- 你的回答必须**仅**来自此数据集:{knowledge}。
|
||||
- 你的回答必须**仅**来自此知识库:{knowledge}。
|
||||
- **当信息可用时**: 总结内容以给出详细答案。
|
||||
- **当信息不可用时**: 你的回答必须包含这句确切的话:"在知识库中未找到您要的答案!"
|
||||
- **始终考虑**整个对话历史。`,
|
||||
@ -1893,6 +1893,11 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
release: '发布',
|
||||
production: '正式版',
|
||||
productionTooltip: '此版本已发布到生产环境。可通过 API 或嵌入页面访问。',
|
||||
confirmPublish: '确认发布',
|
||||
publishIngestionPipeline: '您即将发布此 Ingestion pipeline。',
|
||||
publishAgent: '您即将发布此智能体',
|
||||
linkedDataset: '已关联的知识库:',
|
||||
lastPublished: '上次发布时间',
|
||||
createFromBlank: '从空白创建',
|
||||
createFromTemplate: '从模板创建',
|
||||
importJsonFile: '导入 JSON 文件',
|
||||
@ -1920,7 +1925,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
regularExpressions: '正则表达式',
|
||||
overlappedPercent: '重叠百分比(%)',
|
||||
searchMethod: '搜索方法',
|
||||
searchMethodTip: `决定该数据集启用的搜索方式,可选择全文、向量,或两者兼有。
|
||||
searchMethodTip: `决定该知识库启用的搜索方式,可选择全文、向量,或两者兼有。
|
||||
Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
|
||||
filenameEmbdWeight: '文件名嵌入权重',
|
||||
parserMethod: '解析方法',
|
||||
@ -2178,7 +2183,7 @@ Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
|
||||
changeStepModalCancelText: '取消',
|
||||
unlinkPipelineModalTitle: '解绑pipeline',
|
||||
unlinkPipelineModalContent: `
|
||||
<p>一旦取消链接,该数据集将不再连接到当前数据管道。</p>
|
||||
<p>一旦取消链接,该知识库将不再连接到当前数据管道。</p>
|
||||
<p>正在解析的文件将继续解析,直到完成。</p>
|
||||
<p>尚未解析的文件将不再被处理。</p> <br/>
|
||||
<p>你确定要继续吗?</p> `,
|
||||
@ -2217,8 +2222,8 @@ Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
|
||||
noMCP: '暂无 MCP 服务器可用',
|
||||
agentTitle: '尚未创建智能体',
|
||||
notFoundAgent: '未查询到智能体',
|
||||
datasetTitle: '尚未创建数据集',
|
||||
notFoundDataset: '未查询到数据集',
|
||||
datasetTitle: '尚未创建知识库',
|
||||
notFoundDataset: '未查询到知识库',
|
||||
chatTitle: '尚未创建聊天应用',
|
||||
notFoundChat: '未查询到聊天应用',
|
||||
searchTitle: '尚未创建搜索应用',
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
||||
import { Button, ButtonLoading } from '@/components/ui/button';
|
||||
import {
|
||||
Dialog,
|
||||
@ -9,12 +10,12 @@ import {
|
||||
DialogTrigger,
|
||||
} from '@/components/ui/dialog';
|
||||
import { IFlow } from '@/interfaces/database/agent';
|
||||
import { Operator } from '@/pages/agent/constant';
|
||||
import useGraphStore from '@/pages/agent/store';
|
||||
import { IKnowledge } from '@/interfaces/database/knowledge';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import { BookPlus } from 'lucide-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useIsPipeline } from '../hooks/use-is-pipeline';
|
||||
|
||||
interface PublishConfirmDialogProps {
|
||||
agentDetail: IFlow;
|
||||
@ -22,6 +23,43 @@ interface PublishConfirmDialogProps {
|
||||
onPublish: () => void;
|
||||
}
|
||||
|
||||
function AssociatedDataset({
|
||||
associatedDatasets,
|
||||
}: {
|
||||
associatedDatasets: Pick<IKnowledge, 'id' | 'name' | 'avatar'>[];
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="space-y-2 pl-10 pt-3">
|
||||
<div className="text-sm font-medium text-text-secondary">
|
||||
{t('flow.linkedDataset')}
|
||||
</div>
|
||||
{associatedDatasets.length > 0 ? (
|
||||
<div className="space-y-2 max-h-32 overflow-y-auto">
|
||||
{associatedDatasets.map((dataset) => (
|
||||
<div
|
||||
key={dataset.id}
|
||||
className="flex items-center gap-2 px-2 py-2 bg-bg-card rounded text-sm text-text-primary"
|
||||
>
|
||||
<RAGFlowAvatar
|
||||
avatar={dataset.avatar}
|
||||
name={dataset.name}
|
||||
className="size-4 text-xs"
|
||||
/>
|
||||
<span className="truncate text-text-secondary">
|
||||
{dataset.name}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-sm text-text-disabled">{t('common.noData')}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PublishConfirmDialog({
|
||||
agentDetail,
|
||||
loading,
|
||||
@ -29,30 +67,28 @@ export function PublishConfirmDialog({
|
||||
}: PublishConfirmDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
const nodes = useGraphStore((state) => state.nodes);
|
||||
|
||||
const linkedDatasets = useMemo(() => {
|
||||
const datasets: string[] = [];
|
||||
nodes.forEach((node) => {
|
||||
if (node.data.label === Operator.Retrieval) {
|
||||
const kbIds = node.data.form?.kb_ids || [];
|
||||
datasets.push(...kbIds);
|
||||
}
|
||||
});
|
||||
return [...new Set(datasets)];
|
||||
}, [nodes]);
|
||||
const isPipeline = useIsPipeline();
|
||||
|
||||
const lastPublished = useMemo(() => {
|
||||
if (agentDetail?.last_publish_time) {
|
||||
return formatDate(agentDetail.last_publish_time);
|
||||
}
|
||||
return '-';
|
||||
return '';
|
||||
}, [agentDetail?.update_time]);
|
||||
|
||||
const handleConfirmPublish = () => {
|
||||
// Get datasets associated with this pipeline from API response
|
||||
const associatedDatasets = useMemo(() => {
|
||||
return agentDetail?.datasets || [];
|
||||
}, [agentDetail?.datasets]);
|
||||
|
||||
const handleConfirmPublish = useCallback(() => {
|
||||
onPublish();
|
||||
setOpen(false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (isPipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
@ -66,29 +102,39 @@ export function PublishConfirmDialog({
|
||||
<DialogTitle>{t('flow.confirmPublish')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogDescription>
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-sm font-medium text-text-primary">
|
||||
{agentDetail.title}
|
||||
</span>
|
||||
<div className="space-y-3">
|
||||
<div className="text-sm text-text-secondary">
|
||||
{t(
|
||||
`flow.${isPipeline ? 'publishIngestionPipeline' : 'publishAgent'}`,
|
||||
)}
|
||||
</div>
|
||||
|
||||
<section className="bg-bg-input px-2.5 py-4 rounded border border-border-default">
|
||||
<div className="flex gap-2.5 items-center">
|
||||
<RAGFlowAvatar
|
||||
avatar={agentDetail.avatar}
|
||||
name={agentDetail.title}
|
||||
className="size-8"
|
||||
/>
|
||||
<span className="text-text-primary text-lg">
|
||||
{agentDetail.title}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{isPipeline && (
|
||||
<AssociatedDataset
|
||||
associatedDatasets={associatedDatasets}
|
||||
></AssociatedDataset>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-text-secondary">
|
||||
{t('flow.linkedDataset')}
|
||||
</span>
|
||||
<span className="text-text-primary">
|
||||
{linkedDatasets.length > 0
|
||||
? linkedDatasets.join(', ')
|
||||
: t('common.none')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-text-secondary">
|
||||
{t('flow.lastPublished')}
|
||||
</span>
|
||||
<span className="text-text-primary">{lastPublished}</span>
|
||||
</div>
|
||||
{lastPublished && (
|
||||
<div className="flex items-center text-sm text-text-secondary gap-2">
|
||||
<span>{t('flow.lastPublished')}:</span>
|
||||
<span>{lastPublished}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</DialogDescription>
|
||||
|
||||
@ -44,6 +44,7 @@ export function AgentCard({ data, showAgentRenameModal }: DatasetCardProps) {
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
showReleaseTime
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user