@burdenoff/microfe-devportal 2026.701.1 → 2026.702.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,12 @@ import { InputField as s, SelectField as c, TextareaField as l } from "../compon
7
7
  import { PermissionGuard as u } from "../components/PermissionGuard.js";
8
8
  import "../components/index.js";
9
9
  import { DEVPORTAL_PERMISSIONS as d } from "../constants/permissions.js";
10
- import { useState as f } from "react";
10
+ import { useRef as ee, useState as f } from "react";
11
11
  import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
- import { ArrowLeft as ee, Box as m, Check as h, ChevronRight as g, GitFork as _, Info as v, Loader2 as te, Puzzle as y, Save as b, X as x } from "lucide-react";
13
- import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
12
+ import { ArrowLeft as m, Box as h, Check as g, ChevronRight as _, GitFork as v, Info as y, Loader2 as b, Puzzle as x, Save as S, X as te } from "lucide-react";
13
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
14
14
  //#region src/devportal/pages/CreateApplicationPage.tsx
15
- var T = [
15
+ var E = [
16
16
  {
17
17
  id: "auth",
18
18
  label: "Authentication",
@@ -84,29 +84,22 @@ var T = [
84
84
  description: "Access control configuration"
85
85
  }
86
86
  ];
87
- function E() {
88
- return Object.fromEntries(T.map((e) => [e.id, "none"]));
87
+ function D() {
88
+ return Object.fromEntries(E.map((e) => [e.id, "none"]));
89
89
  }
90
- function D(e) {
90
+ function O(e) {
91
91
  return Object.entries(e).filter(([, e]) => e !== "none").map(([e, t]) => ({
92
92
  resource: e,
93
93
  level: t
94
94
  }));
95
95
  }
96
- var O = [
97
- {
98
- value: "PUBLIC",
99
- label: "Public — visible to everyone"
100
- },
101
- {
102
- value: "PRIVATE",
103
- label: "Private — only visible to you"
104
- },
105
- {
106
- value: "UNLISTED",
107
- label: "Unlisted — accessible via direct link"
108
- }
109
- ], k = [
96
+ var k = [{
97
+ value: "PUBLIC",
98
+ label: "Public — synced to the marketplace"
99
+ }, {
100
+ value: "PRIVATE",
101
+ label: "Private — only visible to you and your org"
102
+ }], A = [
110
103
  {
111
104
  value: "ai",
112
105
  label: "AI & Automation"
@@ -135,41 +128,41 @@ var O = [
135
128
  value: "trigger",
136
129
  label: "Triggers"
137
130
  }
138
- ], A = ({ icon: e, title: n, description: r, bullets: i, selected: a, onClick: o }) => /* @__PURE__ */ w("button", {
131
+ ], j = ({ icon: e, title: n, description: r, bullets: i, selected: a, onClick: o }) => /* @__PURE__ */ T("button", {
139
132
  type: "button",
140
133
  onClick: o,
141
134
  className: t("relative flex flex-col gap-3 rounded-xl border-2 p-6 text-left transition-all hover:border-primary/50 hover:shadow-sm", a ? "border-primary bg-action-primary-bg/5 shadow-sm" : "border-border-subtle bg-bg-surface"),
142
135
  children: [
143
- a && /* @__PURE__ */ C("span", {
136
+ a && /* @__PURE__ */ w("span", {
144
137
  className: "absolute top-4 right-4 flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text",
145
- children: /* @__PURE__ */ C(h, { size: 12 })
138
+ children: /* @__PURE__ */ w(g, { size: 12 })
146
139
  }),
147
- /* @__PURE__ */ C("div", {
140
+ /* @__PURE__ */ w("div", {
148
141
  className: "flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken",
149
- children: /* @__PURE__ */ C(e, {
142
+ children: /* @__PURE__ */ w(e, {
150
143
  size: 22,
151
144
  className: "text-text-primary"
152
145
  })
153
146
  }),
154
- /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
147
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
155
148
  className: "font-semibold text-text-primary",
156
149
  children: n
157
- }), /* @__PURE__ */ C("p", {
150
+ }), /* @__PURE__ */ w("p", {
158
151
  className: "mt-1 text-sm text-text-secondary",
159
152
  children: r
160
153
  })] }),
161
- /* @__PURE__ */ C("ul", {
154
+ /* @__PURE__ */ w("ul", {
162
155
  className: "mt-1 space-y-1",
163
- children: i.map((e) => /* @__PURE__ */ w("li", {
156
+ children: i.map((e) => /* @__PURE__ */ T("li", {
164
157
  className: "flex items-center gap-2 text-xs text-text-secondary",
165
- children: [/* @__PURE__ */ C(g, {
158
+ children: [/* @__PURE__ */ w(_, {
166
159
  size: 12,
167
160
  className: "flex-shrink-0 text-primary"
168
161
  }), e]
169
162
  }, e))
170
163
  })
171
164
  ]
172
- }), j = ({ permissions: e, onChange: t }) => {
165
+ }), M = ({ permissions: e, onChange: t }) => {
173
166
  let n = [
174
167
  "none",
175
168
  "read",
@@ -179,35 +172,35 @@ var O = [
179
172
  read: "Read",
180
173
  write: "Read & Write"
181
174
  };
182
- return /* @__PURE__ */ C("div", {
175
+ return /* @__PURE__ */ w("div", {
183
176
  className: "overflow-x-auto rounded-lg border border-border-subtle",
184
- children: /* @__PURE__ */ w("table", {
177
+ children: /* @__PURE__ */ T("table", {
185
178
  className: "w-full text-sm",
186
- children: [/* @__PURE__ */ C("thead", { children: /* @__PURE__ */ w("tr", {
179
+ children: [/* @__PURE__ */ w("thead", { children: /* @__PURE__ */ T("tr", {
187
180
  className: "border-b border-border-subtle bg-bg-sunken/50",
188
- children: [/* @__PURE__ */ C("th", {
181
+ children: [/* @__PURE__ */ w("th", {
189
182
  className: "px-4 py-3 text-left font-medium text-text-secondary w-1/2",
190
183
  children: "Resource"
191
- }), n.map((e) => /* @__PURE__ */ C("th", {
184
+ }), n.map((e) => /* @__PURE__ */ w("th", {
192
185
  className: "px-4 py-3 text-center font-medium text-text-secondary",
193
186
  children: r[e]
194
187
  }, e))]
195
- }) }), /* @__PURE__ */ C("tbody", {
188
+ }) }), /* @__PURE__ */ w("tbody", {
196
189
  className: "divide-y divide-border",
197
- children: T.map((r) => /* @__PURE__ */ w("tr", {
190
+ children: E.map((r) => /* @__PURE__ */ T("tr", {
198
191
  className: "hover:bg-bg-sunken/30 transition-colors",
199
- children: [/* @__PURE__ */ w("td", {
192
+ children: [/* @__PURE__ */ T("td", {
200
193
  className: "px-4 py-3",
201
- children: [/* @__PURE__ */ C("p", {
194
+ children: [/* @__PURE__ */ w("p", {
202
195
  className: "font-medium text-text-primary",
203
196
  children: r.label
204
- }), /* @__PURE__ */ C("p", {
197
+ }), /* @__PURE__ */ w("p", {
205
198
  className: "text-xs text-text-secondary",
206
199
  children: r.description
207
200
  })]
208
- }), n.map((n) => /* @__PURE__ */ C("td", {
201
+ }), n.map((n) => /* @__PURE__ */ w("td", {
209
202
  className: "px-4 py-3 text-center",
210
- children: /* @__PURE__ */ C("input", {
203
+ children: /* @__PURE__ */ w("input", {
211
204
  type: "radio",
212
205
  name: `permission-${r.id}`,
213
206
  value: n,
@@ -220,18 +213,35 @@ var O = [
220
213
  })]
221
214
  })
222
215
  });
223
- }, M = () => {
224
- let { navigate: t, basePath: h, activeOrgId: g } = e(), { t: T } = p(), M = (e, t) => {
225
- let n = T(e);
216
+ }, ne = [
217
+ {
218
+ value: "fluidgrids",
219
+ label: "FluidGrids"
220
+ },
221
+ {
222
+ value: "workspaces",
223
+ label: "Workspaces"
224
+ },
225
+ {
226
+ value: "bigconsole",
227
+ label: "BigConsole"
228
+ },
229
+ {
230
+ value: "botlit",
231
+ label: "Botlit"
232
+ }
233
+ ], N = () => {
234
+ let { navigate: _, basePath: E, activeOrgId: N } = e(), { t: re } = p(), ie = (e, t) => {
235
+ let n = re(e);
226
236
  return n === e ? t : n;
227
- }, N = n(), [P, F] = f(null), [I, L] = f(E()), [R, z] = f({
237
+ }, ae = n(), [P, F] = f(null), [I, L] = f([]), [R, z] = f(D()), B = ee(!1), [V, H] = f({
228
238
  name: "",
229
239
  slug: "",
230
240
  shortDescription: "",
231
241
  description: "",
232
242
  category: "",
233
- visibility: "PRIVATE",
234
- developerOrganizationId: g ?? "",
243
+ visibility: "PUBLIC",
244
+ developerOrganizationId: N ?? "",
235
245
  websiteUrl: "",
236
246
  githubUrl: "",
237
247
  documentationUrl: "",
@@ -239,91 +249,108 @@ var O = [
239
249
  oauthAuthUrl: "",
240
250
  oauthTokenUrl: "",
241
251
  oauthRevokeUrl: ""
242
- }), [B, V] = f({}), [H, { loading: U }] = r(), { data: W } = i({ fetchPolicy: "cache-and-network" }), G = [{
252
+ }), [U, W] = f({}), [G, { loading: K }] = r(), { data: q } = i({ fetchPolicy: "cache-and-network" }), J = [{
243
253
  value: "",
244
254
  label: "No organization (personal)"
245
- }, ...(W?.myDeveloperOrganizations ?? []).map((e) => ({
255
+ }, ...(q?.myDeveloperOrganizations ?? []).map((e) => ({
246
256
  value: e.id,
247
257
  label: e.name
248
- }))], K = (e) => t?.(`${h}${e}`), q = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""), J = (e) => {
258
+ }))], Y = (e) => _?.(`${E}${e}`), oe = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""), se = (e) => {
249
259
  let t = e.target.value;
250
- z((e) => ({
260
+ H((e) => ({
251
261
  ...e,
252
262
  name: t,
253
- slug: e.slug || q(t)
254
- })), B.name && V((e) => ({
263
+ slug: B.current ? e.slug : oe(t)
264
+ })), U.name && W((e) => ({
255
265
  ...e,
256
266
  name: void 0
257
267
  }));
258
- }, Y = (e, t) => {
259
- z((n) => ({
268
+ }, ce = (e) => {
269
+ B.current = !0;
270
+ let t = e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, "");
271
+ H((e) => ({
272
+ ...e,
273
+ slug: t
274
+ })), U.slug && W((e) => ({
275
+ ...e,
276
+ slug: void 0
277
+ }));
278
+ }, X = (e, t) => {
279
+ H((n) => ({
260
280
  ...n,
261
281
  [e]: t
262
- })), B[e] && V((t) => ({
282
+ })), (U[e] || U._submit) && W((t) => ({
263
283
  ...t,
264
- [e]: void 0
284
+ [e]: void 0,
285
+ _submit: void 0
265
286
  }));
266
- }, X = (e, t) => {
267
- L((n) => ({
287
+ }, Z = (e, t) => {
288
+ z((n) => ({
268
289
  ...n,
269
290
  [e]: t
270
291
  }));
271
- }, Z = () => {
292
+ }, le = () => {
272
293
  let e = {};
273
- return R.name.trim() ? R.name.length < 3 ? e.name = "Name must be at least 3 characters" : R.name.length > 100 && (e.name = "Name must be less than 100 characters") : e.name = "Name is required", R.slug.trim() ? /^[a-z0-9-]+$/.test(R.slug) || (e.slug = "Slug can only contain lowercase letters, numbers, and hyphens") : e.slug = "Slug is required", R.shortDescription.trim() ? R.shortDescription.length > 200 && (e.shortDescription = "Short description must be less than 200 characters") : e.shortDescription = "Short description is required", V(e), Object.keys(e).length === 0;
274
- }, Q = () => P === "node" ? "NODE" : P === "workflow" ? "WORKFLOW" : "API_INTEGRATION", ne = async (e) => {
275
- if (e.preventDefault(), !Z() || !P) return;
276
- let t = P === "app" ? { permissions: D(I) } : null;
294
+ return V.name.trim() ? V.name.length < 3 ? e.name = "Name must be at least 3 characters" : V.name.length > 100 && (e.name = "Name must be less than 100 characters") : e.name = "Name is required", V.slug.trim() ? /^[a-z0-9-]+$/.test(V.slug) || (e.slug = "Slug can only contain lowercase letters, numbers, and hyphens") : e.slug = "Slug is required", V.shortDescription.trim() ? V.shortDescription.length > 200 && (e.shortDescription = "Short description must be less than 200 characters") : e.shortDescription = "Short description is required", V.category || (e.category = "Category is required"), P !== "app" && I.length === 0 && (e.compatibleProducts = "Select at least one compatible product so users can find this in the right store"), W(e), Object.keys(e).length === 0;
295
+ }, Q = () => P === "node" ? "NODE" : P === "workflow" ? "WORKFLOW" : "API_INTEGRATION", ue = async (e) => {
296
+ if (e.preventDefault(), !le() || !P) return;
297
+ let t = P === "app" ? { permissions: O(R) } : null;
277
298
  try {
278
- let e = await H({ variables: { input: {
279
- name: R.name,
280
- slug: R.slug || void 0,
281
- shortDescription: R.shortDescription || void 0,
282
- description: R.description || void 0,
283
- category: R.category || void 0,
299
+ let e = await G({ variables: { input: {
300
+ name: V.name,
301
+ slug: V.slug || void 0,
302
+ shortDescription: V.shortDescription || void 0,
303
+ description: V.description || void 0,
304
+ category: V.category || void 0,
284
305
  appType: Q(),
285
- visibility: R.visibility,
286
- developerOrganizationId: R.developerOrganizationId || void 0,
287
- websiteUrl: R.websiteUrl || void 0,
288
- githubUrl: R.githubUrl || void 0,
289
- documentationUrl: R.documentationUrl || void 0,
290
- supportUrl: R.supportUrl || void 0,
306
+ visibility: V.visibility,
307
+ developerOrganizationId: V.developerOrganizationId || void 0,
308
+ websiteUrl: V.websiteUrl || void 0,
309
+ githubUrl: V.githubUrl || void 0,
310
+ documentationUrl: V.documentationUrl || void 0,
311
+ supportUrl: V.supportUrl || void 0,
291
312
  manifest: t ?? void 0,
313
+ compatibleProducts: I.length > 0 ? I : void 0,
292
314
  ...P === "app" && {
293
- oauthAuthUrl: R.oauthAuthUrl || void 0,
294
- oauthTokenUrl: R.oauthTokenUrl || void 0,
295
- oauthRevokeUrl: R.oauthRevokeUrl || void 0
315
+ oauthAuthUrl: V.oauthAuthUrl || void 0,
316
+ oauthTokenUrl: V.oauthTokenUrl || void 0,
317
+ oauthRevokeUrl: V.oauthRevokeUrl || void 0
296
318
  }
297
319
  } } });
298
- e.data?.createApplication?.id && (N.emit("devportal.app.created", {
320
+ e.data?.createApplication?.id && (ae.emit("devportal.app.created", {
299
321
  appId: e.data.createApplication.id,
300
- name: R.name,
322
+ name: V.name,
301
323
  appType: Q(),
302
- organizationId: R.developerOrganizationId || null
303
- }), K(`/apps/${e.data.createApplication.id}`));
324
+ organizationId: V.developerOrganizationId || null
325
+ }), Y(`/apps/${e.data.createApplication.id}`));
304
326
  } catch (e) {
305
- let t = e instanceof Error ? e.message : String(e);
306
- (t.includes("slug") || t.includes("already exists") || t.includes("slugConflict")) && V((e) => ({
327
+ let t = [];
328
+ e && typeof e == "object" && "graphQLErrors" in e && Array.isArray(e.graphQLErrors) && e.graphQLErrors.forEach((e) => t.push(e.message)), e instanceof Error && t.push(e.message);
329
+ let n = t.join(" ").toLowerCase();
330
+ n.includes("slug") || n.includes("already exist") || n.includes("unique") || n.includes("conflict") || n.includes("duplicate") ? W((e) => ({
307
331
  ...e,
308
- slug: "This slug is already in use — try a different name"
332
+ slug: "This slug is already taken — choose a different one"
333
+ })) : W((e) => ({
334
+ ...e,
335
+ _submit: t[0] ?? "Something went wrong. Please try again."
309
336
  }));
310
337
  }
311
338
  };
312
- if (!P) return /* @__PURE__ */ C(u, {
339
+ if (!P) return /* @__PURE__ */ w(u, {
313
340
  permission: d.APP_CREATE,
314
- children: /* @__PURE__ */ C(a, {
341
+ children: /* @__PURE__ */ w(a, {
315
342
  title: "What do you want to build?",
316
343
  description: "Choose a builder type to get started",
317
344
  purpose: "Pick the kind of integration you are creating — a standard app, a Node package, or a workflow. Your choice sets up the right defaults (credentials, permissions, and where it can be installed) so you only fill in what that type actually needs.",
318
- backLink: `${h}/apps`,
345
+ backLink: `${E}/apps`,
319
346
  backLabel: "Back to Applications",
320
- children: /* @__PURE__ */ w("div", {
347
+ children: /* @__PURE__ */ T("div", {
321
348
  className: "max-w-3xl space-y-6",
322
- children: [/* @__PURE__ */ w("div", {
349
+ children: [/* @__PURE__ */ T("div", {
323
350
  className: "grid gap-4 sm:grid-cols-3",
324
351
  children: [
325
- /* @__PURE__ */ C(A, {
326
- icon: m,
352
+ /* @__PURE__ */ w(j, {
353
+ icon: h,
327
354
  title: "App",
328
355
  description: "Build integrations that connect your service to the platform using OAuth tokens.",
329
356
  bullets: [
@@ -335,8 +362,8 @@ var O = [
335
362
  selected: P === "app",
336
363
  onClick: () => F("app")
337
364
  }),
338
- /* @__PURE__ */ C(A, {
339
- icon: y,
365
+ /* @__PURE__ */ w(j, {
366
+ icon: x,
340
367
  title: "Node",
341
368
  description: "Build custom FluidGrids nodes that users can drag into their visual workflows.",
342
369
  bullets: [
@@ -348,8 +375,8 @@ var O = [
348
375
  selected: P === "node",
349
376
  onClick: () => F("node")
350
377
  }),
351
- /* @__PURE__ */ C(A, {
352
- icon: _,
378
+ /* @__PURE__ */ w(j, {
379
+ icon: v,
353
380
  title: "Workflow",
354
381
  description: "Build reusable automation workflows that users can import and customize.",
355
382
  bullets: [
@@ -362,78 +389,151 @@ var O = [
362
389
  onClick: () => F("workflow")
363
390
  })
364
391
  ]
365
- }), /* @__PURE__ */ w("div", {
392
+ }), /* @__PURE__ */ T("div", {
366
393
  className: "rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 flex gap-3 text-sm text-text-secondary",
367
- children: [/* @__PURE__ */ C(v, {
394
+ children: [/* @__PURE__ */ w(y, {
368
395
  size: 16,
369
396
  className: "flex-shrink-0 mt-0.5"
370
- }), /* @__PURE__ */ C("p", { children: "Apps use OAuth to interact with platform data. Nodes and Workflows are packaged files you upload after creation." })]
397
+ }), /* @__PURE__ */ w("p", { children: "Apps use OAuth to interact with platform data. Nodes and Workflows are packaged files you upload after creation." })]
371
398
  })]
372
399
  })
373
400
  })
374
401
  });
375
- let $ = P === "app" ? "App" : P === "node" ? "Node" : "Workflow", re = C(P === "app" ? m : P === "node" ? y : _, { size: 16 });
376
- return /* @__PURE__ */ C(u, {
402
+ let $ = P === "app" ? "App" : P === "node" ? "Node" : "Workflow", de = w(P === "app" ? h : P === "node" ? x : v, { size: 16 });
403
+ return /* @__PURE__ */ w(u, {
377
404
  permission: d.APP_CREATE,
378
- children: /* @__PURE__ */ C(a, {
405
+ children: /* @__PURE__ */ w(a, {
379
406
  title: `Create ${$}`,
380
407
  description: P === "app" ? "Register a new app integration with OAuth permissions" : P === "node" ? "Register a new FluidGrids node package" : "Register a new reusable automation workflow",
381
408
  purpose: "Give your integration a name, description, and the permissions it will request. Once created you will get credentials and can configure webhooks, then publish it to the marketplace when it is ready for users.",
382
- backLink: `${h}/apps`,
409
+ backLink: `${E}/apps`,
383
410
  backLabel: "Back to Applications",
384
- children: /* @__PURE__ */ w("form", {
385
- onSubmit: ne,
411
+ children: /* @__PURE__ */ T("form", {
412
+ onSubmit: ue,
386
413
  className: "space-y-8 max-w-3xl",
387
414
  children: [
388
- /* @__PURE__ */ w("div", {
415
+ /* @__PURE__ */ T("div", {
389
416
  className: "flex items-center gap-3",
390
- children: [/* @__PURE__ */ w("button", {
417
+ children: [/* @__PURE__ */ T("button", {
391
418
  type: "button",
392
419
  onClick: () => F(null),
393
420
  className: "flex items-center gap-1.5 text-sm text-text-secondary hover:text-text-primary transition-colors",
394
- children: [/* @__PURE__ */ C(ee, { size: 14 }), "Change type"]
395
- }), /* @__PURE__ */ w("span", {
421
+ children: [/* @__PURE__ */ w(m, { size: 14 }), "Change type"]
422
+ }), /* @__PURE__ */ T("span", {
396
423
  className: "flex items-center gap-1.5 rounded-full border border-border-subtle bg-bg-sunken px-3 py-1 text-xs font-medium",
397
- children: [re, $]
424
+ children: [de, $]
398
425
  })]
399
426
  }),
400
- /* @__PURE__ */ C(o, {
427
+ /* @__PURE__ */ w(o, {
401
428
  title: "Basic Information",
402
429
  description: "Core details about your application",
403
- children: /* @__PURE__ */ w("div", {
430
+ children: /* @__PURE__ */ T("div", {
404
431
  className: "space-y-4",
405
432
  children: [
406
- /* @__PURE__ */ C(s, {
433
+ /* @__PURE__ */ w(s, {
407
434
  label: "Name",
408
- value: R.name,
409
- onChange: J,
435
+ value: V.name,
436
+ onChange: se,
410
437
  placeholder: P === "app" ? "My Integration" : P === "node" ? "HTTP Request" : "Onboarding Flow",
411
438
  required: !0,
412
- error: B.name
439
+ error: U.name
413
440
  }),
414
- /* @__PURE__ */ C(s, {
441
+ /* @__PURE__ */ w(s, {
415
442
  label: "Slug",
416
- value: R.slug,
417
- onChange: (e) => Y("slug", e.target.value.toLowerCase()),
443
+ value: V.slug,
444
+ onChange: ce,
418
445
  placeholder: "my-integration",
419
446
  required: !0,
420
- error: B.slug,
421
- hint: "URL-friendly identifier (auto-generated from name)"
447
+ error: U.slug,
448
+ hint: B.current ? "Only lowercase letters, numbers, and hyphens" : "Auto-generated from name — edit to customise"
422
449
  }),
423
- /* @__PURE__ */ C(l, {
450
+ /* @__PURE__ */ w(l, {
424
451
  label: "Short Description",
425
- value: R.shortDescription,
426
- onChange: (e) => Y("shortDescription", e.target.value),
452
+ value: V.shortDescription,
453
+ onChange: (e) => X("shortDescription", e.target.value),
427
454
  placeholder: "Briefly describe what this does",
428
455
  required: !0,
429
- error: B.shortDescription,
430
- hint: `${R.shortDescription.length}/200 characters`,
456
+ error: U.shortDescription,
457
+ hint: `${V.shortDescription.length}/200 characters`,
431
458
  rows: 2
432
459
  }),
433
- /* @__PURE__ */ C(l, {
460
+ /* @__PURE__ */ T("div", {
461
+ className: "grid gap-4 sm:grid-cols-2",
462
+ children: [/* @__PURE__ */ w(c, {
463
+ label: "Category",
464
+ value: V.category,
465
+ onChange: (e) => X("category", e.target.value),
466
+ options: A,
467
+ placeholder: "Select a category…",
468
+ required: !0,
469
+ error: U.category,
470
+ hint: "Helps users discover your item in the store"
471
+ }), /* @__PURE__ */ w(c, {
472
+ label: "Visibility",
473
+ value: V.visibility,
474
+ onChange: (e) => X("visibility", e.target.value),
475
+ options: k,
476
+ required: !0,
477
+ hint: "Public apps are synced to the marketplace after review"
478
+ })]
479
+ }),
480
+ P !== "app" && /* @__PURE__ */ T("div", {
481
+ className: "space-y-2",
482
+ children: [
483
+ /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ T("label", {
484
+ className: "block text-sm font-medium text-text-primary",
485
+ children: ["Compatible Products", /* @__PURE__ */ w("span", {
486
+ className: "text-status-error-text ml-1",
487
+ children: "*"
488
+ })]
489
+ }), /* @__PURE__ */ T("p", {
490
+ className: "text-xs text-text-secondary mt-0.5",
491
+ children: [
492
+ "Select which products this ",
493
+ P,
494
+ " works with. Users will see it in those products' node stores."
495
+ ]
496
+ })] }),
497
+ /* @__PURE__ */ w("div", {
498
+ className: "flex flex-wrap gap-3",
499
+ children: ne.map((e) => {
500
+ let n = I.includes(e.value);
501
+ return /* @__PURE__ */ T("label", {
502
+ className: t("flex items-center gap-2 cursor-pointer rounded-md border px-3 py-2 text-sm transition-colors", n ? "border-primary bg-primary/10 text-text-primary" : "border-border-subtle hover:border-border text-text-secondary hover:text-text-primary", U.compatibleProducts && !n && "border-status-error-bg/50"),
503
+ children: [
504
+ /* @__PURE__ */ w("input", {
505
+ type: "checkbox",
506
+ className: "sr-only",
507
+ checked: n,
508
+ onChange: () => {
509
+ L((t) => {
510
+ let r = n ? t.filter((t) => t !== e.value) : [...t, e.value];
511
+ return r.length > 0 && W((e) => ({
512
+ ...e,
513
+ compatibleProducts: void 0
514
+ })), r;
515
+ });
516
+ }
517
+ }),
518
+ n && /* @__PURE__ */ w(g, {
519
+ size: 14,
520
+ className: "text-primary flex-shrink-0"
521
+ }),
522
+ e.label
523
+ ]
524
+ }, e.value);
525
+ })
526
+ }),
527
+ U.compatibleProducts && /* @__PURE__ */ w("p", {
528
+ className: "text-xs text-status-error-text",
529
+ children: U.compatibleProducts
530
+ })
531
+ ]
532
+ }),
533
+ /* @__PURE__ */ w(l, {
434
534
  label: "Full Description",
435
- value: R.description,
436
- onChange: (e) => Y("description", e.target.value),
535
+ value: V.description,
536
+ onChange: (e) => X("description", e.target.value),
437
537
  placeholder: "Detailed description, features, and use cases...",
438
538
  rows: 5,
439
539
  hint: "Markdown supported"
@@ -441,147 +541,100 @@ var O = [
441
541
  ]
442
542
  })
443
543
  }),
444
- /* @__PURE__ */ C(o, {
445
- title: "Publish Settings",
446
- description: "Control who can see this and which organization it belongs to",
447
- children: /* @__PURE__ */ w("div", {
448
- className: "grid gap-4 sm:grid-cols-2",
449
- children: [
450
- /* @__PURE__ */ C(c, {
451
- label: "Category",
452
- value: R.category,
453
- onChange: (e) => Y("category", e.target.value),
454
- options: k
455
- }),
456
- /* @__PURE__ */ C(c, {
457
- label: "Visibility",
458
- value: R.visibility,
459
- onChange: (e) => Y("visibility", e.target.value),
460
- options: O
461
- }),
462
- /* @__PURE__ */ C(c, {
463
- label: "Developer Organization",
464
- value: R.developerOrganizationId,
465
- onChange: (e) => Y("developerOrganizationId", e.target.value),
466
- options: G
467
- })
468
- ]
544
+ J.length > 2 && /* @__PURE__ */ w(o, {
545
+ title: "Organization",
546
+ description: "Which developer organization owns this?",
547
+ children: /* @__PURE__ */ w(c, {
548
+ label: "Developer Organization",
549
+ value: V.developerOrganizationId,
550
+ onChange: (e) => X("developerOrganizationId", e.target.value),
551
+ options: J
469
552
  })
470
553
  }),
471
- /* @__PURE__ */ C(o, {
472
- title: "Links",
473
- description: "External resources",
474
- children: /* @__PURE__ */ w("div", {
475
- className: "grid gap-4 sm:grid-cols-2",
476
- children: [
477
- /* @__PURE__ */ C(s, {
478
- label: "Website URL",
479
- type: "url",
480
- value: R.websiteUrl,
481
- onChange: (e) => Y("websiteUrl", e.target.value),
482
- placeholder: "https://example.com"
483
- }),
484
- /* @__PURE__ */ C(s, {
485
- label: "GitHub URL",
486
- type: "url",
487
- value: R.githubUrl,
488
- onChange: (e) => Y("githubUrl", e.target.value),
489
- placeholder: "https://github.com/org/repo"
490
- }),
491
- /* @__PURE__ */ C(s, {
492
- label: "Documentation URL",
493
- type: "url",
494
- value: R.documentationUrl,
495
- onChange: (e) => Y("documentationUrl", e.target.value),
496
- placeholder: "https://docs.example.com"
497
- }),
498
- /* @__PURE__ */ C(s, {
499
- label: "Support URL",
500
- type: "url",
501
- value: R.supportUrl,
502
- onChange: (e) => Y("supportUrl", e.target.value),
503
- placeholder: "https://support.example.com"
504
- })
505
- ]
506
- })
507
- }),
508
- P === "app" && /* @__PURE__ */ w(o, {
554
+ P === "app" && /* @__PURE__ */ T(o, {
509
555
  title: "Permissions",
510
556
  description: "Choose what data your app can access. Users will see these permissions when authorizing your app — like GitHub Apps.",
511
- children: [/* @__PURE__ */ C(j, {
512
- permissions: I,
513
- onChange: X
514
- }), /* @__PURE__ */ w("div", {
557
+ children: [/* @__PURE__ */ w(M, {
558
+ permissions: R,
559
+ onChange: Z
560
+ }), /* @__PURE__ */ T("div", {
515
561
  className: "mt-3 flex gap-2 rounded-lg border border-border-subtle bg-bg-sunken/30 p-3 text-xs text-text-secondary",
516
- children: [/* @__PURE__ */ C(v, {
562
+ children: [/* @__PURE__ */ w(y, {
517
563
  size: 14,
518
564
  className: "flex-shrink-0 mt-0.5"
519
- }), /* @__PURE__ */ w("span", { children: [/* @__PURE__ */ C("strong", { children: "Read & Write" }), " implies Read. Select only what your app genuinely needs — fewer permissions build more user trust."] })]
565
+ }), /* @__PURE__ */ T("span", { children: [/* @__PURE__ */ w("strong", { children: "Read & Write" }), " implies Read. Select only what your app genuinely needs — fewer permissions build more user trust."] })]
520
566
  })]
521
567
  }),
522
- P === "app" && /* @__PURE__ */ C(o, {
568
+ P === "app" && /* @__PURE__ */ w(o, {
523
569
  title: "OAuth Endpoints",
524
570
  description: "Configure the OAuth 2.0 endpoints your app uses to authenticate workspaces. Workspaces will be redirected through these URLs during installation.",
525
- children: /* @__PURE__ */ w("div", {
571
+ children: /* @__PURE__ */ T("div", {
526
572
  className: "space-y-4",
527
573
  children: [
528
- /* @__PURE__ */ C(s, {
574
+ /* @__PURE__ */ w(s, {
529
575
  label: "Authorization URL",
530
576
  type: "url",
531
- value: R.oauthAuthUrl,
532
- onChange: (e) => Y("oauthAuthUrl", e.target.value),
577
+ value: V.oauthAuthUrl,
578
+ onChange: (e) => X("oauthAuthUrl", e.target.value),
533
579
  placeholder: "https://yourapp.com/oauth/authorize",
534
580
  hint: "Where users are redirected to grant access"
535
581
  }),
536
- /* @__PURE__ */ C(s, {
582
+ /* @__PURE__ */ w(s, {
537
583
  label: "Token URL",
538
584
  type: "url",
539
- value: R.oauthTokenUrl,
540
- onChange: (e) => Y("oauthTokenUrl", e.target.value),
585
+ value: V.oauthTokenUrl,
586
+ onChange: (e) => X("oauthTokenUrl", e.target.value),
541
587
  placeholder: "https://yourapp.com/oauth/token",
542
588
  hint: "Endpoint to exchange auth code for access token"
543
589
  }),
544
- /* @__PURE__ */ C(s, {
590
+ /* @__PURE__ */ w(s, {
545
591
  label: "Revoke URL",
546
592
  type: "url",
547
- value: R.oauthRevokeUrl,
548
- onChange: (e) => Y("oauthRevokeUrl", e.target.value),
593
+ value: V.oauthRevokeUrl,
594
+ onChange: (e) => X("oauthRevokeUrl", e.target.value),
549
595
  placeholder: "https://yourapp.com/oauth/revoke",
550
596
  hint: "Endpoint to revoke tokens when app is uninstalled"
551
597
  })
552
598
  ]
553
599
  })
554
600
  }),
555
- P !== "app" && /* @__PURE__ */ w("div", {
601
+ P !== "app" && /* @__PURE__ */ T("div", {
556
602
  className: "rounded-lg border border-border-subtle bg-bg-sunken/30 p-4 flex gap-3 text-sm text-text-secondary",
557
- children: [/* @__PURE__ */ C(v, {
603
+ children: [/* @__PURE__ */ w(y, {
558
604
  size: 16,
559
605
  className: "flex-shrink-0 mt-0.5"
560
- }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
606
+ }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
561
607
  className: "font-medium text-text-primary",
562
608
  children: "File uploads"
563
- }), /* @__PURE__ */ C("p", {
609
+ }), /* @__PURE__ */ w("p", {
564
610
  className: "mt-1",
565
611
  children: P === "node" ? "After creating your Node, go to the Versions tab to upload your ZIP bundle and manifest.json." : "After creating your Workflow, go to the Versions tab to upload your manifest and workflow JSON definition."
566
612
  })] })]
567
613
  }),
568
- /* @__PURE__ */ w("div", {
614
+ U._submit && /* @__PURE__ */ T("div", {
615
+ className: "flex items-start gap-3 rounded-lg border border-status-error-bg bg-status-error-bg/10 px-4 py-3 text-sm text-status-error-text",
616
+ children: [/* @__PURE__ */ w(y, {
617
+ size: 16,
618
+ className: "flex-shrink-0 mt-0.5"
619
+ }), /* @__PURE__ */ w("span", { children: U._submit })]
620
+ }),
621
+ /* @__PURE__ */ T("div", {
569
622
  className: "flex items-center justify-end gap-3 border-t pt-6",
570
- children: [/* @__PURE__ */ w("button", {
623
+ children: [/* @__PURE__ */ T("button", {
571
624
  type: "button",
572
- onClick: () => K("/apps"),
573
- disabled: U,
625
+ onClick: () => Y("/apps"),
626
+ disabled: K,
574
627
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50",
575
- children: [/* @__PURE__ */ C(x, { size: 16 }), M("devportal.cancel", "Cancel")]
576
- }), /* @__PURE__ */ C("button", {
628
+ children: [/* @__PURE__ */ w(te, { size: 16 }), ie("devportal.cancel", "Cancel")]
629
+ }), /* @__PURE__ */ w("button", {
577
630
  type: "submit",
578
- disabled: U,
631
+ disabled: K,
579
632
  className: "inline-flex items-center gap-2 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 disabled:opacity-50",
580
- children: U ? /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ C(te, {
633
+ children: K ? /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(b, {
581
634
  size: 16,
582
635
  className: "animate-spin"
583
- }), "Creating…"] }) : /* @__PURE__ */ w(S, { children: [
584
- /* @__PURE__ */ C(b, { size: 16 }),
636
+ }), "Creating…"] }) : /* @__PURE__ */ T(C, { children: [
637
+ /* @__PURE__ */ w(S, { size: 16 }),
585
638
  "Create ",
586
639
  $
587
640
  ] })
@@ -593,6 +646,6 @@ var O = [
593
646
  });
594
647
  };
595
648
  //#endregion
596
- export { M as CreateApplicationPage };
649
+ export { N as CreateApplicationPage };
597
650
 
598
651
  //# sourceMappingURL=CreateApplicationPage.js.map