eslint and build
Some checks failed
CI / Rustfmt (push) Successful in 22s
CI / Cargo Audit & Deny (push) Failing after 32s
CI / Web Blocking Checks (push) Successful in 47s
CI / Security Blocking Checks (push) Successful in 9s
CI / Clippy (push) Successful in 2m9s
CI / Web Advisory Checks (push) Successful in 37s
CI / Security Advisory Checks (push) Successful in 34s
CI / Tests (push) Failing after 8m37s
Some checks failed
CI / Rustfmt (push) Successful in 22s
CI / Cargo Audit & Deny (push) Failing after 32s
CI / Web Blocking Checks (push) Successful in 47s
CI / Security Blocking Checks (push) Successful in 9s
CI / Clippy (push) Successful in 2m9s
CI / Web Advisory Checks (push) Successful in 37s
CI / Security Advisory Checks (push) Successful in 34s
CI / Tests (push) Failing after 8m37s
This commit is contained in:
@@ -4,7 +4,9 @@ import { useCreatePack, useUpdatePack } from "@/hooks/usePacks";
|
|||||||
import type { PackResponse } from "@/api";
|
import type { PackResponse } from "@/api";
|
||||||
import { labelToRef } from "@/lib/format-utils";
|
import { labelToRef } from "@/lib/format-utils";
|
||||||
import SchemaBuilder from "@/components/common/SchemaBuilder";
|
import SchemaBuilder from "@/components/common/SchemaBuilder";
|
||||||
import ParamSchemaForm from "@/components/common/ParamSchemaForm";
|
import ParamSchemaForm, {
|
||||||
|
type ParamSchema,
|
||||||
|
} from "@/components/common/ParamSchemaForm";
|
||||||
import { RotateCcw } from "lucide-react";
|
import { RotateCcw } from "lucide-react";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -603,7 +605,7 @@ export default function PackForm({ pack, onSuccess, onCancel }: PackFormProps) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ParamSchemaForm
|
<ParamSchemaForm
|
||||||
schema={confSchema}
|
schema={confSchema as unknown as ParamSchema}
|
||||||
values={configValues}
|
values={configValues}
|
||||||
onChange={setConfigValues}
|
onChange={setConfigValues}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import type {
|
|||||||
TriggerResponse,
|
TriggerResponse,
|
||||||
ActionResponse,
|
ActionResponse,
|
||||||
} from "@/types/api";
|
} from "@/types/api";
|
||||||
|
import type { CreateRuleRequest, UpdateRuleRequest } from "@/api";
|
||||||
import { labelToRef, extractLocalRef, combineRefs } from "@/lib/format-utils";
|
import { labelToRef, extractLocalRef, combineRefs } from "@/lib/format-utils";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -205,7 +206,7 @@ export default function RuleForm({ rule, onSuccess, onCancel }: RuleFormProps) {
|
|||||||
// Combine pack ref and local ref to create full ref
|
// Combine pack ref and local ref to create full ref
|
||||||
const fullRef = combineRefs(selectedPackData?.ref || "", localRef.trim());
|
const fullRef = combineRefs(selectedPackData?.ref || "", localRef.trim());
|
||||||
|
|
||||||
const formData: Record<string, JsonValue> = {
|
const formData: Record<string, JsonValue> & Partial<CreateRuleRequest> = {
|
||||||
pack_ref: selectedPackData?.ref || "",
|
pack_ref: selectedPackData?.ref || "",
|
||||||
ref: fullRef,
|
ref: fullRef,
|
||||||
label: label.trim(),
|
label: label.trim(),
|
||||||
@@ -232,9 +233,14 @@ export default function RuleForm({ rule, onSuccess, onCancel }: RuleFormProps) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (isEditing && rule) {
|
if (isEditing && rule) {
|
||||||
await updateRule.mutateAsync({ ref: rule.ref, data: formData });
|
await updateRule.mutateAsync({
|
||||||
|
ref: rule.ref,
|
||||||
|
data: formData as unknown as UpdateRuleRequest,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const newRuleResponse = await createRule.mutateAsync(formData);
|
const newRuleResponse = await createRule.mutateAsync(
|
||||||
|
formData as unknown as CreateRuleRequest,
|
||||||
|
);
|
||||||
if (!onSuccess) {
|
if (!onSuccess) {
|
||||||
navigate(`/rules/${newRuleResponse.data.ref}`);
|
navigate(`/rules/${newRuleResponse.data.ref}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ export default function TriggerForm({
|
|||||||
setPackId(pack.id);
|
setPackId(pack.id);
|
||||||
}
|
}
|
||||||
// Extract local ref from full ref
|
// Extract local ref from full ref
|
||||||
setLocalRef(extractLocalRef(initialData.ref, initialData.pack_ref));
|
setLocalRef(
|
||||||
|
extractLocalRef(initialData.ref, initialData.pack_ref ?? undefined),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [initialData, packs, isEditing]);
|
}, [initialData, packs, isEditing]);
|
||||||
|
|||||||
@@ -213,7 +213,9 @@ export default function WorkflowInputsPanel({
|
|||||||
<SchemaBuilder
|
<SchemaBuilder
|
||||||
value={draftSchema}
|
value={draftSchema}
|
||||||
onChange={(schema) =>
|
onChange={(schema) =>
|
||||||
setDraftSchema(schema as Record<string, ParamDefinition>)
|
setDraftSchema(
|
||||||
|
schema as unknown as Record<string, ParamDefinition>,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
placeholder={
|
placeholder={
|
||||||
modalTarget === "parameters"
|
modalTarget === "parameters"
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { useEntityNotifications } from "@/contexts/WebSocketContext";
|
import {
|
||||||
|
useEntityNotifications,
|
||||||
|
type Notification,
|
||||||
|
} from "@/contexts/WebSocketContext";
|
||||||
|
|
||||||
interface UseArtifactStreamOptions {
|
interface UseArtifactStreamOptions {
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +65,8 @@ export function useArtifactStream(options: UseArtifactStreamOptions = {}) {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const handleNotification = useCallback(
|
const handleNotification = useCallback(
|
||||||
(notification: ArtifactNotification) => {
|
(raw: Notification) => {
|
||||||
|
const notification = raw as unknown as ArtifactNotification;
|
||||||
const payload = notification.payload;
|
const payload = notification.payload;
|
||||||
|
|
||||||
// If we're filtering by execution ID, only process matching artifacts
|
// If we're filtering by execution ID, only process matching artifacts
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { useEntityNotifications } from "@/contexts/WebSocketContext";
|
import {
|
||||||
|
useEntityNotifications,
|
||||||
|
type Notification,
|
||||||
|
} from "@/contexts/WebSocketContext";
|
||||||
import type { EnforcementSummary } from "@/api";
|
import type { EnforcementSummary } from "@/api";
|
||||||
|
|
||||||
interface UseEnforcementStreamOptions {
|
interface UseEnforcementStreamOptions {
|
||||||
@@ -120,7 +123,8 @@ export function useEnforcementStream(
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const handleNotification = useCallback(
|
const handleNotification = useCallback(
|
||||||
(notification: EnforcementNotification) => {
|
(raw: Notification) => {
|
||||||
|
const notification = raw as unknown as EnforcementNotification;
|
||||||
// Filter by enforcement ID if specified
|
// Filter by enforcement ID if specified
|
||||||
if (enforcementId && notification.entity_id !== enforcementId) {
|
if (enforcementId && notification.entity_id !== enforcementId) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { useEntityNotifications } from "@/contexts/WebSocketContext";
|
import {
|
||||||
import type { ExecutionSummary } from "@/api";
|
useEntityNotifications,
|
||||||
|
type Notification,
|
||||||
|
} from "@/contexts/WebSocketContext";
|
||||||
|
import type { ExecutionSummary, ExecutionStatus } from "@/api";
|
||||||
|
|
||||||
interface UseExecutionStreamOptions {
|
interface UseExecutionStreamOptions {
|
||||||
/**
|
/**
|
||||||
@@ -132,10 +135,8 @@ function executionMatchesParams(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check executor filter (may be present)
|
// Note: executor is not part of ExecutionSummary so we cannot filter on it
|
||||||
if (params.executor !== undefined && execution.executor !== params.executor) {
|
// from WebSocket payloads. Executor-filtered queries rely on API refetch.
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: rule_ref and trigger_ref are NOT checked here because they may not be
|
// Note: rule_ref and trigger_ref are NOT checked here because they may not be
|
||||||
// present in WebSocket payloads (they come from enforcement data which is
|
// present in WebSocket payloads (they come from enforcement data which is
|
||||||
@@ -152,7 +153,7 @@ function hasUnsupportedFilters(
|
|||||||
params: ExecutionQueryParams | undefined,
|
params: ExecutionQueryParams | undefined,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!params) return false;
|
if (!params) return false;
|
||||||
return !!(params.ruleRef || params.triggerRef);
|
return !!(params.ruleRef || params.triggerRef || params.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,21 +176,23 @@ export function useExecutionStream(options: UseExecutionStreamOptions = {}) {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const handleNotification = useCallback(
|
const handleNotification = useCallback(
|
||||||
(notification: ExecutionNotification) => {
|
(notification: Notification) => {
|
||||||
|
const executionNotification =
|
||||||
|
notification as unknown as ExecutionNotification;
|
||||||
// Filter by execution ID if specified
|
// Filter by execution ID if specified
|
||||||
if (executionId && notification.entity_id !== executionId) {
|
if (executionId && executionNotification.entity_id !== executionId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract execution data from notification payload (flat structure).
|
// Extract execution data from notification payload (flat structure).
|
||||||
// Keep raw payload for old_status inspection, but use cleaned data for cache.
|
// Keep raw payload for old_status inspection, but use cleaned data for cache.
|
||||||
const rawPayload = notification.payload;
|
const rawPayload = executionNotification.payload;
|
||||||
const oldStatus: string | undefined = rawPayload?.old_status;
|
const oldStatus: string | undefined = rawPayload?.old_status;
|
||||||
const executionData = stripNotificationMeta(rawPayload);
|
const executionData = stripNotificationMeta(rawPayload);
|
||||||
|
|
||||||
// Update specific execution query if it exists
|
// Update specific execution query if it exists
|
||||||
queryClient.setQueryData(
|
queryClient.setQueryData(
|
||||||
["executions", notification.entity_id],
|
["executions", executionNotification.entity_id],
|
||||||
(old: ExecutionDetailCache | undefined) => {
|
(old: ExecutionDetailCache | undefined) => {
|
||||||
if (!old) return old;
|
if (!old) return old;
|
||||||
return {
|
return {
|
||||||
@@ -223,7 +226,7 @@ export function useExecutionStream(options: UseExecutionStreamOptions = {}) {
|
|||||||
|
|
||||||
// Check if execution already exists in the list
|
// Check if execution already exists in the list
|
||||||
const existingIndex = old.data.findIndex(
|
const existingIndex = old.data.findIndex(
|
||||||
(exec) => exec.id === notification.entity_id,
|
(exec) => exec.id === executionNotification.entity_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Merge the updated fields to determine if the execution matches the query
|
// Merge the updated fields to determine if the execution matches the query
|
||||||
@@ -266,7 +269,7 @@ export function useExecutionStream(options: UseExecutionStreamOptions = {}) {
|
|||||||
// not in our local data array, total_items must stay accurate.
|
// not in our local data array, total_items must stay accurate.
|
||||||
const virtualOldExecution = {
|
const virtualOldExecution = {
|
||||||
...mergedExecution,
|
...mergedExecution,
|
||||||
status: oldStatus,
|
status: oldStatus as ExecutionStatus,
|
||||||
};
|
};
|
||||||
const oldMatchedQuery = executionMatchesParams(
|
const oldMatchedQuery = executionMatchesParams(
|
||||||
virtualOldExecution,
|
virtualOldExecution,
|
||||||
|
|||||||
@@ -551,11 +551,11 @@ function ActionDetail({ actionRef }: { actionRef: string }) {
|
|||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={`px-2 py-1 text-xs rounded ${
|
className={`px-2 py-1 text-xs rounded ${
|
||||||
execution.status === "Completed"
|
execution.status === "completed"
|
||||||
? "bg-green-100 text-green-800"
|
? "bg-green-100 text-green-800"
|
||||||
: execution.status === "Failed"
|
: execution.status === "failed"
|
||||||
? "bg-red-100 text-red-800"
|
? "bg-red-100 text-red-800"
|
||||||
: execution.status === "Running"
|
: execution.status === "running"
|
||||||
? "bg-blue-100 text-blue-800"
|
? "bg-blue-100 text-blue-800"
|
||||||
: "bg-gray-100 text-gray-800"
|
: "bg-gray-100 text-gray-800"
|
||||||
}`}
|
}`}
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ export interface ParamDefinition {
|
|||||||
secret?: boolean;
|
secret?: boolean;
|
||||||
default?: unknown;
|
default?: unknown;
|
||||||
enum?: string[];
|
enum?: string[];
|
||||||
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Workflow definition as stored in the YAML file / API */
|
/** Workflow definition as stored in the YAML file / API */
|
||||||
|
|||||||
Reference in New Issue
Block a user