feat: 支持工作流插件复用与试运行

- 新增工作流插件类型、发布快照同步、实时可用性与下线影响检查

- 收口绑定候选、分类权限、间接环路校验与运行态优雅降级

- 补齐管理端工作流插件配置、详情与试运行界面及定向测试
This commit is contained in:
2026-04-12 13:15:13 +08:00
parent 6da90e2296
commit 47655a728b
57 changed files with 4018 additions and 780 deletions

View File

@@ -37,6 +37,7 @@
let inputEl = $state<HTMLInputElement | null>(null);
let textareaEl = $state<HTMLTextAreaElement | null>(null);
let highlightEl = $state<HTMLDivElement | null>(null);
let scrollbarWidth = $state(0);
let triggerObject: any;
let isFocused = $state(false);
let isComposing = $state(false);
@@ -49,6 +50,17 @@
}
});
$effect(() => {
localValue;
if (mode !== 'textarea') {
return;
}
requestAnimationFrame(() => {
updateScrollbarWidth();
});
});
const paramCandidates = $derived(flattenParameterCandidates(parameters));
const paramNames = $derived(paramCandidates.map((item) => item.name));
const unresolvedParamSet = $derived.by(() => {
@@ -129,9 +141,48 @@
highlightEl.scrollLeft = el.scrollLeft;
};
const updateScrollbarWidth = () => {
const el = textareaEl;
if (!el || mode !== 'textarea') {
scrollbarWidth = 0;
return;
}
const style = getComputedStyle(el);
const borderLeft = parseFloat(style.borderLeftWidth || '0');
const borderRight = parseFloat(style.borderRightWidth || '0');
const nextWidth = Math.max(0, el.offsetWidth - el.clientWidth - borderLeft - borderRight);
scrollbarWidth = Number.isFinite(nextWidth) ? nextWidth : 0;
};
const syncEditorMetrics = () => {
syncScroll();
updateScrollbarWidth();
};
$effect(() => {
if (mode !== 'textarea' || !textareaEl) {
scrollbarWidth = 0;
return;
}
const resizeObserver = typeof ResizeObserver !== 'undefined'
? new ResizeObserver(() => {
updateScrollbarWidth();
})
: null;
updateScrollbarWidth();
resizeObserver?.observe(textareaEl);
return () => {
resizeObserver?.disconnect();
};
});
const handleInput = (event: Event) => {
localValue = ((event.target as HTMLInputElement | HTMLTextAreaElement).value || '') as string;
syncScroll();
syncEditorMetrics();
emitInput(event);
};
@@ -158,7 +209,7 @@
newEditorEl.focus();
newEditorEl.setSelectionRange(result.cursor, result.cursor);
}
syncScroll();
syncEditorMetrics();
triggerObject?.hide?.();
};
@@ -310,7 +361,7 @@
editorEl.focus();
editorEl.setSelectionRange(deleteRange.start, deleteRange.start);
}
syncScroll();
syncEditorMetrics();
rest.onkeydown?.(event);
return;
}
@@ -339,7 +390,7 @@
editorEl.focus();
editorEl.setSelectionRange(tokenRange.start, tokenRange.start);
}
syncScroll();
syncEditorMetrics();
rest.onkeydown?.(event);
};
@@ -400,6 +451,7 @@
<div
class="param-token-editor-highlight {mode === 'input' ? 'single-line' : 'multi-line'}"
bind:this={highlightEl}
style={`--param-token-scrollbar-width: ${scrollbarWidth}px;`}
aria-hidden="true"
>
{@html highlightedHtml}
@@ -571,7 +623,9 @@
inset: 0;
border: 1px solid transparent;
border-radius: 5px;
padding: var(--param-token-padding-y) var(--param-token-padding-right) var(--param-token-padding-y)
padding: var(--param-token-padding-y)
calc(var(--param-token-padding-right) + var(--param-token-scrollbar-width, 0px))
var(--param-token-padding-y)
var(--param-token-padding-left);
box-sizing: border-box;
color: var(--tf-text-primary);
@@ -621,6 +675,8 @@
.param-token-textarea {
overflow: auto;
display: block;
scrollbar-gutter: stable;
}
.param-token-action {