@stigmer/react 3.5.2 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/AgentPicker.d.ts +10 -1
- package/agent/AgentPicker.d.ts.map +1 -1
- package/agent/AgentPicker.js +2 -2
- package/agent/AgentPicker.js.map +1 -1
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +22 -5
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/ChannelTemplatesDialog.d.ts +53 -0
- package/channel/ChannelTemplatesDialog.d.ts.map +1 -0
- package/channel/ChannelTemplatesDialog.js +150 -0
- package/channel/ChannelTemplatesDialog.js.map +1 -0
- package/channel/index.d.ts +8 -0
- package/channel/index.d.ts.map +1 -1
- package/channel/index.js +4 -0
- package/channel/index.js.map +1 -1
- package/channel/providers.d.ts +12 -0
- package/channel/providers.d.ts.map +1 -1
- package/channel/providers.js +14 -2
- package/channel/providers.js.map +1 -1
- package/channel/templatePresentation.d.ts +37 -0
- package/channel/templatePresentation.d.ts.map +1 -0
- package/channel/templatePresentation.js +69 -0
- package/channel/templatePresentation.js.map +1 -0
- package/channel/useChannelTemplateList.d.ts +64 -0
- package/channel/useChannelTemplateList.d.ts.map +1 -0
- package/channel/useChannelTemplateList.js +69 -0
- package/channel/useChannelTemplateList.js.map +1 -0
- package/channel/useChannelTemplateReadiness.d.ts +53 -0
- package/channel/useChannelTemplateReadiness.d.ts.map +1 -0
- package/channel/useChannelTemplateReadiness.js +42 -0
- package/channel/useChannelTemplateReadiness.js.map +1 -0
- package/dashboard/useDashboardFailedRuns.d.ts.map +1 -1
- package/dashboard/useDashboardFailedRuns.js +2 -0
- package/dashboard/useDashboardFailedRuns.js.map +1 -1
- package/index.d.ts +4 -2
- package/index.d.ts.map +1 -1
- package/index.js +9 -1
- package/index.js.map +1 -1
- package/library/useExportResource.d.ts +4 -3
- package/library/useExportResource.d.ts.map +1 -1
- package/library/useExportResource.js +1 -1
- package/library/useExportResource.js.map +1 -1
- package/organization/OrgProvider.d.ts +11 -4
- package/organization/OrgProvider.d.ts.map +1 -1
- package/organization/OrgProvider.js +28 -4
- package/organization/OrgProvider.js.map +1 -1
- package/package.json +4 -4
- package/resource-detail/useDeleteResource.d.ts +1 -1
- package/resource-detail/useDeleteResource.d.ts.map +1 -1
- package/resource-detail/useDeleteResource.js +5 -0
- package/resource-detail/useDeleteResource.js.map +1 -1
- package/resource-workbench/components/ResourceWorkbench.d.ts +10 -1
- package/resource-workbench/components/ResourceWorkbench.d.ts.map +1 -1
- package/resource-workbench/components/ResourceWorkbench.js +6 -2
- package/resource-workbench/components/ResourceWorkbench.js.map +1 -1
- package/resource-workbench/hooks/useResourceCollection.d.ts +8 -0
- package/resource-workbench/hooks/useResourceCollection.d.ts.map +1 -1
- package/resource-workbench/hooks/useResourceCollection.js +2 -2
- package/resource-workbench/hooks/useResourceCollection.js.map +1 -1
- package/schedule/CadenceField.d.ts +31 -0
- package/schedule/CadenceField.d.ts.map +1 -0
- package/schedule/CadenceField.js +116 -0
- package/schedule/CadenceField.js.map +1 -0
- package/schedule/ScheduleDetailView.d.ts +58 -0
- package/schedule/ScheduleDetailView.d.ts.map +1 -0
- package/schedule/ScheduleDetailView.js +236 -0
- package/schedule/ScheduleDetailView.js.map +1 -0
- package/schedule/ScheduleForm.d.ts +43 -0
- package/schedule/ScheduleForm.d.ts.map +1 -0
- package/schedule/ScheduleForm.js +129 -0
- package/schedule/ScheduleForm.js.map +1 -0
- package/schedule/ScheduleRowActions.d.ts +20 -0
- package/schedule/ScheduleRowActions.d.ts.map +1 -0
- package/schedule/ScheduleRowActions.js +54 -0
- package/schedule/ScheduleRowActions.js.map +1 -0
- package/schedule/TimeZoneField.d.ts +32 -0
- package/schedule/TimeZoneField.d.ts.map +1 -0
- package/schedule/TimeZoneField.js +104 -0
- package/schedule/TimeZoneField.js.map +1 -0
- package/schedule/cadence.d.ts +95 -0
- package/schedule/cadence.d.ts.map +1 -0
- package/schedule/cadence.js +242 -0
- package/schedule/cadence.js.map +1 -0
- package/schedule/index.d.ts +31 -0
- package/schedule/index.d.ts.map +1 -0
- package/schedule/index.js +16 -0
- package/schedule/index.js.map +1 -0
- package/schedule/scheduleColumns.d.ts +26 -0
- package/schedule/scheduleColumns.d.ts.map +1 -0
- package/schedule/scheduleColumns.js +77 -0
- package/schedule/scheduleColumns.js.map +1 -0
- package/schedule/scheduleListFn.d.ts +50 -0
- package/schedule/scheduleListFn.d.ts.map +1 -0
- package/schedule/scheduleListFn.js +65 -0
- package/schedule/scheduleListFn.js.map +1 -0
- package/schedule/scheduleState.d.ts +43 -0
- package/schedule/scheduleState.d.ts.map +1 -0
- package/schedule/scheduleState.js +67 -0
- package/schedule/scheduleState.js.map +1 -0
- package/schedule/useCreateSchedule.d.ts +57 -0
- package/schedule/useCreateSchedule.d.ts.map +1 -0
- package/schedule/useCreateSchedule.js +61 -0
- package/schedule/useCreateSchedule.js.map +1 -0
- package/schedule/useResumeSchedule.d.ts +30 -0
- package/schedule/useResumeSchedule.d.ts.map +1 -0
- package/schedule/useResumeSchedule.js +45 -0
- package/schedule/useResumeSchedule.js.map +1 -0
- package/schedule/useSchedule.d.ts +39 -0
- package/schedule/useSchedule.d.ts.map +1 -0
- package/schedule/useSchedule.js +44 -0
- package/schedule/useSchedule.js.map +1 -0
- package/schedule/useScheduleCount.d.ts +38 -0
- package/schedule/useScheduleCount.d.ts.map +1 -0
- package/schedule/useScheduleCount.js +30 -0
- package/schedule/useScheduleCount.js.map +1 -0
- package/schedule/useScheduleList.d.ts +48 -0
- package/schedule/useScheduleList.d.ts.map +1 -0
- package/schedule/useScheduleList.js +43 -0
- package/schedule/useScheduleList.js.map +1 -0
- package/schedule/useSetScheduleEnabled.d.ts +31 -0
- package/schedule/useSetScheduleEnabled.d.ts.map +1 -0
- package/schedule/useSetScheduleEnabled.js +53 -0
- package/schedule/useSetScheduleEnabled.js.map +1 -0
- package/schedule/useTriggerSchedule.d.ts +28 -0
- package/schedule/useTriggerSchedule.d.ts.map +1 -0
- package/schedule/useTriggerSchedule.js +43 -0
- package/schedule/useTriggerSchedule.js.map +1 -0
- package/search/useResourceCount.d.ts +2 -1
- package/search/useResourceCount.d.ts.map +1 -1
- package/search/useResourceCount.js +6 -1
- package/search/useResourceCount.js.map +1 -1
- package/src/agent/AgentPicker.tsx +13 -1
- package/src/channel/AgentChannelsPanel.tsx +43 -1
- package/src/channel/ChannelTemplatesDialog.tsx +433 -0
- package/src/channel/__tests__/AgentChannelsPanel.test.tsx +73 -0
- package/src/channel/__tests__/ChannelTemplatesDialog.test.tsx +292 -0
- package/src/channel/__tests__/providers.test.ts +9 -0
- package/src/channel/__tests__/templatePresentation.test.ts +96 -0
- package/src/channel/__tests__/useChannelTemplateList.test.tsx +216 -0
- package/src/channel/__tests__/useChannelTemplateReadiness.test.tsx +124 -0
- package/src/channel/index.ts +15 -0
- package/src/channel/providers.ts +26 -2
- package/src/channel/templatePresentation.ts +82 -0
- package/src/channel/useChannelTemplateList.ts +123 -0
- package/src/channel/useChannelTemplateReadiness.ts +69 -0
- package/src/dashboard/__tests__/useDashboardFailedRuns.test.tsx +106 -0
- package/src/dashboard/useDashboardFailedRuns.ts +2 -0
- package/src/execution/__tests__/PlanArtifactCard.test.tsx +23 -2
- package/src/index.ts +65 -0
- package/src/library/useExportResource.ts +4 -3
- package/src/organization/OrgProvider.tsx +29 -4
- package/src/organization/__tests__/OrgProvider.orgSwitch.test.tsx +89 -0
- package/src/resource-detail/useDeleteResource.ts +11 -1
- package/src/resource-workbench/__tests__/ResourceWorkbench.test.tsx +112 -0
- package/src/resource-workbench/components/ResourceWorkbench.tsx +32 -15
- package/src/resource-workbench/hooks/useResourceCollection.ts +11 -1
- package/src/schedule/CadenceField.tsx +365 -0
- package/src/schedule/ScheduleDetailView.tsx +583 -0
- package/src/schedule/ScheduleForm.tsx +405 -0
- package/src/schedule/ScheduleRowActions.tsx +124 -0
- package/src/schedule/TimeZoneField.tsx +199 -0
- package/src/schedule/__tests__/ScheduleDetailView.test.tsx +260 -0
- package/src/schedule/__tests__/cadence.test.ts +278 -0
- package/src/schedule/__tests__/scheduleColumnsRowActions.test.tsx +176 -0
- package/src/schedule/__tests__/scheduleCreation.test.tsx +340 -0
- package/src/schedule/__tests__/scheduleHooks.test.tsx +312 -0
- package/src/schedule/__tests__/scheduleListFn.test.ts +128 -0
- package/src/schedule/__tests__/scheduleState.test.ts +133 -0
- package/src/schedule/cadence.ts +298 -0
- package/src/schedule/index.ts +57 -0
- package/src/schedule/scheduleColumns.tsx +118 -0
- package/src/schedule/scheduleListFn.ts +108 -0
- package/src/schedule/scheduleState.ts +96 -0
- package/src/schedule/useCreateSchedule.ts +88 -0
- package/src/schedule/useResumeSchedule.ts +67 -0
- package/src/schedule/useSchedule.ts +67 -0
- package/src/schedule/useScheduleCount.ts +57 -0
- package/src/schedule/useScheduleList.ts +83 -0
- package/src/schedule/useSetScheduleEnabled.ts +84 -0
- package/src/schedule/useTriggerSchedule.ts +65 -0
- package/src/search/__tests__/useResourceCount.test.tsx +89 -0
- package/src/search/useResourceCount.ts +8 -2
- package/src/workflow/WorkflowDashboard.tsx +1 -0
- package/src/workflow/useWorkflowExecutionList.ts +13 -2
- package/styles.css +1 -1
- package/workflow/CanvasTransitionEdge.d.ts +1 -1
- package/workflow/WorkflowDashboard.d.ts.map +1 -1
- package/workflow/WorkflowDashboard.js +1 -0
- package/workflow/WorkflowDashboard.js.map +1 -1
- package/workflow/useWorkflowExecutionList.d.ts +10 -0
- package/workflow/useWorkflowExecutionList.d.ts.map +1 -1
- package/workflow/useWorkflowExecutionList.js +3 -2
- package/workflow/useWorkflowExecutionList.js.map +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { clone } from "@bufbuild/protobuf";
|
|
5
|
+
import {
|
|
6
|
+
ScheduleSchema,
|
|
7
|
+
type Schedule,
|
|
8
|
+
} from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
9
|
+
import { getUserMessage, manifestDocumentForResource } from "@stigmer/sdk";
|
|
10
|
+
import { useStigmer } from "../hooks.js";
|
|
11
|
+
import { toast } from "../feedback/toast.js";
|
|
12
|
+
import { toError } from "../internal/toError.js";
|
|
13
|
+
|
|
14
|
+
/** Return value of {@link useSetScheduleEnabled}. */
|
|
15
|
+
export interface UseSetScheduleEnabledReturn {
|
|
16
|
+
/**
|
|
17
|
+
* Flip the owner's `spec.enabled` switch. Takes the full fetched
|
|
18
|
+
* schedule (not just an id) because the write re-applies the whole
|
|
19
|
+
* resource. Resolves with the post-apply schedule; the caller
|
|
20
|
+
* refetches or replaces its local copy from it.
|
|
21
|
+
*/
|
|
22
|
+
readonly setEnabled: (schedule: Schedule, enabled: boolean) => Promise<Schedule>;
|
|
23
|
+
/** `true` while the apply is in flight. */
|
|
24
|
+
readonly isPending: boolean;
|
|
25
|
+
/** Error from the last failed apply, or `null` when healthy. */
|
|
26
|
+
readonly error: Error | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Behavior hook that flips a schedule's owner-controlled `enabled` flag.
|
|
31
|
+
*
|
|
32
|
+
* The write path is deliberate: clone the fetched proto, flip one
|
|
33
|
+
* field, and re-apply the WHOLE resource through the manifest engine
|
|
34
|
+
* (`stigmer.manifest.apply`) — never down-convert to the curated
|
|
35
|
+
* `ScheduleInput` shape. The server replaces spec and mutable metadata
|
|
36
|
+
* wholesale on update, and `ScheduleInput` cannot express every
|
|
37
|
+
* metadata field (tags, description), so the input route would silently
|
|
38
|
+
* wipe them. The full-proto route is lossless by construction; the
|
|
39
|
+
* server ignores client-provided status, and re-applying never clears a
|
|
40
|
+
* platform pause (Resume is the one clearing path — see
|
|
41
|
+
* {@link useResumeSchedule}).
|
|
42
|
+
*/
|
|
43
|
+
export function useSetScheduleEnabled(): UseSetScheduleEnabledReturn {
|
|
44
|
+
const stigmer = useStigmer();
|
|
45
|
+
const [isPending, setIsPending] = useState(false);
|
|
46
|
+
const [error, setError] = useState<Error | null>(null);
|
|
47
|
+
|
|
48
|
+
const setEnabled = useCallback(
|
|
49
|
+
async (schedule: Schedule, enabled: boolean): Promise<Schedule> => {
|
|
50
|
+
if (!schedule.spec) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
"Cannot toggle this schedule: it has no spec. Pass a schedule " +
|
|
53
|
+
"as returned by the server (get/getByReference).",
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setIsPending(true);
|
|
58
|
+
setError(null);
|
|
59
|
+
try {
|
|
60
|
+
const updated = clone(ScheduleSchema, schedule);
|
|
61
|
+
updated.spec!.enabled = enabled;
|
|
62
|
+
|
|
63
|
+
const applied = await stigmer.manifest.apply(
|
|
64
|
+
manifestDocumentForResource(updated),
|
|
65
|
+
);
|
|
66
|
+
toast.success(enabled ? "Schedule enabled" : "Schedule disabled");
|
|
67
|
+
return applied.message as Schedule;
|
|
68
|
+
} catch (err) {
|
|
69
|
+
const wrapped = toError(err);
|
|
70
|
+
setError(wrapped);
|
|
71
|
+
toast.error(getUserMessage(err));
|
|
72
|
+
throw wrapped;
|
|
73
|
+
} finally {
|
|
74
|
+
setIsPending(false);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
[stigmer],
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return useMemo(
|
|
81
|
+
() => ({ setEnabled, isPending, error }),
|
|
82
|
+
[setEnabled, isPending, error],
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
5
|
+
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import { useStigmer } from "../hooks.js";
|
|
7
|
+
import { toast } from "../feedback/toast.js";
|
|
8
|
+
import { toError } from "../internal/toError.js";
|
|
9
|
+
|
|
10
|
+
/** Return value of {@link useTriggerSchedule}. */
|
|
11
|
+
export interface UseTriggerScheduleReturn {
|
|
12
|
+
/**
|
|
13
|
+
* Fire the schedule once, now — a real agent execution, outside the
|
|
14
|
+
* cron cadence. Resolves with the post-trigger schedule; refetch to
|
|
15
|
+
* pick up the new `status.last_execution_id`.
|
|
16
|
+
*/
|
|
17
|
+
readonly triggerSchedule: (scheduleId: string) => Promise<Schedule>;
|
|
18
|
+
/** `true` while the trigger request is in flight. */
|
|
19
|
+
readonly isTriggering: boolean;
|
|
20
|
+
/** Error from the last failed or refused trigger, or `null` when healthy. */
|
|
21
|
+
readonly error: Error | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Behavior hook that fires a schedule once, immediately.
|
|
26
|
+
*
|
|
27
|
+
* The server enforces a refusal matrix — a disabled schedule refuses
|
|
28
|
+
* first, then a paused one — both as `FAILED_PRECONDITION` with copy
|
|
29
|
+
* that names the remedy ("enable it before triggering" / "resume it
|
|
30
|
+
* before triggering"). Error toasts relay that copy verbatim; the copy
|
|
31
|
+
* is byte-identical across editions.
|
|
32
|
+
*
|
|
33
|
+
* Triggering starts a real, billable execution — gate the call behind a
|
|
34
|
+
* confirmation (the detail view uses `ConfirmDialog`).
|
|
35
|
+
*/
|
|
36
|
+
export function useTriggerSchedule(): UseTriggerScheduleReturn {
|
|
37
|
+
const stigmer = useStigmer();
|
|
38
|
+
const [isTriggering, setIsTriggering] = useState(false);
|
|
39
|
+
const [error, setError] = useState<Error | null>(null);
|
|
40
|
+
|
|
41
|
+
const triggerSchedule = useCallback(
|
|
42
|
+
async (scheduleId: string): Promise<Schedule> => {
|
|
43
|
+
setIsTriggering(true);
|
|
44
|
+
setError(null);
|
|
45
|
+
try {
|
|
46
|
+
const triggered = await stigmer.schedule.trigger(scheduleId);
|
|
47
|
+
toast.success("Run started");
|
|
48
|
+
return triggered;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
const wrapped = toError(err);
|
|
51
|
+
setError(wrapped);
|
|
52
|
+
toast.error(getUserMessage(err));
|
|
53
|
+
throw wrapped;
|
|
54
|
+
} finally {
|
|
55
|
+
setIsTriggering(false);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
[stigmer],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return useMemo(
|
|
62
|
+
() => ({ triggerSchedule, isTriggering, error }),
|
|
63
|
+
[triggerSchedule, isTriggering, error],
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
3
|
+
import type { ListParams, ListResult } from "@stigmer/sdk";
|
|
4
|
+
import { useResourceCount } from "../useResourceCount";
|
|
5
|
+
|
|
6
|
+
function mockListFn(totalCount = 0) {
|
|
7
|
+
return vi.fn<(params: ListParams) => Promise<ListResult>>().mockResolvedValue({
|
|
8
|
+
entries: [],
|
|
9
|
+
totalCount,
|
|
10
|
+
totalPages: totalCount > 0 ? 1 : 0,
|
|
11
|
+
} as never);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe("useResourceCount", () => {
|
|
15
|
+
it("counts in org scope by default: org sent, crossOrgPublic false", async () => {
|
|
16
|
+
const listFn = mockListFn(7);
|
|
17
|
+
|
|
18
|
+
const { result } = renderHook(() => useResourceCount(listFn, "acme"));
|
|
19
|
+
|
|
20
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
21
|
+
|
|
22
|
+
expect(result.current.count).toBe(7);
|
|
23
|
+
const params = listFn.mock.calls[0][0];
|
|
24
|
+
expect(params.org).toBe("acme");
|
|
25
|
+
expect(params.crossOrgPublic).toBe(false);
|
|
26
|
+
expect(params.page).toEqual({ num: 1, size: 1 });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('always sends org in "all" scope (empty org means a cross-org FGA dump to the backend)', async () => {
|
|
30
|
+
const listFn = mockListFn(3);
|
|
31
|
+
|
|
32
|
+
const { result } = renderHook(() =>
|
|
33
|
+
useResourceCount(listFn, "acme", { scope: "all" }),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
37
|
+
|
|
38
|
+
const params = listFn.mock.calls[0][0];
|
|
39
|
+
// Regression guard: the pre-fix hook blanked org for "all", which the
|
|
40
|
+
// search backend defines as "every org the caller can access" — the
|
|
41
|
+
// Library cards then counted platform-wide instead of org + public.
|
|
42
|
+
expect(params.org).toBe("acme");
|
|
43
|
+
expect(params.crossOrgPublic).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("does not fetch when org is null", async () => {
|
|
47
|
+
const listFn = mockListFn();
|
|
48
|
+
|
|
49
|
+
const { result } = renderHook(() => useResourceCount(listFn, null));
|
|
50
|
+
|
|
51
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
52
|
+
|
|
53
|
+
expect(listFn).not.toHaveBeenCalled();
|
|
54
|
+
expect(result.current.count).toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("recounts when refetchToken changes", async () => {
|
|
58
|
+
const listFn = mockListFn(1);
|
|
59
|
+
|
|
60
|
+
const { result, rerender } = renderHook(
|
|
61
|
+
({ token }: { token: number }) =>
|
|
62
|
+
useResourceCount(listFn, "acme", { refetchToken: token }),
|
|
63
|
+
{ initialProps: { token: 0 } },
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
67
|
+
expect(listFn).toHaveBeenCalledTimes(1);
|
|
68
|
+
|
|
69
|
+
rerender({ token: 1 });
|
|
70
|
+
|
|
71
|
+
await waitFor(() => expect(listFn).toHaveBeenCalledTimes(2));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("refetches with the new org when the org changes", async () => {
|
|
75
|
+
const listFn = mockListFn(2);
|
|
76
|
+
|
|
77
|
+
const { result, rerender } = renderHook(
|
|
78
|
+
({ org }: { org: string }) => useResourceCount(listFn, org),
|
|
79
|
+
{ initialProps: { org: "acme" } },
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
83
|
+
|
|
84
|
+
rerender({ org: "globex" });
|
|
85
|
+
|
|
86
|
+
await waitFor(() => expect(listFn).toHaveBeenCalledTimes(2));
|
|
87
|
+
expect(listFn.mock.calls[1][0].org).toBe("globex");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -11,7 +11,8 @@ export interface UseResourceCountOptions {
|
|
|
11
11
|
* Controls resource visibility scope.
|
|
12
12
|
*
|
|
13
13
|
* - `"org"` — all resources owned by the given organization, regardless of visibility.
|
|
14
|
-
* - `"all"` — all resources
|
|
14
|
+
* - `"all"` — all resources owned by the given organization plus public resources
|
|
15
|
+
* from other organizations.
|
|
15
16
|
*
|
|
16
17
|
* @default "org"
|
|
17
18
|
*/
|
|
@@ -64,10 +65,15 @@ export function useResourceCount(
|
|
|
64
65
|
const { data: count, isLoading, isRefetching, error, refetch } = useFetch<number | undefined>(
|
|
65
66
|
org
|
|
66
67
|
? async () => {
|
|
68
|
+
// Identical params to useResourceList so a card's count always matches
|
|
69
|
+
// the list page it links to. `org` is ALWAYS sent: an empty org means
|
|
70
|
+
// "every org the caller can access" to the search backend (a global FGA
|
|
71
|
+
// dump), and `crossOrgPublic` with an empty org matches zero rows.
|
|
67
72
|
const params: ListParams = {
|
|
68
|
-
org
|
|
73
|
+
org,
|
|
69
74
|
query: query || undefined,
|
|
70
75
|
excludePublic: false,
|
|
76
|
+
crossOrgPublic: scope === "all",
|
|
71
77
|
page: { num: 1, size: 1 },
|
|
72
78
|
};
|
|
73
79
|
const result = await listFn(params);
|
|
@@ -37,6 +37,16 @@ export interface UseWorkflowExecutionListOptions {
|
|
|
37
37
|
* When omitted, lists all executions across all workflows.
|
|
38
38
|
*/
|
|
39
39
|
readonly workflowId?: string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Organization slug to scope the cross-workflow listing to. Applies only
|
|
42
|
+
* to the `list()` branch (no `workflowId`); ignored by `listByWorkflow()`,
|
|
43
|
+
* which is already scoped by the workflow itself.
|
|
44
|
+
*
|
|
45
|
+
* When omitted, results are bounded only by the caller's view permissions —
|
|
46
|
+
* for a member of several organizations that spans all of them. Console
|
|
47
|
+
* pages should always pass the active org.
|
|
48
|
+
*/
|
|
49
|
+
readonly org?: string | null;
|
|
40
50
|
/**
|
|
41
51
|
* Server-side filter criteria. When set, the backend filters
|
|
42
52
|
* before returning results, reducing transfer size.
|
|
@@ -110,6 +120,7 @@ export function useWorkflowExecutionList(
|
|
|
110
120
|
const pageSize = options?.pageSize ?? 20;
|
|
111
121
|
const pageToken = options?.pageToken ?? "";
|
|
112
122
|
const workflowId = options?.workflowId ?? null;
|
|
123
|
+
const org = options?.org ?? "";
|
|
113
124
|
const fetchFn = async () => {
|
|
114
125
|
if (workflowId) {
|
|
115
126
|
const resp = await stigmer.workflowExecution.listByWorkflow(
|
|
@@ -122,7 +133,7 @@ export function useWorkflowExecutionList(
|
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
const resp = await stigmer.workflowExecution.list(
|
|
125
|
-
create(ListWorkflowExecutionsRequestSchema, { pageSize, pageToken }),
|
|
136
|
+
create(ListWorkflowExecutionsRequestSchema, { pageSize, pageToken, org }),
|
|
126
137
|
);
|
|
127
138
|
return {
|
|
128
139
|
executions: [...resp.entries],
|
|
@@ -138,7 +149,7 @@ export function useWorkflowExecutionList(
|
|
|
138
149
|
refetch,
|
|
139
150
|
} = useFetch<ExecutionListData>(
|
|
140
151
|
fetchFn,
|
|
141
|
-
[stigmer, workflowId, pageSize, pageToken],
|
|
152
|
+
[stigmer, workflowId, org, pageSize, pageToken],
|
|
142
153
|
INITIAL_DATA,
|
|
143
154
|
);
|
|
144
155
|
|