feat(ui/alerts): ReviewStep + promotion prefill warnings
Review step dumps a human summary plus raw request JSON, and (when a
setter is supplied) offers an Enabled-on-save Toggle. Promotion prefill
now returns {form, warnings}: clears agent IDs (per-env), flags missing
apps in target env, and flags webhook connections not allowed in target
env. 4 Vitest cases cover copy-name, agent clear, app-missing, and
webhook-not-allowed paths.
The wizard now consumes {form, warnings}; Task 25 renders the warnings
banner.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,59 @@
|
||||
import { initialForm, type FormState } from './form-state';
|
||||
import type { AlertRuleResponse } from '../../../api/queries/alertRules';
|
||||
|
||||
/**
|
||||
* Prefill the wizard form from a source rule being promoted from another env.
|
||||
*
|
||||
* Task 19 scaffolding: reuses the edit-prefill path and renames the rule.
|
||||
* Task 24 rewrites this to compute scope-adjustment warnings and return
|
||||
* `{ form, warnings }`.
|
||||
*/
|
||||
export function prefillFromPromotion(source: AlertRuleResponse): FormState {
|
||||
const f = initialForm(source);
|
||||
f.name = `${source.name ?? 'rule'} (copy)`;
|
||||
return f;
|
||||
export interface PrefillWarning {
|
||||
field: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface PrefillOptions {
|
||||
targetEnvAppSlugs?: string[];
|
||||
/** IDs of outbound connections allowed in the target env. */
|
||||
targetEnvAllowedConnectionIds?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-side prefill when promoting a rule from another env. Emits warnings for
|
||||
* fields that cross env boundaries (agent IDs, apps missing in target env,
|
||||
* outbound connections not allowed in target env).
|
||||
*/
|
||||
export function prefillFromPromotion(
|
||||
source: AlertRuleResponse,
|
||||
opts: PrefillOptions = {},
|
||||
): { form: FormState; warnings: PrefillWarning[] } {
|
||||
const form = initialForm(source);
|
||||
form.name = `${source.name ?? 'rule'} (copy)`;
|
||||
const warnings: PrefillWarning[] = [];
|
||||
|
||||
// Agent IDs are per-env, can't transfer.
|
||||
if (form.agentId) {
|
||||
warnings.push({
|
||||
field: 'scope.agentId',
|
||||
message: `Agent \`${form.agentId}\` is specific to the source env \u2014 cleared for target env.`,
|
||||
});
|
||||
form.agentId = '';
|
||||
if (form.scopeKind === 'agent') form.scopeKind = 'app';
|
||||
}
|
||||
|
||||
// App slug: warn if not present in target env.
|
||||
if (form.appSlug && opts.targetEnvAppSlugs && !opts.targetEnvAppSlugs.includes(form.appSlug)) {
|
||||
warnings.push({
|
||||
field: 'scope.appSlug',
|
||||
message: `App \`${form.appSlug}\` does not exist in the target env. Update before saving.`,
|
||||
});
|
||||
}
|
||||
|
||||
// Webhook connections: warn if connection is not allowed in target env.
|
||||
if (opts.targetEnvAllowedConnectionIds) {
|
||||
for (const w of form.webhooks) {
|
||||
if (!opts.targetEnvAllowedConnectionIds.includes(w.outboundConnectionId)) {
|
||||
warnings.push({
|
||||
field: `webhooks[${w.outboundConnectionId}]`,
|
||||
message: `Outbound connection is not allowed in the target env \u2014 remove or pick another before saving.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { form, warnings };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user