@stigmer/react 3.40.0 → 3.40.1
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/channel-app/ChannelAppDetailPanel.d.ts +5 -0
- package/channel-app/ChannelAppDetailPanel.d.ts.map +1 -1
- package/channel-app/ChannelAppDetailPanel.js +9 -3
- package/channel-app/ChannelAppDetailPanel.js.map +1 -1
- package/channel-app/ChannelAppListPanel.d.ts +13 -4
- package/channel-app/ChannelAppListPanel.d.ts.map +1 -1
- package/channel-app/ChannelAppListPanel.js +5 -5
- package/channel-app/ChannelAppListPanel.js.map +1 -1
- package/channel-app/copy.d.ts +15 -0
- package/channel-app/copy.d.ts.map +1 -0
- package/channel-app/copy.js +15 -0
- package/channel-app/copy.js.map +1 -0
- package/package.json +5 -5
- package/settings/ChannelAppsSection.d.ts +7 -0
- package/settings/ChannelAppsSection.d.ts.map +1 -1
- package/settings/ChannelAppsSection.js +15 -2
- package/settings/ChannelAppsSection.js.map +1 -1
- package/src/channel-app/ChannelAppDetailPanel.tsx +179 -158
- package/src/channel-app/ChannelAppListPanel.tsx +14 -4
- package/src/channel-app/copy.ts +16 -0
- package/src/settings/ChannelAppsSection.tsx +19 -2
|
@@ -41,6 +41,11 @@ export interface ChannelAppDetailPanelProps {
|
|
|
41
41
|
* untouched preserves the stored values (rotate one secret without
|
|
42
42
|
* re-entering the others). Deletion is refused server-side while any
|
|
43
43
|
* agent channel still installs through this app.
|
|
44
|
+
*
|
|
45
|
+
* The credentials form is offered to a caller who may edit the app
|
|
46
|
+
* (`can_edit`) and the deletion section to one who may delete it
|
|
47
|
+
* (`can_delete`): its creator and the organization's admins. Someone
|
|
48
|
+
* granted viewer on an app sees its setup values with no actions.
|
|
44
49
|
*/
|
|
45
50
|
export declare function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff, onUpdated, onDeleted, onBack, className, }: ChannelAppDetailPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
46
51
|
//# sourceMappingURL=ChannelAppDetailPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppDetailPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAI1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"ChannelAppDetailPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAI1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAkBzE,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACjD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/C,sCAAsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,GACV,EAAE,0BAA0B,2CAuG5B"}
|
|
@@ -9,6 +9,7 @@ import { useDeleteChannelApp } from "./useDeleteChannelApp.js";
|
|
|
9
9
|
import { buildSlackChannelAppManifest, slackChannelAppRedirectUrl, slackChannelAppWebhookUrl, } from "./slackAppSetup.js";
|
|
10
10
|
import { WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS, whatsappChannelAppWebhookUrl, } from "./whatsappAppSetup.js";
|
|
11
11
|
import { CopyBlock, CopyRow, FormField } from "./internal.js";
|
|
12
|
+
import { PermissionGate } from "../iam-policy/PermissionGate.js";
|
|
12
13
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
13
14
|
/**
|
|
14
15
|
* Detail view for one {@link ChannelApp}: the "finish setup at the
|
|
@@ -24,6 +25,11 @@ import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
|
24
25
|
* untouched preserves the stored values (rotate one secret without
|
|
25
26
|
* re-entering the others). Deletion is refused server-side while any
|
|
26
27
|
* agent channel still installs through this app.
|
|
28
|
+
*
|
|
29
|
+
* The credentials form is offered to a caller who may edit the app
|
|
30
|
+
* (`can_edit`) and the deletion section to one who may delete it
|
|
31
|
+
* (`can_delete`): its creator and the organization's admins. Someone
|
|
32
|
+
* granted viewer on an app sees its setup values with no actions.
|
|
27
33
|
*/
|
|
28
34
|
export function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff, onUpdated, onDeleted, onBack, className, }) {
|
|
29
35
|
const { deleteApp, isDeleting, error: deleteError } = useDeleteChannelApp();
|
|
@@ -43,7 +49,7 @@ export function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff
|
|
|
43
49
|
setConfirmingDelete(false);
|
|
44
50
|
}
|
|
45
51
|
}, [deleteApp, appId, onDeleted]);
|
|
46
|
-
return (_jsxs("div", { className: cn("stg:space-y-5", className), children: [_jsxs("div", { className: "stg:flex stg:items-center stg:justify-between", children: [_jsxs("div", { className: "stg:min-w-0", children: [_jsx("h3", { className: "stg:truncate stg:text-sm stg:font-semibold stg:text-foreground", children: name }), _jsx("p", { className: "stg:font-mono stg:text-[0.65rem] stg:text-muted-foreground", children: appId })] }), onBack && (_jsx("button", { type: "button", onClick: onBack, className: "stg:text-muted-foreground stg:hover:text-foreground stg:shrink-0 stg:text-xs stg:transition-colors", children: "\u2190 Back" }))] }), providerCase === "slack" ? (_jsx(SlackAppDetail, { channelApp: channelApp, consoleOrigin: consoleOrigin, onUpdated: onUpdated })) : providerCase === "whatsapp" ? (_jsx(WhatsAppAppDetail, { channelApp: channelApp, createHandoff: createHandoff, onUpdated: onUpdated })) : null, _jsxs("section", { className: "stg:border-t stg:border-border stg:pt-3", "aria-label": "Danger zone", children: [deleteError && (_jsx("p", { className: "stg:text-destructive stg:mb-2 stg:text-[0.65rem]", role: "alert", children: getUserMessage(deleteError) })), confirmingDelete ? (_jsxs("div", { className: "stg:flex stg:items-center stg:gap-2", children: [_jsx("p", { className: "stg:text-xs stg:text-foreground", children: "Delete this channel app? Channels installing through it must be disconnected first." }), _jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium", "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isDeleting && _jsx(SpinnerIcon, { size: 12 }), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isDeleting, className: "stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors", children: "Keep" })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80", children: "Delete channel app" }))] })] }));
|
|
52
|
+
return (_jsxs("div", { className: cn("stg:space-y-5", className), children: [_jsxs("div", { className: "stg:flex stg:items-center stg:justify-between", children: [_jsxs("div", { className: "stg:min-w-0", children: [_jsx("h3", { className: "stg:truncate stg:text-sm stg:font-semibold stg:text-foreground", children: name }), _jsx("p", { className: "stg:font-mono stg:text-[0.65rem] stg:text-muted-foreground", children: appId })] }), onBack && (_jsx("button", { type: "button", onClick: onBack, className: "stg:text-muted-foreground stg:hover:text-foreground stg:shrink-0 stg:text-xs stg:transition-colors", children: "\u2190 Back" }))] }), providerCase === "slack" ? (_jsx(SlackAppDetail, { channelApp: channelApp, consoleOrigin: consoleOrigin, onUpdated: onUpdated })) : providerCase === "whatsapp" ? (_jsx(WhatsAppAppDetail, { channelApp: channelApp, createHandoff: createHandoff, onUpdated: onUpdated })) : null, _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_delete", children: _jsxs("section", { className: "stg:border-t stg:border-border stg:pt-3", "aria-label": "Danger zone", children: [deleteError && (_jsx("p", { className: "stg:text-destructive stg:mb-2 stg:text-[0.65rem]", role: "alert", children: getUserMessage(deleteError) })), confirmingDelete ? (_jsxs("div", { className: "stg:flex stg:items-center stg:gap-2", children: [_jsx("p", { className: "stg:text-xs stg:text-foreground", children: "Delete this channel app? Channels installing through it must be disconnected first." }), _jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium", "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isDeleting && _jsx(SpinnerIcon, { size: 12 }), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isDeleting, className: "stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors", children: "Keep" })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80", children: "Delete channel app" }))] }) })] }));
|
|
47
53
|
}
|
|
48
54
|
// ---------------------------------------------------------------------------
|
|
49
55
|
// Slack — finish setup in Slack + credential rotation
|
|
@@ -91,7 +97,7 @@ function SlackAppDetail({ channelApp, consoleOrigin, onUpdated, }) {
|
|
|
91
97
|
// error state is managed by useUpdateChannelApp
|
|
92
98
|
}
|
|
93
99
|
}, [canSave, clearError, update, channelApp, clientId, clientSecret, signingSecret, onUpdated]);
|
|
94
|
-
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Slack", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Slack" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "Event Subscriptions" }), " page, enable events and set the request URL below (Slack verifies it immediately). The completed manifest is also available for review or re-paste."] }), _jsx(CopyRow, { label: "Events request URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), _jsx(CopyRow, { label: "OAuth redirect URL", value: redirectUrl }), _jsx(CopyBlock, { label: "Completed app manifest", value: manifest })] }), _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-client-id`, label: "Client ID", value: clientId, onChange: setClientId, placeholder: "1234567890.0987654321", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-client-secret`, label: "Client secret", value: clientSecret, onChange: setClientSecret, placeholder: "Client secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-signing-secret`, label: "Signing secret", value: signingSecret, onChange: setSigningSecret, placeholder: "Signing secret", type: "password", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] })] }));
|
|
100
|
+
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Slack", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Slack" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "Event Subscriptions" }), " page, enable events and set the request URL below (Slack verifies it immediately). The completed manifest is also available for review or re-paste."] }), _jsx(CopyRow, { label: "Events request URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), _jsx(CopyRow, { label: "OAuth redirect URL", value: redirectUrl }), _jsx(CopyBlock, { label: "Completed app manifest", value: manifest })] }), _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_edit", children: _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-client-id`, label: "Client ID", value: clientId, onChange: setClientId, placeholder: "1234567890.0987654321", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-client-secret`, label: "Client secret", value: clientSecret, onChange: setClientSecret, placeholder: "Client secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-signing-secret`, label: "Signing secret", value: signingSecret, onChange: setSigningSecret, placeholder: "Signing secret", type: "password", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] }) })] }));
|
|
95
101
|
}
|
|
96
102
|
// ---------------------------------------------------------------------------
|
|
97
103
|
// WhatsApp — finish setup in Meta + credential rotation
|
|
@@ -140,6 +146,6 @@ function WhatsAppAppDetail({ channelApp, createHandoff, onUpdated, }) {
|
|
|
140
146
|
// error state is managed by useUpdateChannelApp
|
|
141
147
|
}
|
|
142
148
|
}, [canSave, clearError, update, channelApp, metaAppId, appSecret, accessToken, verifyToken, onUpdated]);
|
|
143
|
-
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Meta", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Meta" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "WhatsApp \u2192 Configuration" }), " page, set the callback URL and verify token below, click ", _jsx("span", { className: "stg:font-medium", children: "Verify and save" }), " ", "(Meta verifies immediately), then subscribe to the", " ", _jsx("span", { className: "stg:font-medium", children: WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS.join(", ") }), " ", "webhook field."] }), _jsx(CopyRow, { label: "Callback URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), createHandoff?.verifyToken ? (_jsx(CopyRow, { label: "Verify token", value: createHandoff.verifyToken, copyTargetId: "stgm-chapp-verify-token-copy" })) : (_jsxs("div", { className: "stg:space-y-1", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Verify token" }), _jsx("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: "Shown once at registration. If you no longer have it, paste a new one below and update Meta's webhook configuration to match." })] }))] }), _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-app-id`, label: "App ID", value: metaAppId, onChange: setMetaAppId, placeholder: "1234567890123456", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-app-secret`, label: "App secret", value: appSecret, onChange: setAppSecret, placeholder: "App secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-access-token`, label: "Access token", value: accessToken, onChange: setAccessToken, placeholder: "Long-lived system-user access token", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-verify-token`, label: "Verify token", value: verifyToken, onChange: setVerifyToken, placeholder: "Verify token", type: "password", hint: "Rotating it? Update Meta's webhook configuration to the same value.", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] })] }));
|
|
149
|
+
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Meta", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Meta" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "WhatsApp \u2192 Configuration" }), " page, set the callback URL and verify token below, click ", _jsx("span", { className: "stg:font-medium", children: "Verify and save" }), " ", "(Meta verifies immediately), then subscribe to the", " ", _jsx("span", { className: "stg:font-medium", children: WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS.join(", ") }), " ", "webhook field."] }), _jsx(CopyRow, { label: "Callback URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), createHandoff?.verifyToken ? (_jsx(CopyRow, { label: "Verify token", value: createHandoff.verifyToken, copyTargetId: "stgm-chapp-verify-token-copy" })) : (_jsxs("div", { className: "stg:space-y-1", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Verify token" }), _jsx("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: "Shown once at registration. If you no longer have it, paste a new one below and update Meta's webhook configuration to match." })] }))] }), _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_edit", children: _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-app-id`, label: "App ID", value: metaAppId, onChange: setMetaAppId, placeholder: "1234567890123456", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-app-secret`, label: "App secret", value: appSecret, onChange: setAppSecret, placeholder: "App secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-access-token`, label: "Access token", value: accessToken, onChange: setAccessToken, placeholder: "Long-lived system-user access token", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-verify-token`, label: "Verify token", value: verifyToken, onChange: setVerifyToken, placeholder: "Verify token", type: "password", hint: "Rotating it? Update Meta's webhook configuration to the same value.", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] }) })] }));
|
|
144
150
|
}
|
|
145
151
|
//# sourceMappingURL=ChannelAppDetailPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppDetailPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChannelAppDetailPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
1
2
|
import type { ChannelApp } from "@stigmer/protos/ai/stigmer/agentic/channelapp/v1/api_pb";
|
|
2
3
|
/** Props for {@link ChannelAppListPanel}. */
|
|
3
4
|
export interface ChannelAppListPanelProps {
|
|
@@ -10,13 +11,21 @@ export interface ChannelAppListPanelProps {
|
|
|
10
11
|
readonly onEdit?: (app: ChannelApp) => void;
|
|
11
12
|
/** Re-expose refetch so parents can trigger a list refresh. */
|
|
12
13
|
readonly onRefetchRef?: (refetch: () => void) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Shown when the list is empty. Defaults to "No channel apps registered
|
|
16
|
+
* yet." The list holds only the apps the caller may view (their creator,
|
|
17
|
+
* anyone granted viewer on one, and the organization's admins), so a host
|
|
18
|
+
* that knows the caller may not manage channel apps should say who does
|
|
19
|
+
* instead.
|
|
20
|
+
*/
|
|
21
|
+
readonly emptyState?: ReactNode;
|
|
13
22
|
/** Additional CSS class names for the root container. */
|
|
14
23
|
readonly className?: string;
|
|
15
24
|
}
|
|
16
25
|
/**
|
|
17
|
-
* Displays the {@link ChannelApp} resources
|
|
18
|
-
* the customer's own provider apps (Slack,
|
|
19
|
-
* channels can install through.
|
|
26
|
+
* Displays the {@link ChannelApp} resources of an organization that the
|
|
27
|
+
* caller may view — the customer's own provider apps (Slack,
|
|
28
|
+
* Meta/WhatsApp) that agent channels can install through.
|
|
20
29
|
*
|
|
21
30
|
* Each row shows the app name, provider, the provider's non-secret app
|
|
22
31
|
* identifier, and creation date. Secret fields never appear (they
|
|
@@ -32,5 +41,5 @@ export interface ChannelAppListPanelProps {
|
|
|
32
41
|
* />
|
|
33
42
|
* ```
|
|
34
43
|
*/
|
|
35
|
-
export declare function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }: ChannelAppListPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
export declare function ChannelAppListPanel({ org, onEdit, onRefetchRef, emptyState, className, }: ChannelAppListPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
36
45
|
//# sourceMappingURL=ChannelAppListPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppListPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChannelAppListPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAQ1F,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACtD;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;IAChC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,UAA8C,EAC9C,SAAS,GACV,EAAE,wBAAwB,2CAyD1B"}
|
|
@@ -6,9 +6,9 @@ import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
|
6
6
|
import { channelProviderOf } from "../channel/providers.js";
|
|
7
7
|
import { useChannelAppList } from "./useChannelAppList.js";
|
|
8
8
|
/**
|
|
9
|
-
* Displays the {@link ChannelApp} resources
|
|
10
|
-
* the customer's own provider apps (Slack,
|
|
11
|
-
* channels can install through.
|
|
9
|
+
* Displays the {@link ChannelApp} resources of an organization that the
|
|
10
|
+
* caller may view — the customer's own provider apps (Slack,
|
|
11
|
+
* Meta/WhatsApp) that agent channels can install through.
|
|
12
12
|
*
|
|
13
13
|
* Each row shows the app name, provider, the provider's non-secret app
|
|
14
14
|
* identifier, and creation date. Secret fields never appear (they
|
|
@@ -24,7 +24,7 @@ import { useChannelAppList } from "./useChannelAppList.js";
|
|
|
24
24
|
* />
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
export function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }) {
|
|
27
|
+
export function ChannelAppListPanel({ org, onEdit, onRefetchRef, emptyState = "No channel apps registered yet.", className, }) {
|
|
28
28
|
const { channelApps, isLoading, error, refetch } = useChannelAppList(org);
|
|
29
29
|
if (onRefetchRef) {
|
|
30
30
|
onRefetchRef(refetch);
|
|
@@ -36,7 +36,7 @@ export function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }) {
|
|
|
36
36
|
return (_jsx("p", { className: cn("stg:text-destructive stg:text-xs", className), role: "alert", children: getUserMessage(error) }));
|
|
37
37
|
}
|
|
38
38
|
if (channelApps.length === 0) {
|
|
39
|
-
return (_jsx("p", { className: cn("stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs", className), children:
|
|
39
|
+
return (_jsx("p", { className: cn("stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs", className), children: emptyState }));
|
|
40
40
|
}
|
|
41
41
|
return (_jsx("div", { className: cn("stg:space-y-2", className), role: "list", "aria-label": "Channel apps", children: channelApps.map((app) => (_jsx(ChannelAppRow, { channelApp: app, onEdit: onEdit ? () => onEdit(app) : undefined }, app.metadata?.id ?? ""))) }));
|
|
42
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppListPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"ChannelAppListPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel-app copy shared by more than one surface, so the settings section
|
|
3
|
+
* and anything else that lists an organization's channel apps say the same
|
|
4
|
+
* thing.
|
|
5
|
+
*
|
|
6
|
+
* A channel app carries its organization's Slack or Meta app secrets, so the
|
|
7
|
+
* model shows it to its creator, anyone granted viewer on it and the
|
|
8
|
+
* organization's admins, and plain members and viewers may not see it at all
|
|
9
|
+
* (stigmer/stigmer#1384). An empty list is therefore not evidence that none
|
|
10
|
+
* is registered, so a caller who may not create channel apps is told who
|
|
11
|
+
* manages them instead of being told that nothing exists.
|
|
12
|
+
*/
|
|
13
|
+
/** Shown in place of the empty state to a caller who may not create channel apps. */
|
|
14
|
+
export declare const CHANNEL_APPS_MANAGED_BY_ADMINS = "Channel apps are managed by your organization's admins.";
|
|
15
|
+
//# sourceMappingURL=copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../src/channel-app/copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,4DACgB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel-app copy shared by more than one surface, so the settings section
|
|
3
|
+
* and anything else that lists an organization's channel apps say the same
|
|
4
|
+
* thing.
|
|
5
|
+
*
|
|
6
|
+
* A channel app carries its organization's Slack or Meta app secrets, so the
|
|
7
|
+
* model shows it to its creator, anyone granted viewer on it and the
|
|
8
|
+
* organization's admins, and plain members and viewers may not see it at all
|
|
9
|
+
* (stigmer/stigmer#1384). An empty list is therefore not evidence that none
|
|
10
|
+
* is registered, so a caller who may not create channel apps is told who
|
|
11
|
+
* manages them instead of being told that nothing exists.
|
|
12
|
+
*/
|
|
13
|
+
/** Shown in place of the empty state to a caller who may not create channel apps. */
|
|
14
|
+
export const CHANNEL_APPS_MANAGED_BY_ADMINS = "Channel apps are managed by your organization's admins.";
|
|
15
|
+
//# sourceMappingURL=copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.js","sourceRoot":"","sources":["../src/channel-app/copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,MAAM,CAAC,MAAM,8BAA8B,GACzC,yDAAyD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/react",
|
|
3
|
-
"version": "3.40.
|
|
3
|
+
"version": "3.40.1",
|
|
4
4
|
"description": "React provider and client hook for the Stigmer platform SDK",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@bufbuild/protovalidate": "^1.1.1",
|
|
39
39
|
"@dagrejs/dagre": "^1.1.4",
|
|
40
|
-
"@stigmer/plugin-package": "3.40.
|
|
41
|
-
"@stigmer/theme": "3.40.
|
|
40
|
+
"@stigmer/plugin-package": "3.40.1",
|
|
41
|
+
"@stigmer/theme": "3.40.1",
|
|
42
42
|
"diff": "^8.0.3",
|
|
43
43
|
"fflate": "^0.8.2",
|
|
44
44
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"@codemirror/state": "^6.0.0",
|
|
62
62
|
"@codemirror/view": "^6.0.0",
|
|
63
63
|
"@lezer/highlight": "^1.0.0",
|
|
64
|
-
"@stigmer/protos": "3.40.
|
|
65
|
-
"@stigmer/sdk": "3.40.
|
|
64
|
+
"@stigmer/protos": "3.40.1",
|
|
65
|
+
"@stigmer/sdk": "3.40.1",
|
|
66
66
|
"@tanstack/react-table": "^8.20.0",
|
|
67
67
|
"@xyflow/react": "^12.0.0",
|
|
68
68
|
"elkjs": "^0.9.0",
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
*
|
|
9
9
|
* After registering an app here, the connect dialog on any agent's
|
|
10
10
|
* Channels tab offers it as the serving app.
|
|
11
|
+
*
|
|
12
|
+
* "New channel app" is offered once the server confirms the caller holds
|
|
13
|
+
* `can_create_channel_app` on the organization. The list shows only the
|
|
14
|
+
* apps the caller may view (their creator, anyone granted viewer on one,
|
|
15
|
+
* and the organization's admins), so a caller who may not create channel
|
|
16
|
+
* apps is told that the organization's admins manage them rather than that
|
|
17
|
+
* none is registered.
|
|
11
18
|
*/
|
|
12
19
|
export declare function ChannelAppsSection(): import("react/jsx-runtime").JSX.Element;
|
|
13
20
|
//# sourceMappingURL=ChannelAppsSection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppsSection.d.ts","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChannelAppsSection.d.ts","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,4CAsGjC"}
|
|
@@ -4,9 +4,11 @@ import { useCallback, useId, useRef, useState } from "react";
|
|
|
4
4
|
import { ChannelAppListPanel } from "../channel-app/ChannelAppListPanel.js";
|
|
5
5
|
import { CreateChannelAppForm, } from "../channel-app/CreateChannelAppForm.js";
|
|
6
6
|
import { ChannelAppDetailPanel } from "../channel-app/ChannelAppDetailPanel.js";
|
|
7
|
+
import { CHANNEL_APPS_MANAGED_BY_ADMINS } from "../channel-app/copy.js";
|
|
7
8
|
import { useDeploymentMode } from "../deployment-mode.js";
|
|
9
|
+
import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
|
|
8
10
|
import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
|
|
9
|
-
import { useActiveOrgSlug } from "../organization/OrgProvider.js";
|
|
11
|
+
import { useActiveOrgId, useActiveOrgSlug } from "../organization/OrgProvider.js";
|
|
10
12
|
/**
|
|
11
13
|
* Settings section for the organization's channel apps — customer-owned
|
|
12
14
|
* provider apps (Slack apps, Meta WhatsApp apps) that agent channels
|
|
@@ -17,13 +19,24 @@ import { useActiveOrgSlug } from "../organization/OrgProvider.js";
|
|
|
17
19
|
*
|
|
18
20
|
* After registering an app here, the connect dialog on any agent's
|
|
19
21
|
* Channels tab offers it as the serving app.
|
|
22
|
+
*
|
|
23
|
+
* "New channel app" is offered once the server confirms the caller holds
|
|
24
|
+
* `can_create_channel_app` on the organization. The list shows only the
|
|
25
|
+
* apps the caller may view (their creator, anyone granted viewer on one,
|
|
26
|
+
* and the organization's admins), so a caller who may not create channel
|
|
27
|
+
* apps is told that the organization's admins manage them rather than that
|
|
28
|
+
* none is registered.
|
|
20
29
|
*/
|
|
21
30
|
export function ChannelAppsSection() {
|
|
22
31
|
const headingId = useId();
|
|
23
32
|
const org = useActiveOrgSlug();
|
|
33
|
+
const orgId = useActiveOrgId();
|
|
24
34
|
// Channel installs (the consumer of these credentials) are cloud-only;
|
|
25
35
|
// gate the whole section the way the Channels tab gates connects.
|
|
26
36
|
const installsAvailable = useDeploymentMode() === "cloud";
|
|
37
|
+
const createCheck = useCheckPermission(installsAvailable && orgId ? { kind: "organization", id: orgId } : null, "can_create_channel_app");
|
|
38
|
+
const canCreate = !createCheck.isLoading && createCheck.allowed;
|
|
39
|
+
const deniedCreate = !createCheck.isLoading && !createCheck.allowed;
|
|
27
40
|
const [flow, setFlow] = useState({ phase: "idle" });
|
|
28
41
|
const listRefetchRef = useRef(null);
|
|
29
42
|
const handleRefetchRef = useCallback((refetch) => {
|
|
@@ -44,6 +57,6 @@ export function ChannelAppsSection() {
|
|
|
44
57
|
listRefetchRef.current?.();
|
|
45
58
|
setFlow({ phase: "idle" });
|
|
46
59
|
}, []);
|
|
47
|
-
return (_jsxs("section", { "aria-labelledby": headingId, children: [_jsxs("div", { className: "stg:mb-3 stg:flex stg:items-center stg:justify-between", children: [_jsx("h2", { id: headingId, className: "stg:text-foreground stg:text-sm stg:font-semibold", children: "Channel Apps" }), installsAvailable && org && flow.phase === "idle" && (_jsx("button", { type: "button", onClick: () => setFlow({ phase: "creating" }), className: "stg:text-primary stg:hover:text-foreground stg:text-xs stg:font-medium stg:transition-colors", children: "+ New channel app" }))] }), _jsx("p", { className: "stg:text-muted-foreground stg:mb-4 stg:text-xs", children: "Your own provider apps for serving agent channels. A Slack app gives the bot your name and icon, and lets multiple agents serve the same workspace \u2014 one per app. A Meta app is how WhatsApp channels connect \u2014 every WhatsApp channel installs through one." }), !installsAvailable ? (_jsx(CloudFeatureNotice, { children: "Channel apps are not available in local mode. Channel installs require Stigmer Cloud." })) : flow.phase === "creating" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(CreateChannelAppForm, { org: org, onCreated: handleCreated, onCancel: () => setFlow({ phase: "idle" }) }) })) : flow.phase === "editing" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(ChannelAppDetailPanel, { channelApp: flow.channelApp, createHandoff: flow.createHandoff, onUpdated: handleUpdated, onDeleted: handleDeleted, onBack: () => setFlow({ phase: "idle" }) }) })) : (_jsx(ChannelAppListPanel, { org: org, onEdit: (app) => setFlow({ phase: "editing", channelApp: app }), onRefetchRef: handleRefetchRef }))] }));
|
|
60
|
+
return (_jsxs("section", { "aria-labelledby": headingId, children: [_jsxs("div", { className: "stg:mb-3 stg:flex stg:items-center stg:justify-between", children: [_jsx("h2", { id: headingId, className: "stg:text-foreground stg:text-sm stg:font-semibold", children: "Channel Apps" }), installsAvailable && org && canCreate && flow.phase === "idle" && (_jsx("button", { type: "button", onClick: () => setFlow({ phase: "creating" }), className: "stg:text-primary stg:hover:text-foreground stg:text-xs stg:font-medium stg:transition-colors", children: "+ New channel app" }))] }), _jsx("p", { className: "stg:text-muted-foreground stg:mb-4 stg:text-xs", children: "Your own provider apps for serving agent channels. A Slack app gives the bot your name and icon, and lets multiple agents serve the same workspace \u2014 one per app. A Meta app is how WhatsApp channels connect \u2014 every WhatsApp channel installs through one." }), !installsAvailable ? (_jsx(CloudFeatureNotice, { children: "Channel apps are not available in local mode. Channel installs require Stigmer Cloud." })) : flow.phase === "creating" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(CreateChannelAppForm, { org: org, onCreated: handleCreated, onCancel: () => setFlow({ phase: "idle" }) }) })) : flow.phase === "editing" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(ChannelAppDetailPanel, { channelApp: flow.channelApp, createHandoff: flow.createHandoff, onUpdated: handleUpdated, onDeleted: handleDeleted, onBack: () => setFlow({ phase: "idle" }) }) })) : (_jsx(ChannelAppListPanel, { org: org, onEdit: (app) => setFlow({ phase: "editing", channelApp: app }), onRefetchRef: handleRefetchRef, emptyState: deniedCreate ? CHANNEL_APPS_MANAGED_BY_ADMINS : undefined }))] }));
|
|
48
61
|
}
|
|
49
62
|
//# sourceMappingURL=ChannelAppsSection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelAppsSection.js","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EACL,oBAAoB,GAErB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"ChannelAppsSection.js","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
whatsappChannelAppWebhookUrl,
|
|
19
19
|
} from "./whatsappAppSetup.js";
|
|
20
20
|
import { CopyBlock, CopyRow, FormField } from "./internal.js";
|
|
21
|
+
import { PermissionGate } from "../iam-policy/PermissionGate.js";
|
|
21
22
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
22
23
|
|
|
23
24
|
// ---------------------------------------------------------------------------
|
|
@@ -66,6 +67,11 @@ export interface ChannelAppDetailPanelProps {
|
|
|
66
67
|
* untouched preserves the stored values (rotate one secret without
|
|
67
68
|
* re-entering the others). Deletion is refused server-side while any
|
|
68
69
|
* agent channel still installs through this app.
|
|
70
|
+
*
|
|
71
|
+
* The credentials form is offered to a caller who may edit the app
|
|
72
|
+
* (`can_edit`) and the deletion section to one who may delete it
|
|
73
|
+
* (`can_delete`): its creator and the organization's admins. Someone
|
|
74
|
+
* granted viewer on an app sees its setup values with no actions.
|
|
69
75
|
*/
|
|
70
76
|
export function ChannelAppDetailPanel({
|
|
71
77
|
channelApp,
|
|
@@ -127,50 +133,55 @@ export function ChannelAppDetailPanel({
|
|
|
127
133
|
) : null}
|
|
128
134
|
|
|
129
135
|
{/* Deletion */}
|
|
130
|
-
<
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<p className="stg:text-xs stg:text-foreground">
|
|
139
|
-
Delete this channel app? Channels installing through it must be
|
|
140
|
-
disconnected first.
|
|
136
|
+
<PermissionGate
|
|
137
|
+
resource={{ kind: "channel_app", id: appId }}
|
|
138
|
+
relation="can_delete"
|
|
139
|
+
>
|
|
140
|
+
<section className="stg:border-t stg:border-border stg:pt-3" aria-label="Danger zone">
|
|
141
|
+
{deleteError && (
|
|
142
|
+
<p className="stg:text-destructive stg:mb-2 stg:text-[0.65rem]" role="alert">
|
|
143
|
+
{getUserMessage(deleteError)}
|
|
141
144
|
</p>
|
|
145
|
+
)}
|
|
146
|
+
{confirmingDelete ? (
|
|
147
|
+
<div className="stg:flex stg:items-center stg:gap-2">
|
|
148
|
+
<p className="stg:text-xs stg:text-foreground">
|
|
149
|
+
Delete this channel app? Channels installing through it must be
|
|
150
|
+
disconnected first.
|
|
151
|
+
</p>
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
onClick={handleDelete}
|
|
155
|
+
disabled={isDeleting}
|
|
156
|
+
className={cn(
|
|
157
|
+
"stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium",
|
|
158
|
+
"stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90",
|
|
159
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-40",
|
|
160
|
+
)}
|
|
161
|
+
>
|
|
162
|
+
{isDeleting && <SpinnerIcon size={12} />}
|
|
163
|
+
Delete
|
|
164
|
+
</button>
|
|
165
|
+
<button
|
|
166
|
+
type="button"
|
|
167
|
+
onClick={() => setConfirmingDelete(false)}
|
|
168
|
+
disabled={isDeleting}
|
|
169
|
+
className="stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors"
|
|
170
|
+
>
|
|
171
|
+
Keep
|
|
172
|
+
</button>
|
|
173
|
+
</div>
|
|
174
|
+
) : (
|
|
142
175
|
<button
|
|
143
176
|
type="button"
|
|
144
|
-
onClick={
|
|
145
|
-
|
|
146
|
-
className={cn(
|
|
147
|
-
"stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium",
|
|
148
|
-
"stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90",
|
|
149
|
-
"stg:disabled:pointer-events-none stg:disabled:opacity-40",
|
|
150
|
-
)}
|
|
151
|
-
>
|
|
152
|
-
{isDeleting && <SpinnerIcon size={12} />}
|
|
153
|
-
Delete
|
|
154
|
-
</button>
|
|
155
|
-
<button
|
|
156
|
-
type="button"
|
|
157
|
-
onClick={() => setConfirmingDelete(false)}
|
|
158
|
-
disabled={isDeleting}
|
|
159
|
-
className="stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors"
|
|
177
|
+
onClick={() => setConfirmingDelete(true)}
|
|
178
|
+
className="stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80"
|
|
160
179
|
>
|
|
161
|
-
|
|
180
|
+
Delete channel app
|
|
162
181
|
</button>
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
type="button"
|
|
167
|
-
onClick={() => setConfirmingDelete(true)}
|
|
168
|
-
className="stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80"
|
|
169
|
-
>
|
|
170
|
-
Delete channel app
|
|
171
|
-
</button>
|
|
172
|
-
)}
|
|
173
|
-
</section>
|
|
182
|
+
)}
|
|
183
|
+
</section>
|
|
184
|
+
</PermissionGate>
|
|
174
185
|
</div>
|
|
175
186
|
);
|
|
176
187
|
}
|
|
@@ -270,63 +281,68 @@ function SlackAppDetail({
|
|
|
270
281
|
</section>
|
|
271
282
|
|
|
272
283
|
{/* Credential rotation */}
|
|
273
|
-
<
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
label="Client ID"
|
|
284
|
-
value={clientId}
|
|
285
|
-
onChange={setClientId}
|
|
286
|
-
placeholder="1234567890.0987654321"
|
|
287
|
-
disabled={isUpdating}
|
|
288
|
-
required
|
|
289
|
-
/>
|
|
290
|
-
<FormField
|
|
291
|
-
id={`${baseId}-client-secret`}
|
|
292
|
-
label="Client secret"
|
|
293
|
-
value={clientSecret}
|
|
294
|
-
onChange={setClientSecret}
|
|
295
|
-
placeholder="Client secret"
|
|
296
|
-
type="password"
|
|
297
|
-
disabled={isUpdating}
|
|
298
|
-
required
|
|
299
|
-
/>
|
|
300
|
-
<FormField
|
|
301
|
-
id={`${baseId}-signing-secret`}
|
|
302
|
-
label="Signing secret"
|
|
303
|
-
value={signingSecret}
|
|
304
|
-
onChange={setSigningSecret}
|
|
305
|
-
placeholder="Signing secret"
|
|
306
|
-
type="password"
|
|
307
|
-
disabled={isUpdating}
|
|
308
|
-
required
|
|
309
|
-
/>
|
|
310
|
-
|
|
311
|
-
{updateError && (
|
|
312
|
-
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
313
|
-
{getUserMessage(updateError)}
|
|
284
|
+
<PermissionGate
|
|
285
|
+
resource={{ kind: "channel_app", id: appId }}
|
|
286
|
+
relation="can_edit"
|
|
287
|
+
>
|
|
288
|
+
<form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
|
|
289
|
+
<p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
|
|
290
|
+
<p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
|
|
291
|
+
Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
|
|
292
|
+
leave a field untouched to keep its stored value, or paste a new
|
|
293
|
+
one to rotate it.
|
|
314
294
|
</p>
|
|
315
|
-
)}
|
|
316
295
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
"
|
|
323
|
-
|
|
296
|
+
<FormField
|
|
297
|
+
id={`${baseId}-client-id`}
|
|
298
|
+
label="Client ID"
|
|
299
|
+
value={clientId}
|
|
300
|
+
onChange={setClientId}
|
|
301
|
+
placeholder="1234567890.0987654321"
|
|
302
|
+
disabled={isUpdating}
|
|
303
|
+
required
|
|
304
|
+
/>
|
|
305
|
+
<FormField
|
|
306
|
+
id={`${baseId}-client-secret`}
|
|
307
|
+
label="Client secret"
|
|
308
|
+
value={clientSecret}
|
|
309
|
+
onChange={setClientSecret}
|
|
310
|
+
placeholder="Client secret"
|
|
311
|
+
type="password"
|
|
312
|
+
disabled={isUpdating}
|
|
313
|
+
required
|
|
314
|
+
/>
|
|
315
|
+
<FormField
|
|
316
|
+
id={`${baseId}-signing-secret`}
|
|
317
|
+
label="Signing secret"
|
|
318
|
+
value={signingSecret}
|
|
319
|
+
onChange={setSigningSecret}
|
|
320
|
+
placeholder="Signing secret"
|
|
321
|
+
type="password"
|
|
322
|
+
disabled={isUpdating}
|
|
323
|
+
required
|
|
324
|
+
/>
|
|
325
|
+
|
|
326
|
+
{updateError && (
|
|
327
|
+
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
328
|
+
{getUserMessage(updateError)}
|
|
329
|
+
</p>
|
|
324
330
|
)}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
|
|
332
|
+
<button
|
|
333
|
+
type="submit"
|
|
334
|
+
disabled={!canSave}
|
|
335
|
+
className={cn(
|
|
336
|
+
"stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
|
|
337
|
+
"stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
|
|
338
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-40",
|
|
339
|
+
)}
|
|
340
|
+
>
|
|
341
|
+
{isUpdating && <SpinnerIcon size={12} />}
|
|
342
|
+
Save credentials
|
|
343
|
+
</button>
|
|
344
|
+
</form>
|
|
345
|
+
</PermissionGate>
|
|
330
346
|
</>
|
|
331
347
|
);
|
|
332
348
|
}
|
|
@@ -440,74 +456,79 @@ function WhatsAppAppDetail({
|
|
|
440
456
|
</section>
|
|
441
457
|
|
|
442
458
|
{/* Credential rotation */}
|
|
443
|
-
<
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
label="App ID"
|
|
454
|
-
value={metaAppId}
|
|
455
|
-
onChange={setMetaAppId}
|
|
456
|
-
placeholder="1234567890123456"
|
|
457
|
-
disabled={isUpdating}
|
|
458
|
-
required
|
|
459
|
-
/>
|
|
460
|
-
<FormField
|
|
461
|
-
id={`${baseId}-app-secret`}
|
|
462
|
-
label="App secret"
|
|
463
|
-
value={appSecret}
|
|
464
|
-
onChange={setAppSecret}
|
|
465
|
-
placeholder="App secret"
|
|
466
|
-
type="password"
|
|
467
|
-
disabled={isUpdating}
|
|
468
|
-
required
|
|
469
|
-
/>
|
|
470
|
-
<FormField
|
|
471
|
-
id={`${baseId}-access-token`}
|
|
472
|
-
label="Access token"
|
|
473
|
-
value={accessToken}
|
|
474
|
-
onChange={setAccessToken}
|
|
475
|
-
placeholder="Long-lived system-user access token"
|
|
476
|
-
type="password"
|
|
477
|
-
disabled={isUpdating}
|
|
478
|
-
required
|
|
479
|
-
/>
|
|
480
|
-
<FormField
|
|
481
|
-
id={`${baseId}-verify-token`}
|
|
482
|
-
label="Verify token"
|
|
483
|
-
value={verifyToken}
|
|
484
|
-
onChange={setVerifyToken}
|
|
485
|
-
placeholder="Verify token"
|
|
486
|
-
type="password"
|
|
487
|
-
hint="Rotating it? Update Meta's webhook configuration to the same value."
|
|
488
|
-
disabled={isUpdating}
|
|
489
|
-
required
|
|
490
|
-
/>
|
|
491
|
-
|
|
492
|
-
{updateError && (
|
|
493
|
-
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
494
|
-
{getUserMessage(updateError)}
|
|
459
|
+
<PermissionGate
|
|
460
|
+
resource={{ kind: "channel_app", id: appId }}
|
|
461
|
+
relation="can_edit"
|
|
462
|
+
>
|
|
463
|
+
<form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
|
|
464
|
+
<p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
|
|
465
|
+
<p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
|
|
466
|
+
Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
|
|
467
|
+
leave a field untouched to keep its stored value, or paste a new
|
|
468
|
+
one to rotate it.
|
|
495
469
|
</p>
|
|
496
|
-
)}
|
|
497
470
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
"
|
|
504
|
-
|
|
471
|
+
<FormField
|
|
472
|
+
id={`${baseId}-app-id`}
|
|
473
|
+
label="App ID"
|
|
474
|
+
value={metaAppId}
|
|
475
|
+
onChange={setMetaAppId}
|
|
476
|
+
placeholder="1234567890123456"
|
|
477
|
+
disabled={isUpdating}
|
|
478
|
+
required
|
|
479
|
+
/>
|
|
480
|
+
<FormField
|
|
481
|
+
id={`${baseId}-app-secret`}
|
|
482
|
+
label="App secret"
|
|
483
|
+
value={appSecret}
|
|
484
|
+
onChange={setAppSecret}
|
|
485
|
+
placeholder="App secret"
|
|
486
|
+
type="password"
|
|
487
|
+
disabled={isUpdating}
|
|
488
|
+
required
|
|
489
|
+
/>
|
|
490
|
+
<FormField
|
|
491
|
+
id={`${baseId}-access-token`}
|
|
492
|
+
label="Access token"
|
|
493
|
+
value={accessToken}
|
|
494
|
+
onChange={setAccessToken}
|
|
495
|
+
placeholder="Long-lived system-user access token"
|
|
496
|
+
type="password"
|
|
497
|
+
disabled={isUpdating}
|
|
498
|
+
required
|
|
499
|
+
/>
|
|
500
|
+
<FormField
|
|
501
|
+
id={`${baseId}-verify-token`}
|
|
502
|
+
label="Verify token"
|
|
503
|
+
value={verifyToken}
|
|
504
|
+
onChange={setVerifyToken}
|
|
505
|
+
placeholder="Verify token"
|
|
506
|
+
type="password"
|
|
507
|
+
hint="Rotating it? Update Meta's webhook configuration to the same value."
|
|
508
|
+
disabled={isUpdating}
|
|
509
|
+
required
|
|
510
|
+
/>
|
|
511
|
+
|
|
512
|
+
{updateError && (
|
|
513
|
+
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
514
|
+
{getUserMessage(updateError)}
|
|
515
|
+
</p>
|
|
505
516
|
)}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
517
|
+
|
|
518
|
+
<button
|
|
519
|
+
type="submit"
|
|
520
|
+
disabled={!canSave}
|
|
521
|
+
className={cn(
|
|
522
|
+
"stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
|
|
523
|
+
"stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
|
|
524
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-40",
|
|
525
|
+
)}
|
|
526
|
+
>
|
|
527
|
+
{isUpdating && <SpinnerIcon size={12} />}
|
|
528
|
+
Save credentials
|
|
529
|
+
</button>
|
|
530
|
+
</form>
|
|
531
|
+
</PermissionGate>
|
|
511
532
|
</>
|
|
512
533
|
);
|
|
513
534
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import type { ReactNode } from "react";
|
|
3
4
|
import { cn } from "@stigmer/theme";
|
|
4
5
|
import { getUserMessage } from "@stigmer/sdk";
|
|
5
6
|
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
@@ -22,14 +23,22 @@ export interface ChannelAppListPanelProps {
|
|
|
22
23
|
readonly onEdit?: (app: ChannelApp) => void;
|
|
23
24
|
/** Re-expose refetch so parents can trigger a list refresh. */
|
|
24
25
|
readonly onRefetchRef?: (refetch: () => void) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Shown when the list is empty. Defaults to "No channel apps registered
|
|
28
|
+
* yet." The list holds only the apps the caller may view (their creator,
|
|
29
|
+
* anyone granted viewer on one, and the organization's admins), so a host
|
|
30
|
+
* that knows the caller may not manage channel apps should say who does
|
|
31
|
+
* instead.
|
|
32
|
+
*/
|
|
33
|
+
readonly emptyState?: ReactNode;
|
|
25
34
|
/** Additional CSS class names for the root container. */
|
|
26
35
|
readonly className?: string;
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
/**
|
|
30
|
-
* Displays the {@link ChannelApp} resources
|
|
31
|
-
* the customer's own provider apps (Slack,
|
|
32
|
-
* channels can install through.
|
|
39
|
+
* Displays the {@link ChannelApp} resources of an organization that the
|
|
40
|
+
* caller may view — the customer's own provider apps (Slack,
|
|
41
|
+
* Meta/WhatsApp) that agent channels can install through.
|
|
33
42
|
*
|
|
34
43
|
* Each row shows the app name, provider, the provider's non-secret app
|
|
35
44
|
* identifier, and creation date. Secret fields never appear (they
|
|
@@ -49,6 +58,7 @@ export function ChannelAppListPanel({
|
|
|
49
58
|
org,
|
|
50
59
|
onEdit,
|
|
51
60
|
onRefetchRef,
|
|
61
|
+
emptyState = "No channel apps registered yet.",
|
|
52
62
|
className,
|
|
53
63
|
}: ChannelAppListPanelProps) {
|
|
54
64
|
const { channelApps, isLoading, error, refetch } = useChannelAppList(org);
|
|
@@ -87,7 +97,7 @@ export function ChannelAppListPanel({
|
|
|
87
97
|
className,
|
|
88
98
|
)}
|
|
89
99
|
>
|
|
90
|
-
|
|
100
|
+
{emptyState}
|
|
91
101
|
</p>
|
|
92
102
|
);
|
|
93
103
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel-app copy shared by more than one surface, so the settings section
|
|
3
|
+
* and anything else that lists an organization's channel apps say the same
|
|
4
|
+
* thing.
|
|
5
|
+
*
|
|
6
|
+
* A channel app carries its organization's Slack or Meta app secrets, so the
|
|
7
|
+
* model shows it to its creator, anyone granted viewer on it and the
|
|
8
|
+
* organization's admins, and plain members and viewers may not see it at all
|
|
9
|
+
* (stigmer/stigmer#1384). An empty list is therefore not evidence that none
|
|
10
|
+
* is registered, so a caller who may not create channel apps is told who
|
|
11
|
+
* manages them instead of being told that nothing exists.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Shown in place of the empty state to a caller who may not create channel apps. */
|
|
15
|
+
export const CHANNEL_APPS_MANAGED_BY_ADMINS =
|
|
16
|
+
"Channel apps are managed by your organization's admins.";
|
|
@@ -8,9 +8,11 @@ import {
|
|
|
8
8
|
type ChannelAppCreateHandoff,
|
|
9
9
|
} from "../channel-app/CreateChannelAppForm.js";
|
|
10
10
|
import { ChannelAppDetailPanel } from "../channel-app/ChannelAppDetailPanel.js";
|
|
11
|
+
import { CHANNEL_APPS_MANAGED_BY_ADMINS } from "../channel-app/copy.js";
|
|
11
12
|
import { useDeploymentMode } from "../deployment-mode.js";
|
|
13
|
+
import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
|
|
12
14
|
import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
|
|
13
|
-
import { useActiveOrgSlug } from "../organization/OrgProvider.js";
|
|
15
|
+
import { useActiveOrgId, useActiveOrgSlug } from "../organization/OrgProvider.js";
|
|
14
16
|
|
|
15
17
|
type FlowState =
|
|
16
18
|
| { phase: "idle" }
|
|
@@ -36,13 +38,27 @@ type FlowState =
|
|
|
36
38
|
*
|
|
37
39
|
* After registering an app here, the connect dialog on any agent's
|
|
38
40
|
* Channels tab offers it as the serving app.
|
|
41
|
+
*
|
|
42
|
+
* "New channel app" is offered once the server confirms the caller holds
|
|
43
|
+
* `can_create_channel_app` on the organization. The list shows only the
|
|
44
|
+
* apps the caller may view (their creator, anyone granted viewer on one,
|
|
45
|
+
* and the organization's admins), so a caller who may not create channel
|
|
46
|
+
* apps is told that the organization's admins manage them rather than that
|
|
47
|
+
* none is registered.
|
|
39
48
|
*/
|
|
40
49
|
export function ChannelAppsSection() {
|
|
41
50
|
const headingId = useId();
|
|
42
51
|
const org = useActiveOrgSlug();
|
|
52
|
+
const orgId = useActiveOrgId();
|
|
43
53
|
// Channel installs (the consumer of these credentials) are cloud-only;
|
|
44
54
|
// gate the whole section the way the Channels tab gates connects.
|
|
45
55
|
const installsAvailable = useDeploymentMode() === "cloud";
|
|
56
|
+
const createCheck = useCheckPermission(
|
|
57
|
+
installsAvailable && orgId ? { kind: "organization", id: orgId } : null,
|
|
58
|
+
"can_create_channel_app",
|
|
59
|
+
);
|
|
60
|
+
const canCreate = !createCheck.isLoading && createCheck.allowed;
|
|
61
|
+
const deniedCreate = !createCheck.isLoading && !createCheck.allowed;
|
|
46
62
|
|
|
47
63
|
const [flow, setFlow] = useState<FlowState>({ phase: "idle" });
|
|
48
64
|
const listRefetchRef = useRef<(() => void) | null>(null);
|
|
@@ -82,7 +98,7 @@ export function ChannelAppsSection() {
|
|
|
82
98
|
Channel Apps
|
|
83
99
|
</h2>
|
|
84
100
|
|
|
85
|
-
{installsAvailable && org && flow.phase === "idle" && (
|
|
101
|
+
{installsAvailable && org && canCreate && flow.phase === "idle" && (
|
|
86
102
|
<button
|
|
87
103
|
type="button"
|
|
88
104
|
onClick={() => setFlow({ phase: "creating" })}
|
|
@@ -127,6 +143,7 @@ export function ChannelAppsSection() {
|
|
|
127
143
|
org={org}
|
|
128
144
|
onEdit={(app) => setFlow({ phase: "editing", channelApp: app })}
|
|
129
145
|
onRefetchRef={handleRefetchRef}
|
|
146
|
+
emptyState={deniedCreate ? CHANNEL_APPS_MANAGED_BY_ADMINS : undefined}
|
|
130
147
|
/>
|
|
131
148
|
)}
|
|
132
149
|
</section>
|