mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-11 00:06:04 +00:00
Add pipeline copy button to duplicate existing configurations (#1767)
* Initial plan * Add copy button to pipeline configuration page Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Add i18n support for copy suffix and address code review feedback Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Show new pipeline name in copy toast and close dialog after copy Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * perf: tool list style in extension tab --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
@@ -286,8 +286,8 @@ export default function PipelineExtension({
|
||||
variant="outline"
|
||||
className="flex items-center gap-1 mt-1"
|
||||
>
|
||||
<Wrench className="h-3 w-3 text-white" />
|
||||
<span className="text-xs text-white">
|
||||
<Wrench className="h-3 w-3 text-black dark:text-white" />
|
||||
<span className="text-xs text-black dark:text-white">
|
||||
{t('pipelines.extensions.toolCount', {
|
||||
count: server.runtime_info.tool_count || 0,
|
||||
})}
|
||||
@@ -416,14 +416,17 @@ export default function PipelineExtension({
|
||||
</div>
|
||||
{server.runtime_info &&
|
||||
server.runtime_info.status === 'connected' && (
|
||||
<div className="flex items-center gap-1 mt-1">
|
||||
<Wrench className="h-3 w-3 text-muted-foreground" />
|
||||
<span className="text-xs text-muted-foreground">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center gap-1 mt-1"
|
||||
>
|
||||
<Wrench className="h-3 w-3 text-black dark:text-white" />
|
||||
<span className="text-xs text-black dark:text-white">
|
||||
{t('pipelines.extensions.toolCount', {
|
||||
count: server.runtime_info.tool_count || 0,
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{!server.enable && (
|
||||
|
||||
@@ -346,6 +346,32 @@ export default function PipelineFormComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = () => {
|
||||
if (pipelineId) {
|
||||
let newPipelineName = '';
|
||||
httpClient
|
||||
.getPipeline(pipelineId)
|
||||
.then((resp) => {
|
||||
const originalPipeline = resp.pipeline;
|
||||
newPipelineName = `${originalPipeline.name}${t('pipelines.copySuffix')}`;
|
||||
const newPipeline: Pipeline = {
|
||||
name: newPipelineName,
|
||||
description: originalPipeline.description,
|
||||
config: originalPipeline.config,
|
||||
};
|
||||
return httpClient.createPipeline(newPipeline);
|
||||
})
|
||||
.then(() => {
|
||||
onFinish();
|
||||
toast.success(`${t('common.copySuccess')}: ${newPipelineName}`);
|
||||
onCancel();
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(t('pipelines.createError') + err.message);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="!max-w-[70vw] max-w-6xl h-full p-0 flex flex-col bg-white dark:bg-black">
|
||||
@@ -478,6 +504,18 @@ export default function PipelineFormComponent({
|
||||
{t('pipelines.defaultPipelineCannotDelete')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isEditMode && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="default"
|
||||
onClick={handleCopy}
|
||||
className="bg-green-600 hover:bg-green-700 text-white"
|
||||
>
|
||||
{t('common.copy')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button type="submit" form="pipeline-form">
|
||||
{isEditMode ? t('common.save') : t('common.submit')}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user