@stigmer/react 3.0.6 → 3.0.7
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-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.js +2 -9
- package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
- package/agent-instance/AgentInstanceList.d.ts.map +1 -1
- package/agent-instance/AgentInstanceList.js +2 -9
- package/agent-instance/AgentInstanceList.js.map +1 -1
- package/agent-instance/CreateAgentInstanceDialog.d.ts.map +1 -1
- package/agent-instance/CreateAgentInstanceDialog.js +1 -1
- package/agent-instance/CreateAgentInstanceDialog.js.map +1 -1
- package/composer/SessionComposer.d.ts +14 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +15 -9
- package/composer/SessionComposer.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/library/InstanceVisibilitySelector.d.ts +23 -9
- package/library/InstanceVisibilitySelector.d.ts.map +1 -1
- package/library/InstanceVisibilitySelector.js +14 -9
- package/library/InstanceVisibilitySelector.js.map +1 -1
- package/library/VisibilityOptionRow.d.ts +52 -0
- package/library/VisibilityOptionRow.d.ts.map +1 -0
- package/library/VisibilityOptionRow.js +92 -0
- package/library/VisibilityOptionRow.js.map +1 -0
- package/library/VisibilitySelector.d.ts +47 -24
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +137 -115
- package/library/VisibilitySelector.js.map +1 -1
- package/library/visibilityLevels.d.ts +25 -3
- package/library/visibilityLevels.d.ts.map +1 -1
- package/library/visibilityLevels.js +8 -2
- package/library/visibilityLevels.js.map +1 -1
- package/package.json +4 -4
- package/session/NewSessionViewer.d.ts +32 -1
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +20 -9
- package/session/NewSessionViewer.js.map +1 -1
- package/session/SessionViewer.d.ts +24 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +18 -12
- package/session/SessionViewer.js.map +1 -1
- package/session/audience.d.ts +21 -0
- package/session/audience.d.ts.map +1 -0
- package/session/audience.js +2 -0
- package/session/audience.js.map +1 -0
- package/session/index.d.ts +2 -0
- package/session/index.d.ts.map +1 -1
- package/session/index.js.map +1 -1
- package/session/runtime-env.d.ts +47 -0
- package/session/runtime-env.d.ts.map +1 -0
- package/session/runtime-env.js +20 -0
- package/session/runtime-env.js.map +1 -0
- package/session/useNewSessionFlow.d.ts +25 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +20 -8
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionPageFlow.d.ts +27 -2
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +34 -13
- package/session/useSessionPageFlow.js.map +1 -1
- package/src/agent-instance/AgentInstanceDetailPanel.tsx +7 -27
- package/src/agent-instance/AgentInstanceList.tsx +7 -27
- package/src/agent-instance/CreateAgentInstanceDialog.tsx +1 -0
- package/src/composer/SessionComposer.tsx +30 -8
- package/src/composer/__tests__/SessionComposer-lockAgent.test.tsx +150 -0
- package/src/index.ts +2 -0
- package/src/library/InstanceVisibilitySelector.tsx +27 -9
- package/src/library/VisibilityOptionRow.tsx +244 -0
- package/src/library/VisibilitySelector.tsx +303 -260
- package/src/library/__tests__/VisibilitySelector.test.tsx +256 -0
- package/src/library/visibilityLevels.ts +35 -5
- package/src/session/NewSessionViewer.tsx +61 -12
- package/src/session/SessionViewer.tsx +51 -15
- package/src/session/__tests__/audienceWiring.test.tsx +274 -0
- package/src/session/__tests__/useNewSessionFlow.test.tsx +122 -0
- package/src/session/__tests__/useSessionPageFlow.runtimeEnv.test.tsx +170 -0
- package/src/session/audience.ts +20 -0
- package/src/session/index.ts +3 -0
- package/src/session/runtime-env.ts +57 -0
- package/src/session/useNewSessionFlow.ts +44 -9
- package/src/session/useSessionPageFlow.ts +65 -17
- package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +1 -0
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +7 -27
- package/src/workflow/instance/WorkflowInstanceList.tsx +7 -27
- package/styles.css +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.d.ts.map +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.js +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -9
- package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
- package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceList.js +2 -9
- package/workflow/instance/WorkflowInstanceList.js.map +1 -1
|
@@ -16,6 +16,7 @@ import { useCreateAgentExecution } from "../execution/useCreateAgentExecution";
|
|
|
16
16
|
import type { ExecutionTargetOption } from "./execution-target";
|
|
17
17
|
import { useExecutionTarget } from "../execution-target-context";
|
|
18
18
|
import { useRunnerAdapter } from "../runner-adapter";
|
|
19
|
+
import { resolveExecutionRuntimeEnv, type RuntimeEnvProvider } from "./runtime-env";
|
|
19
20
|
|
|
20
21
|
const DEFAULT_AGENT_TIMEOUT_MS = 10_000;
|
|
21
22
|
|
|
@@ -55,6 +56,30 @@ export interface UseNewSessionFlowOptions {
|
|
|
55
56
|
* server decides based on deployment context.
|
|
56
57
|
*/
|
|
57
58
|
readonly executionTarget?: ExecutionTargetOption;
|
|
59
|
+
/**
|
|
60
|
+
* Supplies host-app environment variables for the session's first
|
|
61
|
+
* execution. Evaluated once per submission, at submit time, so
|
|
62
|
+
* short-lived credentials stay fresh; evaluated **before** the session
|
|
63
|
+
* is created so a credential failure never strands an empty session.
|
|
64
|
+
*
|
|
65
|
+
* Host values win over composer-collected env on key collisions. If
|
|
66
|
+
* the provider throws, the submission fails and the error surfaces
|
|
67
|
+
* via {@link UseNewSessionFlowReturn.submitError} / {@link onError}.
|
|
68
|
+
* See {@link RuntimeEnvProvider}.
|
|
69
|
+
*/
|
|
70
|
+
readonly getRuntimeEnv?: RuntimeEnvProvider;
|
|
71
|
+
/**
|
|
72
|
+
* Harness pre-selected for new sessions when the user has not made an
|
|
73
|
+
* explicit choice yet (e.g. an embedder whose agents primarily run
|
|
74
|
+
* coding tasks defaults to `"cursor"`).
|
|
75
|
+
*
|
|
76
|
+
* Read once on mount. The user's own selection — persisted to
|
|
77
|
+
* localStorage on explicit change — always takes precedence on
|
|
78
|
+
* subsequent visits.
|
|
79
|
+
*
|
|
80
|
+
* @default DEFAULT_HARNESS ("native")
|
|
81
|
+
*/
|
|
82
|
+
readonly defaultHarness?: HarnessOption;
|
|
58
83
|
}
|
|
59
84
|
|
|
60
85
|
/** Return value of {@link useNewSessionFlow}. */
|
|
@@ -158,15 +183,18 @@ export interface UseNewSessionFlowReturn {
|
|
|
158
183
|
export function useNewSessionFlow(
|
|
159
184
|
options: UseNewSessionFlowOptions,
|
|
160
185
|
): UseNewSessionFlowReturn {
|
|
161
|
-
const { org, onSessionCreated, onError } = options;
|
|
186
|
+
const { org, onSessionCreated, onError, getRuntimeEnv, defaultHarness } = options;
|
|
162
187
|
const contextTarget = useExecutionTarget();
|
|
163
188
|
const executionTarget = options.executionTarget ?? contextTarget;
|
|
164
189
|
const adapter = useRunnerAdapter();
|
|
165
190
|
|
|
166
191
|
const [harness, setHarnessRaw] = useState<HarnessOption>(() => {
|
|
167
|
-
if (typeof window === "undefined") return DEFAULT_HARNESS;
|
|
192
|
+
if (typeof window === "undefined") return defaultHarness ?? DEFAULT_HARNESS;
|
|
193
|
+
// Only explicit user choices are persisted (see setHarness), so a
|
|
194
|
+
// stored value always outranks the embedder's defaultHarness.
|
|
168
195
|
const stored = localStorage.getItem(STORAGE_KEY_HARNESS);
|
|
169
|
-
|
|
196
|
+
if (stored === "native" || stored === "cursor") return stored;
|
|
197
|
+
return defaultHarness ?? DEFAULT_HARNESS;
|
|
170
198
|
});
|
|
171
199
|
|
|
172
200
|
const { getModel, isLoading: isModelsLoading } = useModelRegistry({ harness });
|
|
@@ -191,14 +219,12 @@ export function useNewSessionFlow(
|
|
|
191
219
|
|
|
192
220
|
const validModelId = modelId && getModel(modelId) ? modelId : undefined;
|
|
193
221
|
|
|
194
|
-
// Persist harness on change
|
|
195
|
-
useEffect(() => {
|
|
196
|
-
localStorage.setItem(STORAGE_KEY_HARNESS, harness);
|
|
197
|
-
}, [harness]);
|
|
198
|
-
|
|
199
222
|
const setHarness = useCallback(
|
|
200
223
|
(h: HarnessOption) => {
|
|
201
224
|
setHarnessRaw(h);
|
|
225
|
+
// Persist only explicit choices — never the seeded value — so the
|
|
226
|
+
// embedder's defaultHarness keeps applying until the user decides.
|
|
227
|
+
localStorage.setItem(STORAGE_KEY_HARNESS, h);
|
|
202
228
|
const storedModel = localStorage.getItem(modelStorageKey(h));
|
|
203
229
|
const plain = storedModel ? (parseModelKey(storedModel)?.modelId ?? storedModel) : undefined;
|
|
204
230
|
setModelId(plain);
|
|
@@ -246,6 +272,14 @@ export function useNewSessionFlow(
|
|
|
246
272
|
setSubmitError(null);
|
|
247
273
|
|
|
248
274
|
try {
|
|
275
|
+
// Host env is evaluated per submission (short-lived credentials)
|
|
276
|
+
// and before session creation, so a credential failure can never
|
|
277
|
+
// strand an empty session. Without a provider the composer env
|
|
278
|
+
// passes through untouched — no extra await on the hot path.
|
|
279
|
+
const runtimeEnv = getRuntimeEnv
|
|
280
|
+
? await resolveExecutionRuntimeEnv(getRuntimeEnv, context?.runtimeEnv)
|
|
281
|
+
: context?.runtimeEnv;
|
|
282
|
+
|
|
249
283
|
const sessionFields = {
|
|
250
284
|
org,
|
|
251
285
|
workspaceEntries: workspace.hasEntries
|
|
@@ -261,7 +295,7 @@ export function useNewSessionFlow(
|
|
|
261
295
|
org,
|
|
262
296
|
message,
|
|
263
297
|
modelName: selectedModel ?? validModelId,
|
|
264
|
-
runtimeEnv
|
|
298
|
+
runtimeEnv,
|
|
265
299
|
attachments: context?.attachments,
|
|
266
300
|
interactionMode: context?.interactionMode,
|
|
267
301
|
workspaceFileRefs: context?.workspaceFileRefs,
|
|
@@ -344,6 +378,7 @@ export function useNewSessionFlow(
|
|
|
344
378
|
harness,
|
|
345
379
|
executionTarget,
|
|
346
380
|
adapter,
|
|
381
|
+
getRuntimeEnv,
|
|
347
382
|
validModelId,
|
|
348
383
|
workspace,
|
|
349
384
|
mcpServerUsages,
|
|
@@ -14,6 +14,7 @@ import { fromProtoHarness, type HarnessOption } from "../models/harness";
|
|
|
14
14
|
import { Harness, ExecutionTarget } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
|
|
15
15
|
import { fromProtoExecutionTarget, type ExecutionTargetOption } from "./execution-target";
|
|
16
16
|
import { useSessionConversation, type UseSessionConversationReturn } from "./useSessionConversation";
|
|
17
|
+
import { resolveExecutionRuntimeEnv, type RuntimeEnvProvider } from "./runtime-env";
|
|
17
18
|
import { useAgentRefFromSession } from "./useAgentRefFromSession";
|
|
18
19
|
import { usePersistedModel, type UsePersistedModelReturn } from "./usePersistedModel";
|
|
19
20
|
import { specMcpUsagesToInput, specSkillRefsToInput } from "./session-spec-converters";
|
|
@@ -30,6 +31,18 @@ export interface UseSessionPageFlowOptions {
|
|
|
30
31
|
readonly sessionId: string;
|
|
31
32
|
/** Organization slug. */
|
|
32
33
|
readonly org: string;
|
|
34
|
+
/**
|
|
35
|
+
* Supplies host-app environment variables for every follow-up
|
|
36
|
+
* execution. Evaluated once per follow-up, at send time, so
|
|
37
|
+
* short-lived credentials stay fresh.
|
|
38
|
+
*
|
|
39
|
+
* Host values win over composer-collected env on key collisions. If
|
|
40
|
+
* the provider throws, the follow-up is aborted before any optimistic
|
|
41
|
+
* UI or session mutation and the error surfaces via
|
|
42
|
+
* {@link UseSessionPageFlowReturn.submitError}. See
|
|
43
|
+
* {@link RuntimeEnvProvider}.
|
|
44
|
+
*/
|
|
45
|
+
readonly getRuntimeEnv?: RuntimeEnvProvider;
|
|
33
46
|
}
|
|
34
47
|
|
|
35
48
|
/** Return value of {@link useSessionPageFlow}. */
|
|
@@ -128,8 +141,10 @@ export interface UseSessionPageFlowReturn {
|
|
|
128
141
|
|
|
129
142
|
/**
|
|
130
143
|
* Submit a follow-up message. Handles agent override resolution
|
|
131
|
-
* (if the user changed the agent mid-session)
|
|
132
|
-
* `conv.sendFollowUp` with
|
|
144
|
+
* (if the user changed the agent mid-session), evaluates the host
|
|
145
|
+
* runtime-env provider, and delegates to `conv.sendFollowUp` with
|
|
146
|
+
* all managed state. Never rejects — pre-send failures land in
|
|
147
|
+
* {@link submitError}.
|
|
133
148
|
*/
|
|
134
149
|
readonly handleSubmit: (
|
|
135
150
|
message: string,
|
|
@@ -137,6 +152,17 @@ export interface UseSessionPageFlowReturn {
|
|
|
137
152
|
context?: SessionComposerSubmitContext,
|
|
138
153
|
) => Promise<void>;
|
|
139
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Error from the most recent follow-up's pre-send work (agent
|
|
157
|
+
* override resolution, host runtime-env evaluation), or `null`.
|
|
158
|
+
*
|
|
159
|
+
* Distinct from `conv.sendError`, which covers the create-execution
|
|
160
|
+
* RPC itself. Kept as the raw `Error` so consumers can render
|
|
161
|
+
* contextual guidance (e.g. secret-flow errors). Cleared at the
|
|
162
|
+
* start of each submission.
|
|
163
|
+
*/
|
|
164
|
+
readonly submitError: Error | null;
|
|
165
|
+
|
|
140
166
|
/**
|
|
141
167
|
* The most relevant execution for sidebar display — the active
|
|
142
168
|
* streaming execution, or the last completed one.
|
|
@@ -199,7 +225,7 @@ export interface UseSessionPageFlowReturn {
|
|
|
199
225
|
export function useSessionPageFlow(
|
|
200
226
|
options: UseSessionPageFlowOptions,
|
|
201
227
|
): UseSessionPageFlowReturn {
|
|
202
|
-
const { sessionId, org } = options;
|
|
228
|
+
const { sessionId, org, getRuntimeEnv } = options;
|
|
203
229
|
|
|
204
230
|
const stigmer = useStigmer();
|
|
205
231
|
const conv = useSessionConversation(sessionId, org);
|
|
@@ -324,27 +350,48 @@ export function useSessionPageFlow(
|
|
|
324
350
|
// Follow-up submission with agent override
|
|
325
351
|
// -------------------------------------------------------------------------
|
|
326
352
|
|
|
353
|
+
const [submitError, setSubmitError] = useState<Error | null>(null);
|
|
354
|
+
|
|
327
355
|
const handleSubmit = useCallback(
|
|
328
356
|
async (
|
|
329
357
|
message: string,
|
|
330
358
|
selectedModel?: string,
|
|
331
359
|
context?: SessionComposerSubmitContext,
|
|
332
360
|
) => {
|
|
333
|
-
|
|
361
|
+
setSubmitError(null);
|
|
334
362
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
363
|
+
// Pre-send work runs before conv.sendFollowUp so a failure here
|
|
364
|
+
// aborts cleanly: no optimistic pending message, no session
|
|
365
|
+
// mutation. The composer fires this handler without awaiting it,
|
|
366
|
+
// so a rejection would otherwise be an unhandled rejection —
|
|
367
|
+
// failures must land in submitError instead.
|
|
368
|
+
let agentInstanceIdOverride: string | undefined;
|
|
369
|
+
let runtimeEnv: SessionComposerSubmitContext["runtimeEnv"];
|
|
370
|
+
|
|
371
|
+
try {
|
|
372
|
+
if (resolution) {
|
|
373
|
+
if (
|
|
374
|
+
resolution.mode === "saved" &&
|
|
375
|
+
resolution.instanceId !== sessionInstanceId
|
|
376
|
+
) {
|
|
377
|
+
agentInstanceIdOverride = resolution.instanceId;
|
|
378
|
+
} else if (resolution.mode === "direct" && agentRef) {
|
|
379
|
+
const agent = await stigmer.agent.getByReference(agentRef);
|
|
380
|
+
const defaultId = agent.status?.defaultInstanceId;
|
|
381
|
+
if (defaultId && defaultId !== sessionInstanceId) {
|
|
382
|
+
agentInstanceIdOverride = defaultId;
|
|
383
|
+
}
|
|
346
384
|
}
|
|
347
385
|
}
|
|
386
|
+
|
|
387
|
+
// Evaluated per follow-up so short-lived host credentials are
|
|
388
|
+
// current; host values win over composer-collected env.
|
|
389
|
+
runtimeEnv = getRuntimeEnv
|
|
390
|
+
? await resolveExecutionRuntimeEnv(getRuntimeEnv, context?.runtimeEnv)
|
|
391
|
+
: context?.runtimeEnv;
|
|
392
|
+
} catch (err) {
|
|
393
|
+
setSubmitError(err instanceof Error ? err : new Error(String(err)));
|
|
394
|
+
return;
|
|
348
395
|
}
|
|
349
396
|
|
|
350
397
|
conv.sendFollowUp(message, {
|
|
@@ -355,7 +402,7 @@ export function useSessionPageFlow(
|
|
|
355
402
|
: undefined,
|
|
356
403
|
mcpServerUsages: mcpServerUsages.length > 0 ? mcpServerUsages : undefined,
|
|
357
404
|
skillRefs: skillRefs.length > 0 ? skillRefs : undefined,
|
|
358
|
-
runtimeEnv
|
|
405
|
+
runtimeEnv,
|
|
359
406
|
attachments: context?.attachments,
|
|
360
407
|
interactionMode: context?.interactionMode,
|
|
361
408
|
// Sourced from the session-scoped preference set at the approval gate,
|
|
@@ -366,7 +413,7 @@ export function useSessionPageFlow(
|
|
|
366
413
|
|
|
367
414
|
sessionVariables.clear();
|
|
368
415
|
},
|
|
369
|
-
[conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll],
|
|
416
|
+
[conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll, getRuntimeEnv],
|
|
370
417
|
);
|
|
371
418
|
|
|
372
419
|
// -------------------------------------------------------------------------
|
|
@@ -416,6 +463,7 @@ export function useSessionPageFlow(
|
|
|
416
463
|
setAutoApproveAll,
|
|
417
464
|
submitApproval,
|
|
418
465
|
handleSubmit,
|
|
466
|
+
submitError,
|
|
419
467
|
displayExecution,
|
|
420
468
|
allExecutions,
|
|
421
469
|
sandboxWorkspaceRoot,
|
|
@@ -10,9 +10,7 @@ import type { ResourceRef } from "@stigmer/sdk";
|
|
|
10
10
|
import { getUserMessage } from "@stigmer/sdk";
|
|
11
11
|
import { useUpdateWorkflowInstance } from "./useUpdateWorkflowInstance";
|
|
12
12
|
import { useDeleteWorkflowInstance } from "./useDeleteWorkflowInstance";
|
|
13
|
-
import {
|
|
14
|
-
import { InstanceVisibilitySelector } from "../../library/InstanceVisibilitySelector";
|
|
15
|
-
import { visibilityLabel } from "../../library/visibilityLevels";
|
|
13
|
+
import { ResourceVisibilityControl } from "../../library/ResourceVisibilityControl";
|
|
16
14
|
import { PermissionGate } from "../../iam-policy/PermissionGate";
|
|
17
15
|
import { SharePanel } from "../../iam-policy/SharePanel";
|
|
18
16
|
import { EnvironmentPicker } from "../../environment/EnvironmentPicker";
|
|
@@ -56,7 +54,6 @@ export function WorkflowInstanceDetailPanel({
|
|
|
56
54
|
|
|
57
55
|
const { update, isUpdating } = useUpdateWorkflowInstance();
|
|
58
56
|
const { deleteInstance, isDeleting } = useDeleteWorkflowInstance();
|
|
59
|
-
const { updateVisibility, isPending: isVisibilityPending } = useUpdateVisibility("workflowInstance", id || null);
|
|
60
57
|
const { environments } = useEnvironmentList(org);
|
|
61
58
|
|
|
62
59
|
const [isEditingEnvs, setIsEditingEnvs] = useState(false);
|
|
@@ -65,14 +62,6 @@ export function WorkflowInstanceDetailPanel({
|
|
|
65
62
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
66
63
|
const [deleteError, setDeleteError] = useState<Error | null>(null);
|
|
67
64
|
|
|
68
|
-
const handleVisibilityChange = useCallback(
|
|
69
|
-
async (v: ApiResourceVisibility) => {
|
|
70
|
-
await updateVisibility(v);
|
|
71
|
-
onUpdated?.();
|
|
72
|
-
},
|
|
73
|
-
[updateVisibility, onUpdated],
|
|
74
|
-
);
|
|
75
|
-
|
|
76
65
|
const handleStartEditEnvs = useCallback(() => {
|
|
77
66
|
const currentRefs: ResourceRef[] = (spec?.environmentRefs ?? []).map((ref) => ({
|
|
78
67
|
org: ref.org || org,
|
|
@@ -255,21 +244,12 @@ export function WorkflowInstanceDetailPanel({
|
|
|
255
244
|
{/* Visibility */}
|
|
256
245
|
<div className="px-4 py-3">
|
|
257
246
|
<h4 className="text-xs font-medium text-muted-foreground mb-2">Visibility</h4>
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
</span>
|
|
265
|
-
}
|
|
266
|
-
>
|
|
267
|
-
<InstanceVisibilitySelector
|
|
268
|
-
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
269
|
-
onVisibilityChange={handleVisibilityChange}
|
|
270
|
-
isPending={isVisibilityPending}
|
|
271
|
-
/>
|
|
272
|
-
</PermissionGate>
|
|
247
|
+
<ResourceVisibilityControl
|
|
248
|
+
kind="workflowInstance"
|
|
249
|
+
resourceId={id}
|
|
250
|
+
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
251
|
+
onChanged={onUpdated}
|
|
252
|
+
/>
|
|
273
253
|
</div>
|
|
274
254
|
|
|
275
255
|
{/* Share Panel */}
|
|
@@ -6,9 +6,7 @@ import type { WorkflowInstance } from "@stigmer/protos/ai/stigmer/agentic/workfl
|
|
|
6
6
|
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
7
7
|
import { useWorkflowInstances } from "../useWorkflowInstances";
|
|
8
8
|
import { useEnvironmentList } from "../../environment/useEnvironmentList";
|
|
9
|
-
import {
|
|
10
|
-
import { InstanceVisibilitySelector } from "../../library/InstanceVisibilitySelector";
|
|
11
|
-
import { visibilityLabel } from "../../library/visibilityLevels";
|
|
9
|
+
import { ResourceVisibilityControl } from "../../library/ResourceVisibilityControl";
|
|
12
10
|
import { PermissionGate } from "../../iam-policy/PermissionGate";
|
|
13
11
|
import { WorkflowInstanceEmptyState } from "./WorkflowInstanceEmptyState";
|
|
14
12
|
|
|
@@ -167,18 +165,9 @@ function InstanceRow({
|
|
|
167
165
|
}: InstanceRowProps) {
|
|
168
166
|
const meta = instance.metadata;
|
|
169
167
|
const id = meta?.id ?? "";
|
|
170
|
-
const { updateVisibility, isPending } = useUpdateVisibility("workflowInstance", id || null);
|
|
171
168
|
|
|
172
169
|
const envRefs = instance.spec?.environmentRefs ?? [];
|
|
173
170
|
|
|
174
|
-
const handleVisibilityChange = useCallback(
|
|
175
|
-
async (v: ApiResourceVisibility) => {
|
|
176
|
-
await updateVisibility(v);
|
|
177
|
-
refetch();
|
|
178
|
-
},
|
|
179
|
-
[updateVisibility, refetch],
|
|
180
|
-
);
|
|
181
|
-
|
|
182
171
|
return (
|
|
183
172
|
<tr
|
|
184
173
|
className={cn(
|
|
@@ -224,21 +213,12 @@ function InstanceRow({
|
|
|
224
213
|
|
|
225
214
|
<td className="px-4 py-2.5" onClick={(e) => e.stopPropagation()}>
|
|
226
215
|
{id ? (
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
</span>
|
|
234
|
-
}
|
|
235
|
-
>
|
|
236
|
-
<InstanceVisibilitySelector
|
|
237
|
-
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
238
|
-
onVisibilityChange={handleVisibilityChange}
|
|
239
|
-
isPending={isPending}
|
|
240
|
-
/>
|
|
241
|
-
</PermissionGate>
|
|
216
|
+
<ResourceVisibilityControl
|
|
217
|
+
kind="workflowInstance"
|
|
218
|
+
resourceId={id}
|
|
219
|
+
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
220
|
+
onChanged={refetch}
|
|
221
|
+
/>
|
|
242
222
|
) : (
|
|
243
223
|
<span className="text-xs text-muted-foreground">—</span>
|
|
244
224
|
)}
|