@burdenoff/microfe-devportal 2026.720.5 → 2026.720.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devportal/components/MarkdownEditor.d.ts +24 -0
- package/dist/devportal/components/MarkdownEditor.d.ts.map +1 -0
- package/dist/devportal/components/MarkdownEditor.js +136 -0
- package/dist/devportal/components/MarkdownEditor.js.map +1 -0
- package/dist/devportal/components/index.d.ts +1 -0
- package/dist/devportal/components/index.d.ts.map +1 -1
- package/dist/devportal/components/index.js +1 -0
- package/dist/devportal/hooks/usePackageUpload.d.ts.map +1 -1
- package/dist/devportal/hooks/usePackageUpload.js.map +1 -1
- package/dist/devportal/pages/ApplicationDetailPage.d.ts.map +1 -1
- package/dist/devportal/pages/ApplicationDetailPage.js +748 -746
- package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationVersionsPage.d.ts.map +1 -1
- package/dist/devportal/pages/ApplicationVersionsPage.js +390 -374
- package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +103 -104
- package/dist/devportal/pages/CreateApiKeyPage.js.map +1 -1
- package/dist/devportal/pages/CreateApplicationPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateApplicationPage.js +103 -103
- package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +129 -130
- package/dist/devportal/pages/CreateOAuthClientPage.js.map +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +214 -214
- package/dist/devportal/pages/DelegationsPage.js.map +1 -1
- package/dist/devportal/pages/EditApplicationPage.d.ts.map +1 -1
- package/dist/devportal/pages/EditApplicationPage.js +285 -284
- package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.d.ts.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.js +162 -158
- package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
- package/dist/devportal/pages/PublishPage.d.ts.map +1 -1
- package/dist/devportal/pages/PublishPage.js +106 -106
- package/dist/devportal/pages/PublishPage.js.map +1 -1
- package/dist/devportal/pages/SellerDashboardPage.d.ts.map +1 -1
- package/dist/devportal/pages/SellerDashboardPage.js +136 -137
- package/dist/devportal/pages/SellerDashboardPage.js.map +1 -1
- package/dist/devportal/pages/SellerItemsPage.d.ts.map +1 -1
- package/dist/devportal/pages/SellerItemsPage.js +190 -191
- package/dist/devportal/pages/SellerItemsPage.js.map +1 -1
- package/dist/devportal/pages/SellerOrdersPage.d.ts.map +1 -1
- package/dist/devportal/pages/SellerOrdersPage.js +138 -139
- package/dist/devportal/pages/SellerOrdersPage.js.map +1 -1
- package/dist/devportal/types/index.d.ts.map +1 -1
- package/dist/devportal/types/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -8,241 +8,240 @@ import { InputField as l, SelectField as u, TextareaField as d } from "../compon
|
|
|
8
8
|
import { PermissionGuard as f } from "../components/PermissionGuard.js";
|
|
9
9
|
import "../components/index.js";
|
|
10
10
|
import "../hooks/index.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { OptionalFields as S } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { useState as p } from "react";
|
|
12
|
+
import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
13
|
+
import { Plus as h, Save as g, Trash2 as _, X as v } from "lucide-react";
|
|
14
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
15
|
+
import { OptionalFields as x } from "@burdenoff/fe-libs/ui";
|
|
17
16
|
//#region src/devportal/pages/CreateOAuthClientPage.tsx
|
|
18
|
-
var
|
|
19
|
-
let { navigate:
|
|
20
|
-
let n =
|
|
17
|
+
var S = () => {
|
|
18
|
+
let { navigate: S, basePath: C } = e(), { t: w } = m(), T = (e, t) => {
|
|
19
|
+
let n = w(e);
|
|
21
20
|
return n === e ? t : n;
|
|
22
|
-
}, [
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
let e =
|
|
26
|
-
e && !
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
let e =
|
|
31
|
-
e && !
|
|
32
|
-
},
|
|
33
|
-
|
|
21
|
+
}, [E, D] = p(""), [O, k] = p(""), [A, j] = p("CONFIDENTIAL"), [M, N] = p([]), [P, F] = p(""), [I, L] = p([]), [R, z] = p(""), [B, V] = p(null), [H, U] = p(null), [W, { loading: G, error: K }] = n(), q = (e) => {
|
|
22
|
+
S?.(`${C}${e}`);
|
|
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));
|
|
28
|
+
}, X = () => {
|
|
29
|
+
let e = R.trim();
|
|
30
|
+
e && !I.includes(e) && (L([...I, e]), z(""));
|
|
31
|
+
}, Z = (e) => {
|
|
32
|
+
L(I.filter((t) => t !== e));
|
|
34
33
|
};
|
|
35
|
-
return
|
|
36
|
-
title:
|
|
37
|
-
description:
|
|
34
|
+
return B ? /* @__PURE__ */ y(i, {
|
|
35
|
+
title: T("devportal.appCreated", "App Created!"),
|
|
36
|
+
description: T("devportal.appCreatedDescription", "Save the client secret below. It will not be shown again."),
|
|
38
37
|
backLink: "/oauth",
|
|
39
|
-
backLabel:
|
|
40
|
-
children: /* @__PURE__ */
|
|
38
|
+
backLabel: T("devportal.backToOAuthApps", "Back to OAuth Apps"),
|
|
39
|
+
children: /* @__PURE__ */ b("div", {
|
|
41
40
|
className: "rounded-lg border border-border-subtle bg-status-success-bg-subtle p-6",
|
|
42
41
|
children: [
|
|
43
|
-
/* @__PURE__ */
|
|
42
|
+
/* @__PURE__ */ y("h3", {
|
|
44
43
|
className: "font-medium text-status-success-text",
|
|
45
|
-
children:
|
|
44
|
+
children: T("devportal.oauthAppCreated", "Your OAuth App has been created")
|
|
46
45
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
46
|
+
/* @__PURE__ */ b("div", {
|
|
48
47
|
className: "mt-4 space-y-3",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
|
|
50
49
|
className: "text-xs font-medium text-status-success-text",
|
|
51
|
-
children:
|
|
52
|
-
}), /* @__PURE__ */
|
|
50
|
+
children: T("devportal.clientSecret", "Client Secret")
|
|
51
|
+
}), /* @__PURE__ */ b("div", {
|
|
53
52
|
className: "mt-1 flex items-center gap-2",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
53
|
+
children: [/* @__PURE__ */ y("code", {
|
|
55
54
|
className: "flex-1 rounded border bg-bg-surface px-3 py-2 text-sm font-mono break-all",
|
|
56
|
-
children:
|
|
57
|
-
}), /* @__PURE__ */
|
|
55
|
+
children: B
|
|
56
|
+
}), /* @__PURE__ */ y("button", {
|
|
58
57
|
onClick: async () => {
|
|
59
|
-
s("light"), c(await o(
|
|
58
|
+
s("light"), c(await o(B) ? "success" : "error");
|
|
60
59
|
},
|
|
61
60
|
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",
|
|
62
|
-
children:
|
|
61
|
+
children: T("devportal.copy", "Copy")
|
|
63
62
|
})]
|
|
64
|
-
})] }), /* @__PURE__ */
|
|
63
|
+
})] }), /* @__PURE__ */ y("p", {
|
|
65
64
|
className: "text-sm text-status-success-text",
|
|
66
|
-
children:
|
|
65
|
+
children: T("devportal.storeSecretSecurely", "Store this secret securely. You will not be able to see it again.")
|
|
67
66
|
})]
|
|
68
67
|
}),
|
|
69
|
-
/* @__PURE__ */
|
|
68
|
+
/* @__PURE__ */ b("div", {
|
|
70
69
|
className: "mt-6 flex gap-3",
|
|
71
|
-
children: [
|
|
72
|
-
onClick: () =>
|
|
70
|
+
children: [H && /* @__PURE__ */ y("button", {
|
|
71
|
+
onClick: () => q(`/oauth/${H}`),
|
|
73
72
|
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",
|
|
74
|
-
children:
|
|
75
|
-
}), /* @__PURE__ */
|
|
76
|
-
onClick: () =>
|
|
73
|
+
children: T("devportal.viewAppDetails", "View App Details")
|
|
74
|
+
}), /* @__PURE__ */ y("button", {
|
|
75
|
+
onClick: () => q("/oauth"),
|
|
77
76
|
className: "rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors",
|
|
78
|
-
children:
|
|
77
|
+
children: T("devportal.backToOAuthApps", "Back to OAuth Apps")
|
|
79
78
|
})]
|
|
80
79
|
})
|
|
81
80
|
]
|
|
82
81
|
})
|
|
83
|
-
}) : /* @__PURE__ */
|
|
84
|
-
|
|
85
|
-
children: /* @__PURE__ */
|
|
86
|
-
title:
|
|
87
|
-
description:
|
|
88
|
-
purpose:
|
|
82
|
+
}) : /* @__PURE__ */ y(f, {
|
|
83
|
+
authOnly: !0,
|
|
84
|
+
children: /* @__PURE__ */ y(i, {
|
|
85
|
+
title: T("devportal.createOAuthApp", "Create OAuth App"),
|
|
86
|
+
description: T("devportal.createOAuthAppDescription", "Register a new OAuth application for authentication"),
|
|
87
|
+
purpose: T("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."),
|
|
89
88
|
backLink: "/oauth",
|
|
90
|
-
backLabel:
|
|
91
|
-
children: /* @__PURE__ */
|
|
89
|
+
backLabel: T("devportal.backToOAuthApps", "Back to OAuth Apps"),
|
|
90
|
+
children: /* @__PURE__ */ b("form", {
|
|
92
91
|
onSubmit: async (e) => {
|
|
93
|
-
if (e.preventDefault(),
|
|
94
|
-
let e = await
|
|
95
|
-
name:
|
|
96
|
-
description:
|
|
97
|
-
type:
|
|
98
|
-
scopes:
|
|
99
|
-
redirectUris:
|
|
92
|
+
if (e.preventDefault(), E.trim()) try {
|
|
93
|
+
let e = await W({ variables: { input: {
|
|
94
|
+
name: E.trim(),
|
|
95
|
+
description: O.trim() || void 0,
|
|
96
|
+
type: A,
|
|
97
|
+
scopes: M,
|
|
98
|
+
redirectUris: I
|
|
100
99
|
} } }), t = e.data?.createApp?.clientSecret, n = e.data?.createApp?.app?.id;
|
|
101
|
-
t && (
|
|
100
|
+
t && (V(t), U(n || null));
|
|
102
101
|
} catch {}
|
|
103
102
|
},
|
|
104
103
|
className: "space-y-6 max-w-2xl",
|
|
105
104
|
children: [
|
|
106
|
-
|
|
105
|
+
K && /* @__PURE__ */ y("div", {
|
|
107
106
|
className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-4",
|
|
108
|
-
children: /* @__PURE__ */
|
|
107
|
+
children: /* @__PURE__ */ y("p", {
|
|
109
108
|
className: "text-sm text-status-error-text",
|
|
110
|
-
children: r(
|
|
109
|
+
children: r(K)
|
|
111
110
|
})
|
|
112
111
|
}),
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
-
title:
|
|
112
|
+
/* @__PURE__ */ b(a, {
|
|
113
|
+
title: T("devportal.basicInformation", "Basic Information"),
|
|
115
114
|
children: [
|
|
116
|
-
/* @__PURE__ */
|
|
117
|
-
label:
|
|
118
|
-
value:
|
|
119
|
-
onChange: (e) =>
|
|
120
|
-
placeholder:
|
|
115
|
+
/* @__PURE__ */ y(l, {
|
|
116
|
+
label: T("devportal.appName", "App Name"),
|
|
117
|
+
value: E,
|
|
118
|
+
onChange: (e) => D(e.target.value),
|
|
119
|
+
placeholder: T("devportal.myOAuthAppPlaceholder", "My OAuth App"),
|
|
121
120
|
required: !0
|
|
122
121
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
label:
|
|
125
|
-
value:
|
|
126
|
-
onChange: (e) =>
|
|
127
|
-
placeholder:
|
|
122
|
+
/* @__PURE__ */ y(d, {
|
|
123
|
+
label: T("devportal.description", "Description"),
|
|
124
|
+
value: O,
|
|
125
|
+
onChange: (e) => k(e.target.value),
|
|
126
|
+
placeholder: T("devportal.appDescriptionPlaceholder", "Brief description of what this app does...")
|
|
128
127
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
-
label:
|
|
131
|
-
value:
|
|
132
|
-
onChange: (e) =>
|
|
128
|
+
/* @__PURE__ */ y(u, {
|
|
129
|
+
label: T("devportal.appType", "App Type"),
|
|
130
|
+
value: A,
|
|
131
|
+
onChange: (e) => j(e.target.value),
|
|
133
132
|
options: [
|
|
134
133
|
{
|
|
135
134
|
value: "SERVICE",
|
|
136
|
-
label:
|
|
135
|
+
label: T("devportal.appTypeService", "Service (M2M)")
|
|
137
136
|
},
|
|
138
137
|
{
|
|
139
138
|
value: "INTEGRATION",
|
|
140
|
-
label:
|
|
139
|
+
label: T("devportal.appTypeIntegration", "Integration")
|
|
141
140
|
},
|
|
142
141
|
{
|
|
143
142
|
value: "BOT",
|
|
144
|
-
label:
|
|
143
|
+
label: T("devportal.appTypeBot", "Bot")
|
|
145
144
|
},
|
|
146
145
|
{
|
|
147
146
|
value: "WEB_APP",
|
|
148
|
-
label:
|
|
147
|
+
label: T("devportal.appTypeWebApp", "Web App")
|
|
149
148
|
},
|
|
150
149
|
{
|
|
151
150
|
value: "AUTOMATION",
|
|
152
|
-
label:
|
|
151
|
+
label: T("devportal.appTypeAutomation", "Automation")
|
|
153
152
|
}
|
|
154
153
|
]
|
|
155
154
|
})
|
|
156
155
|
]
|
|
157
156
|
}),
|
|
158
|
-
/* @__PURE__ */ x
|
|
159
|
-
title:
|
|
160
|
-
description:
|
|
161
|
-
children: [/* @__PURE__ */
|
|
162
|
-
title:
|
|
163
|
-
children: /* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ b(x, {
|
|
158
|
+
title: T("devportal.advancedOAuthSettings", "Advanced settings"),
|
|
159
|
+
description: T("devportal.advancedOAuthSettingsDescription", "Advanced grant types, PKCE-required toggles, scope tuning, and redirect URIs."),
|
|
160
|
+
children: [/* @__PURE__ */ y(a, {
|
|
161
|
+
title: T("devportal.scopes", "Scopes"),
|
|
162
|
+
children: /* @__PURE__ */ b("div", {
|
|
164
163
|
className: "space-y-3",
|
|
165
|
-
children: [/* @__PURE__ */
|
|
164
|
+
children: [/* @__PURE__ */ b("div", {
|
|
166
165
|
className: "flex items-center gap-2",
|
|
167
|
-
children: [/* @__PURE__ */
|
|
166
|
+
children: [/* @__PURE__ */ y("input", {
|
|
168
167
|
type: "text",
|
|
169
|
-
value:
|
|
170
|
-
onChange: (e) =>
|
|
168
|
+
value: P,
|
|
169
|
+
onChange: (e) => F(e.target.value),
|
|
171
170
|
onKeyDown: (e) => {
|
|
172
|
-
e.key === "Enter" && (e.preventDefault(),
|
|
171
|
+
e.key === "Enter" && (e.preventDefault(), J());
|
|
173
172
|
},
|
|
174
173
|
placeholder: "e.g. workspace:read",
|
|
175
174
|
className: "flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
|
|
176
|
-
}), /* @__PURE__ */
|
|
175
|
+
}), /* @__PURE__ */ y("button", {
|
|
177
176
|
type: "button",
|
|
178
|
-
onClick:
|
|
177
|
+
onClick: J,
|
|
179
178
|
className: "rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors",
|
|
180
|
-
children: /* @__PURE__ */
|
|
179
|
+
children: /* @__PURE__ */ y(h, { size: 16 })
|
|
181
180
|
})]
|
|
182
|
-
}),
|
|
181
|
+
}), M.length > 0 && /* @__PURE__ */ y("div", {
|
|
183
182
|
className: "flex flex-wrap gap-2",
|
|
184
|
-
children:
|
|
183
|
+
children: M.map((e) => /* @__PURE__ */ b("span", {
|
|
185
184
|
className: "inline-flex items-center gap-1 rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
|
|
186
|
-
children: [e, /* @__PURE__ */
|
|
185
|
+
children: [e, /* @__PURE__ */ y("button", {
|
|
187
186
|
type: "button",
|
|
188
|
-
onClick: () =>
|
|
187
|
+
onClick: () => Y(e),
|
|
189
188
|
className: "hover:text-status-error-text",
|
|
190
|
-
children: /* @__PURE__ */
|
|
189
|
+
children: /* @__PURE__ */ y(v, { size: 12 })
|
|
191
190
|
})]
|
|
192
191
|
}, e))
|
|
193
192
|
})]
|
|
194
193
|
})
|
|
195
|
-
}), /* @__PURE__ */
|
|
196
|
-
title:
|
|
197
|
-
children: /* @__PURE__ */
|
|
194
|
+
}), /* @__PURE__ */ y(a, {
|
|
195
|
+
title: T("devportal.redirectUris", "Redirect URIs"),
|
|
196
|
+
children: /* @__PURE__ */ b("div", {
|
|
198
197
|
className: "space-y-3",
|
|
199
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ b("div", {
|
|
200
199
|
className: "flex items-center gap-2",
|
|
201
|
-
children: [/* @__PURE__ */
|
|
200
|
+
children: [/* @__PURE__ */ y("input", {
|
|
202
201
|
type: "url",
|
|
203
|
-
value:
|
|
204
|
-
onChange: (e) =>
|
|
202
|
+
value: R,
|
|
203
|
+
onChange: (e) => z(e.target.value),
|
|
205
204
|
onKeyDown: (e) => {
|
|
206
|
-
e.key === "Enter" && (e.preventDefault(),
|
|
205
|
+
e.key === "Enter" && (e.preventDefault(), X());
|
|
207
206
|
},
|
|
208
207
|
placeholder: "https://example.com/callback",
|
|
209
208
|
className: "flex-1 rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
|
|
210
|
-
}), /* @__PURE__ */
|
|
209
|
+
}), /* @__PURE__ */ y("button", {
|
|
211
210
|
type: "button",
|
|
212
|
-
onClick:
|
|
211
|
+
onClick: X,
|
|
213
212
|
className: "rounded-md bg-action-primary-bg/10 p-2 text-primary hover:bg-action-primary-bg/20 transition-colors",
|
|
214
|
-
children: /* @__PURE__ */
|
|
213
|
+
children: /* @__PURE__ */ y(h, { size: 16 })
|
|
215
214
|
})]
|
|
216
|
-
}),
|
|
215
|
+
}), I.length > 0 && /* @__PURE__ */ y("div", {
|
|
217
216
|
className: "space-y-2",
|
|
218
|
-
children:
|
|
217
|
+
children: I.map((e) => /* @__PURE__ */ b("div", {
|
|
219
218
|
className: "flex items-center gap-2",
|
|
220
|
-
children: [/* @__PURE__ */
|
|
219
|
+
children: [/* @__PURE__ */ y("code", {
|
|
221
220
|
className: "flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
|
|
222
221
|
children: e
|
|
223
|
-
}), /* @__PURE__ */
|
|
222
|
+
}), /* @__PURE__ */ y("button", {
|
|
224
223
|
type: "button",
|
|
225
|
-
onClick: () =>
|
|
224
|
+
onClick: () => Z(e),
|
|
226
225
|
className: "rounded p-1 text-text-secondary hover:text-status-error-text transition-colors",
|
|
227
|
-
children: /* @__PURE__ */
|
|
226
|
+
children: /* @__PURE__ */ y(_, { size: 14 })
|
|
228
227
|
})]
|
|
229
228
|
}, e))
|
|
230
229
|
})]
|
|
231
230
|
})
|
|
232
231
|
})]
|
|
233
232
|
}),
|
|
234
|
-
/* @__PURE__ */
|
|
233
|
+
/* @__PURE__ */ b("div", {
|
|
235
234
|
className: "flex items-center gap-3 pt-4 border-t",
|
|
236
|
-
children: [/* @__PURE__ */
|
|
235
|
+
children: [/* @__PURE__ */ b("button", {
|
|
237
236
|
type: "submit",
|
|
238
|
-
disabled:
|
|
237
|
+
disabled: G || !E.trim(),
|
|
239
238
|
className: t("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"),
|
|
240
|
-
children: [/* @__PURE__ */
|
|
241
|
-
}), /* @__PURE__ */
|
|
239
|
+
children: [/* @__PURE__ */ y(g, { size: 16 }), G ? T("devportal.creating", "Creating...") : T("devportal.createOAuthApp", "Create OAuth App")]
|
|
240
|
+
}), /* @__PURE__ */ b("button", {
|
|
242
241
|
type: "button",
|
|
243
|
-
onClick: () =>
|
|
242
|
+
onClick: () => q("/oauth"),
|
|
244
243
|
className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors",
|
|
245
|
-
children: [/* @__PURE__ */
|
|
244
|
+
children: [/* @__PURE__ */ y(v, { size: 16 }), T("devportal.cancel", "Cancel")]
|
|
246
245
|
})]
|
|
247
246
|
})
|
|
248
247
|
]
|
|
@@ -251,6 +250,6 @@ var C = () => {
|
|
|
251
250
|
});
|
|
252
251
|
};
|
|
253
252
|
//#endregion
|
|
254
|
-
export {
|
|
253
|
+
export { S as CreateOAuthClientPage };
|
|
255
254
|
|
|
256
255
|
//# sourceMappingURL=CreateOAuthClientPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOAuthClientPage.js","names":[],"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 { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\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 permission={DEVPORTAL_PERMISSIONS.APP_CREATE}>\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":[],"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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"}
|
|
@@ -81,7 +81,7 @@ var E = {
|
|
|
81
81
|
return k.applicationId || (e.applicationId = H("devportal.createWebhook.errors.appRequired", "Select an application")), k.name.trim() || (e.name = H("devportal.createWebhook.errors.nameRequired", "Name is required")), k.url.trim() ? /^https:\/\//i.test(k.url) || (e.url = H("devportal.createWebhook.errors.urlHttps", "Endpoint URL must use HTTPS")) : e.url = H("devportal.createWebhook.errors.urlRequired", "Endpoint URL is required"), k.events.length === 0 && (e.events = H("devportal.createWebhook.errors.eventsRequired", "Select at least one event")), k.retryEnabled && (k.maxRetries < 1 || k.maxRetries > 10) && (e.maxRetries = H("devportal.createWebhook.errors.retriesRange", "Retry count must be between 1 and 10")), M(e), Object.keys(e).length === 0;
|
|
82
82
|
};
|
|
83
83
|
return /* @__PURE__ */ C(f, {
|
|
84
|
-
|
|
84
|
+
authOnly: !0,
|
|
85
85
|
children: /* @__PURE__ */ C(o, {
|
|
86
86
|
title: H("devportal.createWebhook.title", "Create Webhook"),
|
|
87
87
|
description: H("devportal.createWebhook.description", "Set up a real webhook endpoint to receive platform events through the public gateway"),
|