@burdenoff/microfe-devportal 2026.1113.1 → 2026.1113.3
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/dist/devportal/DevportalRoot.js +65 -119
- package/dist/devportal/DevportalRoot.js.map +1 -1
- package/dist/devportal/components/AppCard.js +4 -4
- package/dist/devportal/components/DeveloperSettingsHub.d.ts +6 -0
- package/dist/devportal/components/DeveloperSettingsHub.js +59 -0
- package/dist/devportal/components/DeveloperSettingsHub.js.map +1 -0
- package/dist/devportal/components/SectionNav.d.ts +1 -1
- package/dist/devportal/components/SectionNav.js +60 -36
- package/dist/devportal/components/SectionNav.js.map +1 -1
- package/dist/devportal/pages/AnalyticsDashboardPage.js +186 -179
- package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/devportal/pages/ApiKeysPage.js +113 -111
- package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
- package/dist/devportal/pages/AppLogsPage.js +80 -84
- package/dist/devportal/pages/AppLogsPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationDetailPage.js +529 -504
- package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationsPage.js +68 -67
- package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +163 -166
- package/dist/devportal/pages/CreateApiKeyPage.js.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +134 -130
- package/dist/devportal/pages/CreateOAuthClientPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +11 -11
- package/dist/devportal/pages/DocumentationPage.js +100 -94
- package/dist/devportal/pages/DocumentationPage.js.map +1 -1
- package/dist/devportal/pages/EditApplicationPage.js +379 -377
- package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
- package/dist/devportal/pages/InvitationDecisionPage.js +83 -79
- package/dist/devportal/pages/InvitationDecisionPage.js.map +1 -1
- package/dist/devportal/pages/OAuthClientDetailPage.js +76 -76
- package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
- package/dist/devportal/pages/OAuthClientsPage.js +126 -124
- package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationDetailPage.js +19 -19
- package/dist/devportal/pages/OrganizationMembersPage.js +223 -204
- package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
- package/dist/devportal/pages/ResourcesPage.d.ts +6 -0
- package/dist/devportal/pages/ResourcesPage.js +171 -155
- package/dist/devportal/pages/ResourcesPage.js.map +1 -1
- package/dist/devportal/pages/SellerDashboardPage.js +13 -13
- package/dist/devportal/pages/SellerItemsPage.js +4 -4
- package/dist/devportal/pages/SettingsPage.js +330 -315
- package/dist/devportal/pages/SettingsPage.js.map +1 -1
- package/dist/devportal/pages/SetupPage.js +5 -5
- package/dist/devportal/pages/WebhookDetailPage.js +6 -6
- package/dist/devportal/pages/WebhooksPage.js +39 -39
- package/dist/devportal/pages/WebhooksPage.js.map +1 -1
- package/dist/devportal/utils/appDetailTabs.d.ts +73 -0
- package/dist/devportal/utils/appDetailTabs.js +62 -0
- package/dist/devportal/utils/appDetailTabs.js.map +1 -0
- package/dist/devportal/utils/developerNav.d.ts +39 -0
- package/dist/devportal/utils/developerNav.js +304 -0
- package/dist/devportal/utils/developerNav.js.map +1 -0
- package/package.json +2 -2
|
@@ -2,248 +2,252 @@ import { PageLayout as e, PageSection as t } from "../components/PageLayout.js";
|
|
|
2
2
|
import { InputField as n, SelectField as r, TextareaField as i } from "../components/FormField.js";
|
|
3
3
|
import { useCreateAuthAppMutation as a } from "../../generated/global-operations.js";
|
|
4
4
|
import { getErrorMessage as o } from "../hooks/useGraphQL.js";
|
|
5
|
-
import { useDevportal as s } from "../providers/DevportalProvider.js";
|
|
5
|
+
import { useDevportal as s, useIsFluidgridsVariant as c } from "../providers/DevportalProvider.js";
|
|
6
6
|
import "../components/index.js";
|
|
7
|
-
import { cn as
|
|
8
|
-
import { PermissionGuard as
|
|
9
|
-
import { nativeCopyText as
|
|
7
|
+
import { cn as l } from "../utils/cn.js";
|
|
8
|
+
import { PermissionGuard as u } from "../components/PermissionGuard.js";
|
|
9
|
+
import { nativeCopyText as d, nativeImpact as f, nativeNotify as p } from "../../utils/nativeBridge.js";
|
|
10
10
|
import "../hooks/index.js";
|
|
11
|
-
import { useState as
|
|
12
|
-
import { Plus as
|
|
13
|
-
import { jsx as
|
|
14
|
-
import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
11
|
+
import { useState as m } from "react";
|
|
12
|
+
import { Plus as h, Save as g, Trash2 as _, X as v } from "lucide-react";
|
|
13
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
15
14
|
import { OptionalFields as x } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
import { useI18n as S } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
16
16
|
// src/devportal/pages/CreateOAuthClientPage.tsx
|
|
17
|
-
var
|
|
18
|
-
let { navigate:
|
|
19
|
-
let n =
|
|
17
|
+
var C = () => {
|
|
18
|
+
let { navigate: C, basePath: w } = s(), T = c(), { t: E } = S(), D = (e, t) => {
|
|
19
|
+
let n = E(e);
|
|
20
20
|
return n === e ? t : n;
|
|
21
|
-
}, [
|
|
22
|
-
|
|
23
|
-
}, J = () => {
|
|
24
|
-
let e = P.trim();
|
|
25
|
-
e && !M.includes(e) && (N([...M, e]), F(""));
|
|
26
|
-
}, Y = (e) => {
|
|
27
|
-
N(M.filter((t) => t !== e));
|
|
21
|
+
}, [O, k] = m(""), [A, j] = m(""), [M, N] = m("CONFIDENTIAL"), [P, F] = m([]), [I, L] = m(""), [R, z] = m([]), [B, V] = m(""), [H, U] = m(null), [W, G] = m(null), [K, { loading: q, error: J }] = a(), Y = (e) => {
|
|
22
|
+
C?.(`${w}${e}`);
|
|
28
23
|
}, X = () => {
|
|
29
|
-
let e =
|
|
30
|
-
e && !
|
|
24
|
+
let e = I.trim();
|
|
25
|
+
e && !P.includes(e) && (F([...P, e]), L(""));
|
|
31
26
|
}, Z = (e) => {
|
|
32
|
-
|
|
27
|
+
F(P.filter((t) => t !== e));
|
|
28
|
+
}, Q = () => {
|
|
29
|
+
let e = B.trim();
|
|
30
|
+
e && !R.includes(e) && (z([...R, e]), V(""));
|
|
31
|
+
}, $ = (e) => {
|
|
32
|
+
z(R.filter((t) => t !== e));
|
|
33
33
|
};
|
|
34
|
-
return
|
|
35
|
-
title:
|
|
36
|
-
description:
|
|
34
|
+
return H ? /* @__PURE__ */ y(e, {
|
|
35
|
+
title: D("devportal.appCreated", "App Created!"),
|
|
36
|
+
description: D("devportal.appCreatedDescription", "Save the client secret below. It will not be shown again."),
|
|
37
37
|
backLink: "/oauth",
|
|
38
|
-
backLabel:
|
|
39
|
-
children: /* @__PURE__ */
|
|
38
|
+
backLabel: D("devportal.backToOAuthApps", "Back to OAuth Apps"),
|
|
39
|
+
children: /* @__PURE__ */ b("div", {
|
|
40
40
|
className: "rounded-lg border border-border-subtle bg-status-success-bg-subtle p-6",
|
|
41
41
|
children: [
|
|
42
|
-
/* @__PURE__ */
|
|
42
|
+
/* @__PURE__ */ y("h3", {
|
|
43
43
|
className: "font-medium text-status-success-text",
|
|
44
|
-
children:
|
|
44
|
+
children: D("devportal.oauthAppCreated", "Your OAuth App has been created")
|
|
45
45
|
}),
|
|
46
|
-
/* @__PURE__ */
|
|
46
|
+
/* @__PURE__ */ b("div", {
|
|
47
47
|
className: "mt-4 space-y-3",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
|
|
49
49
|
className: "text-xs font-medium text-status-success-text",
|
|
50
|
-
children:
|
|
51
|
-
}), /* @__PURE__ */
|
|
50
|
+
children: D("devportal.clientSecret", "Client Secret")
|
|
51
|
+
}), /* @__PURE__ */ b("div", {
|
|
52
52
|
className: "mt-1 flex items-center gap-2",
|
|
53
|
-
children: [/* @__PURE__ */
|
|
53
|
+
children: [/* @__PURE__ */ y("code", {
|
|
54
54
|
className: "flex-1 rounded border bg-bg-surface px-3 py-2 text-sm font-mono break-all",
|
|
55
|
-
children:
|
|
56
|
-
}), /* @__PURE__ */
|
|
55
|
+
children: H
|
|
56
|
+
}), /* @__PURE__ */ y("button", {
|
|
57
57
|
onClick: async () => {
|
|
58
|
-
|
|
59
|
-
let e = await
|
|
60
|
-
|
|
58
|
+
f("light");
|
|
59
|
+
let e = await d(H);
|
|
60
|
+
p(e ? "success" : "error");
|
|
61
61
|
},
|
|
62
62
|
className: "rounded bg-status-success-bg-subtle px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle transition-colors",
|
|
63
|
-
children:
|
|
63
|
+
children: D("devportal.copy", "Copy")
|
|
64
64
|
})]
|
|
65
|
-
})] }), /* @__PURE__ */
|
|
65
|
+
})] }), /* @__PURE__ */ y("p", {
|
|
66
66
|
className: "text-sm text-status-success-text",
|
|
67
|
-
children:
|
|
67
|
+
children: D("devportal.storeSecretSecurely", "Store this secret securely. You will not be able to see it again.")
|
|
68
68
|
})]
|
|
69
69
|
}),
|
|
70
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ b("div", {
|
|
71
71
|
className: "mt-6 flex gap-3",
|
|
72
|
-
children: [
|
|
73
|
-
onClick: () =>
|
|
72
|
+
children: [W && /* @__PURE__ */ y("button", {
|
|
73
|
+
onClick: () => Y(`/oauth/${W}`),
|
|
74
74
|
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
|
|
75
|
-
children:
|
|
76
|
-
}), /* @__PURE__ */
|
|
77
|
-
onClick: () =>
|
|
75
|
+
children: D("devportal.viewAppDetails", "View App Details")
|
|
76
|
+
}), /* @__PURE__ */ y("button", {
|
|
77
|
+
onClick: () => Y("/oauth"),
|
|
78
78
|
className: "rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors",
|
|
79
|
-
children:
|
|
79
|
+
children: D("devportal.backToOAuthApps", "Back to OAuth Apps")
|
|
80
80
|
})]
|
|
81
81
|
})
|
|
82
82
|
]
|
|
83
83
|
})
|
|
84
|
-
}) : /* @__PURE__ */
|
|
84
|
+
}) : /* @__PURE__ */ y(u, {
|
|
85
85
|
authOnly: !0,
|
|
86
|
-
children: /* @__PURE__ */
|
|
87
|
-
title:
|
|
88
|
-
description:
|
|
89
|
-
purpose:
|
|
86
|
+
children: /* @__PURE__ */ y(e, {
|
|
87
|
+
title: D("devportal.createOAuthApp", "Create OAuth App"),
|
|
88
|
+
description: D("devportal.createOAuthAppDescription", "Register a new OAuth application for authentication"),
|
|
89
|
+
purpose: D("devportal.createOAuthAppPurpose", "Register an OAuth app so an external service can let users sign in with their account and call the API on their behalf. Set its redirect URIs and request only the scopes it needs — you will receive a client ID and secret to finish the integration."),
|
|
90
90
|
backLink: "/oauth",
|
|
91
|
-
backLabel:
|
|
92
|
-
children: /* @__PURE__ */
|
|
91
|
+
backLabel: D("devportal.backToOAuthApps", "Back to OAuth Apps"),
|
|
92
|
+
children: /* @__PURE__ */ b("form", {
|
|
93
93
|
onSubmit: async (e) => {
|
|
94
|
-
if (e.preventDefault(),
|
|
95
|
-
let e = await
|
|
96
|
-
name:
|
|
97
|
-
description:
|
|
98
|
-
type:
|
|
99
|
-
scopes:
|
|
100
|
-
redirectUris:
|
|
94
|
+
if (e.preventDefault(), O.trim()) try {
|
|
95
|
+
let e = await K({ variables: { input: {
|
|
96
|
+
name: O.trim(),
|
|
97
|
+
description: A.trim() || void 0,
|
|
98
|
+
type: M,
|
|
99
|
+
scopes: P,
|
|
100
|
+
redirectUris: R
|
|
101
101
|
} } }), t = e.data?.createApp?.clientSecret, n = e.data?.createApp?.app?.id;
|
|
102
|
-
t && (
|
|
102
|
+
t && (U(t), G(n || null));
|
|
103
103
|
} catch {}
|
|
104
104
|
},
|
|
105
105
|
className: "space-y-6 max-w-2xl",
|
|
106
106
|
children: [
|
|
107
|
-
|
|
107
|
+
J && /* @__PURE__ */ y("div", {
|
|
108
108
|
className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-4",
|
|
109
|
-
children: /* @__PURE__ */
|
|
109
|
+
children: /* @__PURE__ */ y("p", {
|
|
110
110
|
className: "text-sm text-status-error-text",
|
|
111
|
-
children: o(
|
|
111
|
+
children: o(J)
|
|
112
112
|
})
|
|
113
113
|
}),
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
title:
|
|
114
|
+
/* @__PURE__ */ b(t, {
|
|
115
|
+
title: D("devportal.basicInformation", "Basic Information"),
|
|
116
116
|
children: [
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
-
label:
|
|
119
|
-
value: E,
|
|
120
|
-
onChange: (e) => D(e.target.value),
|
|
121
|
-
placeholder: T("devportal.myOAuthAppPlaceholder", "My OAuth App"),
|
|
122
|
-
required: !0
|
|
123
|
-
}),
|
|
124
|
-
/* @__PURE__ */ v(i, {
|
|
125
|
-
label: T("devportal.description", "Description"),
|
|
117
|
+
/* @__PURE__ */ y(n, {
|
|
118
|
+
label: D("devportal.appName", "App Name"),
|
|
126
119
|
value: O,
|
|
127
120
|
onChange: (e) => k(e.target.value),
|
|
128
|
-
placeholder:
|
|
121
|
+
placeholder: D("devportal.myOAuthAppPlaceholder", "My OAuth App"),
|
|
122
|
+
required: !0
|
|
129
123
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
label:
|
|
124
|
+
/* @__PURE__ */ y(i, {
|
|
125
|
+
label: D("devportal.description", "Description"),
|
|
132
126
|
value: A,
|
|
133
127
|
onChange: (e) => j(e.target.value),
|
|
128
|
+
placeholder: D("devportal.appDescriptionPlaceholder", "Brief description of what this app does...")
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ y(r, {
|
|
131
|
+
label: D("devportal.appType", "App Type"),
|
|
132
|
+
value: M,
|
|
133
|
+
onChange: (e) => N(e.target.value),
|
|
134
134
|
options: [
|
|
135
135
|
{
|
|
136
136
|
value: "SERVICE",
|
|
137
|
-
label:
|
|
137
|
+
label: D("devportal.appTypeService", "Service (M2M)")
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
value: "INTEGRATION",
|
|
141
|
-
label:
|
|
141
|
+
label: D("devportal.appTypeIntegration", "Integration")
|
|
142
142
|
},
|
|
143
143
|
{
|
|
144
144
|
value: "BOT",
|
|
145
|
-
label:
|
|
145
|
+
label: D("devportal.appTypeBot", "Bot")
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
value: "WEB_APP",
|
|
149
|
-
label:
|
|
149
|
+
label: D("devportal.appTypeWebApp", "Web App")
|
|
150
150
|
},
|
|
151
151
|
{
|
|
152
152
|
value: "AUTOMATION",
|
|
153
|
-
label:
|
|
153
|
+
label: D("devportal.appTypeAutomation", "Automation")
|
|
154
154
|
}
|
|
155
155
|
]
|
|
156
156
|
})
|
|
157
157
|
]
|
|
158
158
|
}),
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
159
|
+
/* @__PURE__ */ b(x, {
|
|
160
|
+
...T ? {
|
|
161
|
+
storageKey: "devportal.oauth.create.more",
|
|
162
|
+
label: D("devportal.moreOptions", "More options")
|
|
163
|
+
} : {},
|
|
164
|
+
title: D("devportal.advancedOAuthSettings", "Advanced settings"),
|
|
165
|
+
description: T ? D("devportal.fluidgrids.oauthMoreOptionsDescription", "Scopes and redirect URIs.") : D("devportal.advancedOAuthSettingsDescription", "Advanced grant types, PKCE-required toggles, scope tuning, and redirect URIs."),
|
|
166
|
+
children: [/* @__PURE__ */ y(t, {
|
|
167
|
+
title: D("devportal.scopes", "Scopes"),
|
|
168
|
+
children: /* @__PURE__ */ b("div", {
|
|
165
169
|
className: "space-y-3",
|
|
166
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ b("div", {
|
|
167
171
|
className: "flex items-center gap-2",
|
|
168
|
-
children: [/* @__PURE__ */
|
|
172
|
+
children: [/* @__PURE__ */ y("input", {
|
|
169
173
|
type: "text",
|
|
170
|
-
value:
|
|
171
|
-
onChange: (e) =>
|
|
174
|
+
value: I,
|
|
175
|
+
onChange: (e) => L(e.target.value),
|
|
172
176
|
onKeyDown: (e) => {
|
|
173
|
-
e.key === "Enter" && (e.preventDefault(),
|
|
177
|
+
e.key === "Enter" && (e.preventDefault(), X());
|
|
174
178
|
},
|
|
175
179
|
placeholder: "e.g. workspace:read",
|
|
176
180
|
className: "flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
|
|
177
|
-
}), /* @__PURE__ */
|
|
181
|
+
}), /* @__PURE__ */ y("button", {
|
|
178
182
|
type: "button",
|
|
179
|
-
onClick:
|
|
183
|
+
onClick: X,
|
|
180
184
|
className: "rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors",
|
|
181
|
-
children: /* @__PURE__ */
|
|
185
|
+
children: /* @__PURE__ */ y(h, { size: 16 })
|
|
182
186
|
})]
|
|
183
|
-
}),
|
|
187
|
+
}), P.length > 0 && /* @__PURE__ */ y("div", {
|
|
184
188
|
className: "flex flex-wrap gap-2",
|
|
185
|
-
children:
|
|
189
|
+
children: P.map((e) => /* @__PURE__ */ b("span", {
|
|
186
190
|
className: "inline-flex items-center gap-1 rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
|
|
187
|
-
children: [e, /* @__PURE__ */
|
|
191
|
+
children: [e, /* @__PURE__ */ y("button", {
|
|
188
192
|
type: "button",
|
|
189
|
-
onClick: () =>
|
|
193
|
+
onClick: () => Z(e),
|
|
190
194
|
className: "hover:text-status-error-text",
|
|
191
|
-
children: /* @__PURE__ */ v
|
|
195
|
+
children: /* @__PURE__ */ y(v, { size: 12 })
|
|
192
196
|
})]
|
|
193
197
|
}, e))
|
|
194
198
|
})]
|
|
195
199
|
})
|
|
196
|
-
}), /* @__PURE__ */
|
|
197
|
-
title:
|
|
198
|
-
children: /* @__PURE__ */
|
|
200
|
+
}), /* @__PURE__ */ y(t, {
|
|
201
|
+
title: D("devportal.redirectUris", "Redirect URIs"),
|
|
202
|
+
children: /* @__PURE__ */ b("div", {
|
|
199
203
|
className: "space-y-3",
|
|
200
|
-
children: [/* @__PURE__ */
|
|
204
|
+
children: [/* @__PURE__ */ b("div", {
|
|
201
205
|
className: "flex items-center gap-2",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
206
|
+
children: [/* @__PURE__ */ y("input", {
|
|
203
207
|
type: "url",
|
|
204
|
-
value:
|
|
205
|
-
onChange: (e) =>
|
|
208
|
+
value: B,
|
|
209
|
+
onChange: (e) => V(e.target.value),
|
|
206
210
|
onKeyDown: (e) => {
|
|
207
|
-
e.key === "Enter" && (e.preventDefault(),
|
|
211
|
+
e.key === "Enter" && (e.preventDefault(), Q());
|
|
208
212
|
},
|
|
209
213
|
placeholder: "https://example.com/callback",
|
|
210
214
|
className: "flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
|
|
211
|
-
}), /* @__PURE__ */
|
|
215
|
+
}), /* @__PURE__ */ y("button", {
|
|
212
216
|
type: "button",
|
|
213
|
-
onClick:
|
|
217
|
+
onClick: Q,
|
|
214
218
|
className: "rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors",
|
|
215
|
-
children: /* @__PURE__ */
|
|
219
|
+
children: /* @__PURE__ */ y(h, { size: 16 })
|
|
216
220
|
})]
|
|
217
|
-
}),
|
|
221
|
+
}), R.length > 0 && /* @__PURE__ */ y("div", {
|
|
218
222
|
className: "space-y-2",
|
|
219
|
-
children:
|
|
223
|
+
children: R.map((e) => /* @__PURE__ */ b("div", {
|
|
220
224
|
className: "flex items-center gap-2",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
225
|
+
children: [/* @__PURE__ */ y("code", {
|
|
222
226
|
className: "flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
|
|
223
227
|
children: e
|
|
224
|
-
}), /* @__PURE__ */
|
|
228
|
+
}), /* @__PURE__ */ y("button", {
|
|
225
229
|
type: "button",
|
|
226
|
-
onClick: () =>
|
|
230
|
+
onClick: () => $(e),
|
|
227
231
|
className: "rounded p-1 text-text-secondary hover:text-status-error-text transition-colors",
|
|
228
|
-
children: /* @__PURE__ */
|
|
232
|
+
children: /* @__PURE__ */ y(_, { size: 14 })
|
|
229
233
|
})]
|
|
230
234
|
}, e))
|
|
231
235
|
})]
|
|
232
236
|
})
|
|
233
237
|
})]
|
|
234
238
|
}),
|
|
235
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ b("div", {
|
|
236
240
|
className: "flex items-center gap-3 pt-4 border-t",
|
|
237
|
-
children: [/* @__PURE__ */
|
|
241
|
+
children: [/* @__PURE__ */ b("button", {
|
|
238
242
|
type: "submit",
|
|
239
|
-
disabled:
|
|
240
|
-
className:
|
|
241
|
-
children: [/* @__PURE__ */
|
|
242
|
-
}), /* @__PURE__ */
|
|
243
|
+
disabled: q || !O.trim(),
|
|
244
|
+
className: l("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors", "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90", "disabled:opacity-50 disabled:cursor-not-allowed"),
|
|
245
|
+
children: [/* @__PURE__ */ y(g, { size: 16 }), q ? D("devportal.creating", "Creating...") : D("devportal.createOAuthApp", "Create OAuth App")]
|
|
246
|
+
}), /* @__PURE__ */ b("button", {
|
|
243
247
|
type: "button",
|
|
244
|
-
onClick: () =>
|
|
248
|
+
onClick: () => Y("/oauth"),
|
|
245
249
|
className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors",
|
|
246
|
-
children: [/* @__PURE__ */ v
|
|
250
|
+
children: [/* @__PURE__ */ y(v, { size: 16 }), D("devportal.cancel", "Cancel")]
|
|
247
251
|
})]
|
|
248
252
|
})
|
|
249
253
|
]
|
|
@@ -251,6 +255,6 @@ var S = () => {
|
|
|
251
255
|
})
|
|
252
256
|
});
|
|
253
257
|
};
|
|
254
|
-
export {
|
|
258
|
+
export { C as CreateOAuthClientPage };
|
|
255
259
|
|
|
256
260
|
//# sourceMappingURL=CreateOAuthClientPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOAuthClientPage.js","names":["CreateOAuthClientPage","useDevportal","useI18n","tr","value","t","key","fallback","name","setName","useState","description","setDescription","type","setType","scopes","setScopes","newScope","setNewScope","redirectUris","setRedirectUris","newUri","setNewUri","createdSecret","setCreatedSecret","createdAppId","setCreatedAppId","createApp","useCreateAuthAppMutation","handleNavigate","basePath","path","handleAddScope","trimmed","handleRemoveScope","s","scope","handleAddUri","handleRemoveUri","u","uri","PageLayout","ok","nativeCopyText","PermissionGuard","result","secret","appId","error","getErrorMessage","PageSection","InputField","TextareaField","SelectField","OptionalFields","Plus","X","Trash2","loading","cn","Save"],"sources":["../../../src/devportal/pages/CreateOAuthClientPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { Save, X, Plus, Trash2 } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { OptionalFields } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n InputField,\n SelectField,\n TextareaField,\n} from \"../components/FormField\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport { useCreateAuthAppMutation, getErrorMessage } from \"../hooks\";\n\n/**\n * Create OAuth App page\n *\n * Creates a new App in auth-svc (replaces devportal-svc CreateOAuthClient).\n * Shows the client secret once after creation.\n */\nexport const CreateOAuthClientPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [type, setType] = useState<string>(\"CONFIDENTIAL\");\n const [scopes, setScopes] = useState<string[]>([]);\n const [newScope, setNewScope] = useState(\"\");\n const [redirectUris, setRedirectUris] = useState<string[]>([]);\n const [newUri, setNewUri] = useState(\"\");\n\n const [createdSecret, setCreatedSecret] = useState<string | null>(null);\n const [createdAppId, setCreatedAppId] = useState<string | null>(null);\n\n const [createApp, { loading, error }] = useCreateAuthAppMutation();\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleAddScope = () => {\n const trimmed = newScope.trim();\n if (trimmed && !scopes.includes(trimmed)) {\n setScopes([...scopes, trimmed]);\n setNewScope(\"\");\n }\n };\n\n const handleRemoveScope = (scope: string) => {\n setScopes(scopes.filter((s) => s !== scope));\n };\n\n const handleAddUri = () => {\n const trimmed = newUri.trim();\n if (trimmed && !redirectUris.includes(trimmed)) {\n setRedirectUris([...redirectUris, trimmed]);\n setNewUri(\"\");\n }\n };\n\n const handleRemoveUri = (uri: string) => {\n setRedirectUris(redirectUris.filter((u) => u !== uri));\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!name.trim()) return;\n\n try {\n const result = await createApp({\n variables: {\n input: {\n name: name.trim(),\n description: description.trim() || undefined,\n type,\n scopes,\n redirectUris,\n },\n },\n });\n\n const secret = result.data?.createApp?.clientSecret;\n const appId = result.data?.createApp?.app?.id;\n if (secret) {\n setCreatedSecret(secret);\n setCreatedAppId(appId || null);\n }\n } catch {\n // error handled by Apollo\n }\n };\n\n // Success — show the secret\n if (createdSecret) {\n return (\n <PageLayout\n title={tr(\"devportal.appCreated\", \"App Created!\")}\n description={tr(\n \"devportal.appCreatedDescription\",\n \"Save the client secret below. It will not be shown again.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n >\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-6\">\n <h3 className=\"font-medium text-status-success-text\">\n {tr(\"devportal.oauthAppCreated\", \"Your OAuth App has been created\")}\n </h3>\n <div className=\"mt-4 space-y-3\">\n <div>\n <label className=\"text-xs font-medium text-status-success-text\">\n {tr(\"devportal.clientSecret\", \"Client Secret\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded border bg-bg-surface px-3 py-2 text-sm font-mono break-all\">\n {createdSecret}\n </code>\n <button\n onClick={async () => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(createdSecret);\n void nativeNotify(ok ? \"success\" : \"error\");\n }}\n className=\"rounded bg-status-success-bg-subtle px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle transition-colors\"\n >\n {tr(\"devportal.copy\", \"Copy\")}\n </button>\n </div>\n </div>\n <p className=\"text-sm text-status-success-text\">\n {tr(\n \"devportal.storeSecretSecurely\",\n \"Store this secret securely. You will not be able to see it again.\",\n )}\n </p>\n </div>\n <div className=\"mt-6 flex gap-3\">\n {createdAppId && (\n <button\n onClick={() => handleNavigate(`/oauth/${createdAppId}`)}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n {tr(\"devportal.viewAppDetails\", \"View App Details\")}\n </button>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n description={tr(\n \"devportal.createOAuthAppDescription\",\n \"Register a new OAuth application for authentication\",\n )}\n purpose={tr(\n \"devportal.createOAuthAppPurpose\",\n \"Register an OAuth app so an external service can let users sign in with their account and call the API on their behalf. Set its redirect URIs and request only the scopes it needs — you will receive a client ID and secret to finish the integration.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n >\n <form onSubmit={handleSubmit} className=\"space-y-6 max-w-2xl\">\n {error && (\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-4\">\n <p className=\"text-sm text-status-error-text\">\n {getErrorMessage(error)}\n </p>\n </div>\n )}\n\n <PageSection\n title={tr(\"devportal.basicInformation\", \"Basic Information\")}\n >\n <InputField\n label={tr(\"devportal.appName\", \"App Name\")}\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n \"devportal.myOAuthAppPlaceholder\",\n \"My OAuth App\",\n )}\n required\n />\n <TextareaField\n label={tr(\"devportal.description\", \"Description\")}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={tr(\n \"devportal.appDescriptionPlaceholder\",\n \"Brief description of what this app does...\",\n )}\n />\n <SelectField\n label={tr(\"devportal.appType\", \"App Type\")}\n value={type}\n onChange={(e) => setType(e.target.value)}\n options={[\n {\n value: \"SERVICE\",\n label: tr(\"devportal.appTypeService\", \"Service (M2M)\"),\n },\n {\n value: \"INTEGRATION\",\n label: tr(\"devportal.appTypeIntegration\", \"Integration\"),\n },\n { value: \"BOT\", label: tr(\"devportal.appTypeBot\", \"Bot\") },\n {\n value: \"WEB_APP\",\n label: tr(\"devportal.appTypeWebApp\", \"Web App\"),\n },\n {\n value: \"AUTOMATION\",\n label: tr(\"devportal.appTypeAutomation\", \"Automation\"),\n },\n ]}\n />\n </PageSection>\n\n {/* Advanced: grant types / PKCE-required toggles / scope tuning / redirect URIs — collapse the long-tail knobs */}\n <OptionalFields\n title={tr(\"devportal.advancedOAuthSettings\", \"Advanced settings\")}\n description={tr(\n \"devportal.advancedOAuthSettingsDescription\",\n \"Advanced grant types, PKCE-required toggles, scope tuning, and redirect URIs.\",\n )}\n >\n <PageSection title={tr(\"devportal.scopes\", \"Scopes\")}>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={newScope}\n onChange={(e) => setNewScope(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleAddScope();\n }\n }}\n placeholder=\"e.g. workspace:read\"\n className=\"flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n <button\n type=\"button\"\n onClick={handleAddScope}\n className=\"rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors\"\n >\n <Plus size={16} />\n </button>\n </div>\n {scopes.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {scopes.map((scope) => (\n <span\n key={scope}\n className=\"inline-flex items-center gap-1 rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n <button\n type=\"button\"\n onClick={() => handleRemoveScope(scope)}\n className=\"hover:text-status-error-text\"\n >\n <X size={12} />\n </button>\n </span>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n\n <PageSection title={tr(\"devportal.redirectUris\", \"Redirect URIs\")}>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"url\"\n value={newUri}\n onChange={(e) => setNewUri(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleAddUri();\n }\n }}\n placeholder=\"https://example.com/callback\"\n className=\"flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n <button\n type=\"button\"\n onClick={handleAddUri}\n className=\"rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors\"\n >\n <Plus size={16} />\n </button>\n </div>\n {redirectUris.length > 0 && (\n <div className=\"space-y-2\">\n {redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n type=\"button\"\n onClick={() => handleRemoveUri(uri)}\n className=\"rounded p-1 text-text-secondary hover:text-status-error-text transition-colors\"\n >\n <Trash2 size={14} />\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n </OptionalFields>\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-4 border-t\">\n <button\n type=\"submit\"\n disabled={loading || !name.trim()}\n className={cn(\n \"inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors\",\n \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <Save size={16} />\n {loading\n ? tr(\"devportal.creating\", \"Creating...\")\n : tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <X size={16} />\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n </div>\n </form>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateOAuthClientPage.js","names":["CreateOAuthClientPage","useDevportal","isFluidgrids","useIsFluidgridsVariant","useI18n","tr","value","t","key","fallback","name","setName","useState","description","setDescription","type","setType","scopes","setScopes","newScope","setNewScope","redirectUris","setRedirectUris","newUri","setNewUri","createdSecret","setCreatedSecret","createdAppId","setCreatedAppId","createApp","useCreateAuthAppMutation","handleNavigate","basePath","path","handleAddScope","trimmed","handleRemoveScope","s","scope","handleAddUri","handleRemoveUri","u","uri","PageLayout","ok","nativeCopyText","PermissionGuard","result","secret","appId","error","getErrorMessage","PageSection","InputField","TextareaField","SelectField","OptionalFields","Plus","X","Trash2","loading","cn","Save"],"sources":["../../../src/devportal/pages/CreateOAuthClientPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { Save, X, Plus, Trash2 } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { OptionalFields } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n InputField,\n SelectField,\n TextareaField,\n} from \"../components/FormField\";\nimport {\n useDevportal,\n useIsFluidgridsVariant,\n} from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport { useCreateAuthAppMutation, getErrorMessage } from \"../hooks\";\n\n/**\n * Create OAuth App page\n *\n * Creates a new App in auth-svc (replaces devportal-svc CreateOAuthClient).\n * Shows the client secret once after creation.\n */\nexport const CreateOAuthClientPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const isFluidgrids = useIsFluidgridsVariant();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [type, setType] = useState<string>(\"CONFIDENTIAL\");\n const [scopes, setScopes] = useState<string[]>([]);\n const [newScope, setNewScope] = useState(\"\");\n const [redirectUris, setRedirectUris] = useState<string[]>([]);\n const [newUri, setNewUri] = useState(\"\");\n\n const [createdSecret, setCreatedSecret] = useState<string | null>(null);\n const [createdAppId, setCreatedAppId] = useState<string | null>(null);\n\n const [createApp, { loading, error }] = useCreateAuthAppMutation();\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleAddScope = () => {\n const trimmed = newScope.trim();\n if (trimmed && !scopes.includes(trimmed)) {\n setScopes([...scopes, trimmed]);\n setNewScope(\"\");\n }\n };\n\n const handleRemoveScope = (scope: string) => {\n setScopes(scopes.filter((s) => s !== scope));\n };\n\n const handleAddUri = () => {\n const trimmed = newUri.trim();\n if (trimmed && !redirectUris.includes(trimmed)) {\n setRedirectUris([...redirectUris, trimmed]);\n setNewUri(\"\");\n }\n };\n\n const handleRemoveUri = (uri: string) => {\n setRedirectUris(redirectUris.filter((u) => u !== uri));\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!name.trim()) return;\n\n try {\n const result = await createApp({\n variables: {\n input: {\n name: name.trim(),\n description: description.trim() || undefined,\n type,\n scopes,\n redirectUris,\n },\n },\n });\n\n const secret = result.data?.createApp?.clientSecret;\n const appId = result.data?.createApp?.app?.id;\n if (secret) {\n setCreatedSecret(secret);\n setCreatedAppId(appId || null);\n }\n } catch {\n // error handled by Apollo\n }\n };\n\n // Success — show the secret\n if (createdSecret) {\n return (\n <PageLayout\n title={tr(\"devportal.appCreated\", \"App Created!\")}\n description={tr(\n \"devportal.appCreatedDescription\",\n \"Save the client secret below. It will not be shown again.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n >\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-6\">\n <h3 className=\"font-medium text-status-success-text\">\n {tr(\"devportal.oauthAppCreated\", \"Your OAuth App has been created\")}\n </h3>\n <div className=\"mt-4 space-y-3\">\n <div>\n <label className=\"text-xs font-medium text-status-success-text\">\n {tr(\"devportal.clientSecret\", \"Client Secret\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded border bg-bg-surface px-3 py-2 text-sm font-mono break-all\">\n {createdSecret}\n </code>\n <button\n onClick={async () => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(createdSecret);\n void nativeNotify(ok ? \"success\" : \"error\");\n }}\n className=\"rounded bg-status-success-bg-subtle px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle transition-colors\"\n >\n {tr(\"devportal.copy\", \"Copy\")}\n </button>\n </div>\n </div>\n <p className=\"text-sm text-status-success-text\">\n {tr(\n \"devportal.storeSecretSecurely\",\n \"Store this secret securely. You will not be able to see it again.\",\n )}\n </p>\n </div>\n <div className=\"mt-6 flex gap-3\">\n {createdAppId && (\n <button\n onClick={() => handleNavigate(`/oauth/${createdAppId}`)}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n {tr(\"devportal.viewAppDetails\", \"View App Details\")}\n </button>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n description={tr(\n \"devportal.createOAuthAppDescription\",\n \"Register a new OAuth application for authentication\",\n )}\n purpose={tr(\n \"devportal.createOAuthAppPurpose\",\n \"Register an OAuth app so an external service can let users sign in with their account and call the API on their behalf. Set its redirect URIs and request only the scopes it needs — you will receive a client ID and secret to finish the integration.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToOAuthApps\", \"Back to OAuth Apps\")}\n >\n <form onSubmit={handleSubmit} className=\"space-y-6 max-w-2xl\">\n {error && (\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-4\">\n <p className=\"text-sm text-status-error-text\">\n {getErrorMessage(error)}\n </p>\n </div>\n )}\n\n <PageSection\n title={tr(\"devportal.basicInformation\", \"Basic Information\")}\n >\n <InputField\n label={tr(\"devportal.appName\", \"App Name\")}\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n \"devportal.myOAuthAppPlaceholder\",\n \"My OAuth App\",\n )}\n required\n />\n <TextareaField\n label={tr(\"devportal.description\", \"Description\")}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={tr(\n \"devportal.appDescriptionPlaceholder\",\n \"Brief description of what this app does...\",\n )}\n />\n <SelectField\n label={tr(\"devportal.appType\", \"App Type\")}\n value={type}\n onChange={(e) => setType(e.target.value)}\n options={[\n {\n value: \"SERVICE\",\n label: tr(\"devportal.appTypeService\", \"Service (M2M)\"),\n },\n {\n value: \"INTEGRATION\",\n label: tr(\"devportal.appTypeIntegration\", \"Integration\"),\n },\n { value: \"BOT\", label: tr(\"devportal.appTypeBot\", \"Bot\") },\n {\n value: \"WEB_APP\",\n label: tr(\"devportal.appTypeWebApp\", \"Web App\"),\n },\n {\n value: \"AUTOMATION\",\n label: tr(\"devportal.appTypeAutomation\", \"Automation\"),\n },\n ]}\n />\n </PageSection>\n\n {/* Advanced: grant types / PKCE-required toggles / scope tuning / redirect URIs — collapse the long-tail knobs */}\n <OptionalFields\n {...(isFluidgrids\n ? {\n storageKey: \"devportal.oauth.create.more\",\n label: tr(\"devportal.moreOptions\", \"More options\"),\n }\n : {})}\n title={tr(\"devportal.advancedOAuthSettings\", \"Advanced settings\")}\n description={\n isFluidgrids\n ? tr(\n \"devportal.fluidgrids.oauthMoreOptionsDescription\",\n \"Scopes and redirect URIs.\",\n )\n : tr(\n \"devportal.advancedOAuthSettingsDescription\",\n \"Advanced grant types, PKCE-required toggles, scope tuning, and redirect URIs.\",\n )\n }\n >\n <PageSection title={tr(\"devportal.scopes\", \"Scopes\")}>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={newScope}\n onChange={(e) => setNewScope(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleAddScope();\n }\n }}\n placeholder=\"e.g. workspace:read\"\n className=\"flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n <button\n type=\"button\"\n onClick={handleAddScope}\n className=\"rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors\"\n >\n <Plus size={16} />\n </button>\n </div>\n {scopes.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {scopes.map((scope) => (\n <span\n key={scope}\n className=\"inline-flex items-center gap-1 rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n <button\n type=\"button\"\n onClick={() => handleRemoveScope(scope)}\n className=\"hover:text-status-error-text\"\n >\n <X size={12} />\n </button>\n </span>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n\n <PageSection title={tr(\"devportal.redirectUris\", \"Redirect URIs\")}>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"url\"\n value={newUri}\n onChange={(e) => setNewUri(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleAddUri();\n }\n }}\n placeholder=\"https://example.com/callback\"\n className=\"flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n <button\n type=\"button\"\n onClick={handleAddUri}\n className=\"rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors\"\n >\n <Plus size={16} />\n </button>\n </div>\n {redirectUris.length > 0 && (\n <div className=\"space-y-2\">\n {redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n type=\"button\"\n onClick={() => handleRemoveUri(uri)}\n className=\"rounded p-1 text-text-secondary hover:text-status-error-text transition-colors\"\n >\n <Trash2 size={14} />\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n </OptionalFields>\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-4 border-t\">\n <button\n type=\"submit\"\n disabled={loading || !name.trim()}\n className={cn(\n \"inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors\",\n \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <Save size={16} />\n {loading\n ? tr(\"devportal.creating\", \"Creating...\")\n : tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <X size={16} />\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n </div>\n </form>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
@@ -12,8 +12,8 @@ import { useCurrentUserDelegationsQuery as l, useCurrentUserGrantedDelegationsQu
|
|
|
12
12
|
import { useCallback as u, useEffect as d, useMemo as ne, useState as f } from "react";
|
|
13
13
|
import { AlertCircle as p, AlertTriangle as m, Bot as h, Clock as g, Cog as _, Loader2 as v, Shield as y, Users as b, XCircle as x, Zap as S } from "lucide-react";
|
|
14
14
|
import { Fragment as re, jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { EmphasisPanel as ie, GlassCard as T } from "@burdenoff/fe-libs/ui";
|
|
16
|
+
import { useI18n as E } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
17
17
|
// src/devportal/pages/DelegationsPage.tsx
|
|
18
18
|
function D(e) {
|
|
19
19
|
return {
|
|
@@ -75,7 +75,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
75
75
|
})]
|
|
76
76
|
})
|
|
77
77
|
})), oe = ({ message: e, onRetry: t }) => {
|
|
78
|
-
let { t: n } =
|
|
78
|
+
let { t: n } = E();
|
|
79
79
|
return /* @__PURE__ */ C("div", {
|
|
80
80
|
className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-4",
|
|
81
81
|
children: /* @__PURE__ */ w("div", {
|
|
@@ -98,7 +98,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
98
98
|
})
|
|
99
99
|
});
|
|
100
100
|
}, se = ({ delegation: e, onRevoke: t, isRevoking: n, selected: r, onToggleSelect: o, canRevoke: s }) => {
|
|
101
|
-
let { t: c } =
|
|
101
|
+
let { t: c } = E(), l = (e, t) => {
|
|
102
102
|
let n = c(e);
|
|
103
103
|
return n === e ? t : n;
|
|
104
104
|
};
|
|
@@ -201,7 +201,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
201
201
|
})
|
|
202
202
|
});
|
|
203
203
|
}, ce = ({ delegation: e, onRevoke: t, isRevoking: n, selected: r, onToggleSelect: o, canRevoke: s }) => {
|
|
204
|
-
let { t: c } =
|
|
204
|
+
let { t: c } = E(), l = (e, t) => {
|
|
205
205
|
let n = c(e);
|
|
206
206
|
return n === e ? t : n;
|
|
207
207
|
};
|
|
@@ -292,7 +292,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
292
292
|
})
|
|
293
293
|
});
|
|
294
294
|
}, le = ({ delegations: e }) => {
|
|
295
|
-
let { t } =
|
|
295
|
+
let { t } = E(), n = (e, n) => {
|
|
296
296
|
let r = t(e);
|
|
297
297
|
return r === e ? n : r;
|
|
298
298
|
};
|
|
@@ -329,7 +329,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
329
329
|
})]
|
|
330
330
|
});
|
|
331
331
|
}, M = () => {
|
|
332
|
-
let { t: d } =
|
|
332
|
+
let { t: d } = E(), h = (e, t) => {
|
|
333
333
|
let n = d(e);
|
|
334
334
|
return n === e ? t : n;
|
|
335
335
|
}, { allowed: _ } = c(s.DELEGATION_REVOKE), [v, x] = f("acting-as-me"), [S, O] = f([]), [k, A] = f(null), [j, M] = f(/* @__PURE__ */ new Set()), { data: N, loading: ue, error: de, refetch: P } = l({ fetchPolicy: "cache-and-network" }), { data: F, loading: fe, error: pe, refetch: I } = ee({ fetchPolicy: "cache-and-network" }), [L, { loading: R }] = te(), z = (N?.currentUserDelegations?.delegations ?? []).map(D), B = (F?.currentUserGrantedDelegations?.delegations ?? []).map(D), V = z.filter((e) => e.status === "ACTIVE"), H = z.filter((e) => e.status !== "ACTIVE"), U = B.filter((e) => e.status === "ACTIVE"), W = v === "acting-as-me" ? V : U, G = ne(() => W.filter((e) => j.has(e.id)), [j, W]), K = W.length > 0 && W.every((e) => j.has(e.id)), me = W.some((e) => j.has(e.id)) && !K, q = v === "acting-as-me" ? ue : fe, J = v === "acting-as-me" ? de : pe, Y = u((e) => {
|
|
@@ -393,7 +393,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
393
393
|
/* @__PURE__ */ C(ie, { children: /* @__PURE__ */ w("div", {
|
|
394
394
|
className: "grid grid-cols-2 gap-4 sm:grid-cols-4",
|
|
395
395
|
children: [
|
|
396
|
-
/* @__PURE__ */ w(
|
|
396
|
+
/* @__PURE__ */ w(T, {
|
|
397
397
|
treatment: "metric",
|
|
398
398
|
className: "p-4",
|
|
399
399
|
children: [/* @__PURE__ */ w("div", {
|
|
@@ -407,7 +407,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
407
407
|
children: Q
|
|
408
408
|
})]
|
|
409
409
|
}),
|
|
410
|
-
/* @__PURE__ */ w(
|
|
410
|
+
/* @__PURE__ */ w(T, {
|
|
411
411
|
treatment: "metric",
|
|
412
412
|
className: "p-4",
|
|
413
413
|
children: [/* @__PURE__ */ w("div", {
|
|
@@ -421,7 +421,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
421
421
|
children: $
|
|
422
422
|
})]
|
|
423
423
|
}),
|
|
424
|
-
/* @__PURE__ */ w(
|
|
424
|
+
/* @__PURE__ */ w(T, {
|
|
425
425
|
treatment: "metric",
|
|
426
426
|
className: "p-4",
|
|
427
427
|
children: [/* @__PURE__ */ w("div", {
|
|
@@ -435,7 +435,7 @@ var A = ({ type: e, className: t }) => {
|
|
|
435
435
|
children: H.length
|
|
436
436
|
})]
|
|
437
437
|
}),
|
|
438
|
-
/* @__PURE__ */ w(
|
|
438
|
+
/* @__PURE__ */ w(T, {
|
|
439
439
|
treatment: "metric",
|
|
440
440
|
className: "p-4",
|
|
441
441
|
children: [/* @__PURE__ */ w("div", {
|