fix: stabilize rule detail config persistence

This commit is contained in:
wren
2026-05-07 10:58:42 +08:00
parent 71476fc919
commit d6ce62457a
2 changed files with 181 additions and 82 deletions
+76 -9
View File
@@ -148,7 +148,9 @@ function matchesCurrentRuleDependency(currentRule: RuleSummary | undefined, cand
if (deps.size === 0) return false;
return candidates.some((candidate) => {
const value = String(candidate || '').trim();
return value ? deps.has(value) : false;
if (!value) return false;
if (deps.has(value)) return true;
return Array.from(deps).some((dependency) => dependency.startsWith(`${value}.`));
});
}
@@ -187,6 +189,13 @@ function makeId(prefix: string): string {
return `${prefix}-${Date.now()}`;
}
function rewriteDependencyPrefix(dependency: string, from: string, to: string): string {
if (!from || !to || from === to) return dependency;
if (dependency === from) return to;
if (dependency.startsWith(`${from}.`)) return `${to}${dependency.slice(from.length)}`;
return dependency;
}
function emptyRuleDraft(group = '未分组'): RuleDraft {
return {
id: makeId('rule'),
@@ -634,9 +643,13 @@ export default function RulesTestDetail() {
() => versions.find((item) => !['published', 'rollback'].includes(item.status)),
[versions],
);
const rollbackVersionOptions = useMemo(
() => versions,
[versions],
);
const rollbackOptions = useMemo(
() => versions.filter((item) => item.id !== pack.currentVersionId),
[versions, pack.currentVersionId],
() => rollbackVersionOptions.filter((item) => item.id !== pack.currentVersionId),
[rollbackVersionOptions, pack.currentVersionId],
);
const rollbackTargetVersion = useMemo(
() => rollbackOptions.find((item) => String(item.id) === selectedRollbackVersionId) || rollbackOptions[0] || null,
@@ -644,7 +657,15 @@ export default function RulesTestDetail() {
);
const packFilterMainType = pack.businessType || pack.mainType;
const currentResolvedVersion = useMemo(
() => versions.find((item) => item.id === pack.currentVersionId || item.id === pack.fallbackVersionId) || null,
() => {
if (pack.currentVersionId) {
return versions.find((item) => item.id === pack.currentVersionId) || null;
}
if (pack.fallbackVersionId) {
return versions.find((item) => item.id === pack.fallbackVersionId) || null;
}
return null;
},
[pack.currentVersionId, pack.fallbackVersionId, versions],
);
const versionStatusLabel = (status: string | undefined) => {
@@ -743,6 +764,30 @@ export default function RulesTestDetail() {
});
};
const patchCurrentRuleDependencies = (
replacements: Array<{ from: string; to: string }>,
appendedDependencies: string[],
) => {
if (!currentRule) return;
setRules((current) => current.map((rule) => {
if (rule.id !== currentRule.id) return rule;
const rewritten = rule.dependencies.map((dependency) => (
replacements.reduce(
(nextValue, item) => rewriteDependencyPrefix(nextValue, item.from, item.to),
dependency,
)
));
const merged = Array.from(new Set([
...rewritten,
...appendedDependencies.filter(Boolean),
]));
return {
...rule,
dependencies: merged,
};
}));
};
const saveRule = () => {
if (!editor || editor.kind !== 'rule') return;
const existingRule = editor.id ? rules.find(rule => rule.id === editor.id) : undefined;
@@ -802,6 +847,9 @@ export default function RulesTestDetail() {
const saveDocument = () => {
if (!editor || editor.kind !== 'document') return;
const previousDocument = editor.mode === 'edit'
? subDocuments.find((document) => document.id === editor.id)
: undefined;
const normalizedDocument: SubDocumentSummary = {
...documentDraft,
id: documentDraft.id || makeId('document'),
@@ -824,6 +872,13 @@ export default function RulesTestDetail() {
setDraftSaved(false);
setSaveMessage('');
setSaveError('');
patchCurrentRuleDependencies(
[
previousDocument ? { from: previousDocument.id, to: normalizedDocument.id } : null,
previousDocument ? { from: previousDocument.name, to: normalizedDocument.name } : null,
].filter(Boolean) as Array<{ from: string; to: string }>,
[normalizedDocument.id],
);
setEditor(null);
};
@@ -873,6 +928,9 @@ export default function RulesTestDetail() {
const saveVisual = () => {
if (!editor || editor.kind !== 'visual') return;
const previousVisual = editor.mode === 'edit'
? visualElements.find((item) => item.id === editor.id)
: undefined;
const normalizedVisual: VisualElementSummary = {
...visualDraft,
id: visualDraft.id || makeId('visual'),
@@ -889,6 +947,15 @@ export default function RulesTestDetail() {
setDraftSaved(false);
setSaveMessage('');
setSaveError('');
patchCurrentRuleDependencies(
[
previousVisual ? { from: previousVisual.id, to: normalizedVisual.id } : null,
previousVisual ? { from: previousVisual.name, to: normalizedVisual.name } : null,
previousVisual ? { from: `visual.${previousVisual.id}`, to: `visual.${normalizedVisual.id}` } : null,
previousVisual ? { from: `visual.${previousVisual.name || previousVisual.id}`, to: `visual.${normalizedVisual.name || normalizedVisual.id}` } : null,
].filter(Boolean) as Array<{ from: string; to: string }>,
[`visual.${normalizedVisual.id}`],
);
setEditor(null);
};
@@ -1027,13 +1094,13 @@ export default function RulesTestDetail() {
className="rules-version-select"
value={rollbackTargetVersion ? String(rollbackTargetVersion.id) : selectedRollbackVersionId}
onChange={(event) => setSelectedRollbackVersionId(event.target.value)}
disabled={saveButtonBusy || rollbackOptions.length === 0}
disabled={saveButtonBusy || rollbackVersionOptions.length === 0}
>
{rollbackOptions.length === 0 ? (
{rollbackVersionOptions.length === 0 ? (
<option value=""></option>
) : rollbackOptions.map((item) => (
<option key={item.id} value={item.id}>
{item.versionNo} · {versionStatusLabel(item.status)}
) : rollbackVersionOptions.map((item) => (
<option key={item.id} value={item.id} disabled={item.id === pack.currentVersionId}>
{item.versionNo} · {versionStatusLabel(item.status)}{item.id === pack.currentVersionId ? ' · 当前版本' : ''}
</option>
))}
</select>