@elevasis/ui 2.73.0 → 2.75.0

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.
Files changed (97) hide show
  1. package/dist/api/index.js +3 -3
  2. package/dist/app/index.d.ts +58 -0
  3. package/dist/app/index.js +9 -10
  4. package/dist/auth/index.js +5 -6
  5. package/dist/charts/index.js +5 -6
  6. package/dist/chunk-2GIJBHZT.js +60 -0
  7. package/dist/{chunk-Z4ICFQXG.js → chunk-2ZRY3ARL.js} +1 -1
  8. package/dist/{chunk-5B2ZFO44.js → chunk-3H5DIJN7.js} +1 -1
  9. package/dist/{chunk-LZT2H2MA.js → chunk-47YJVIZE.js} +36 -43
  10. package/dist/{chunk-3TS5U5BL.js → chunk-5RH6NYZH.js} +1 -1
  11. package/dist/chunk-5SLRGUC4.js +224 -0
  12. package/dist/{chunk-JYBJMVNY.js → chunk-5VF5LPYS.js} +1 -1
  13. package/dist/{chunk-SWKAH2YM.js → chunk-6BJ5HMMC.js} +282 -553
  14. package/dist/{chunk-NI37YNRP.js → chunk-7OOFMEX6.js} +11 -5
  15. package/dist/{chunk-IBCEAVB2.js → chunk-A2SB32YV.js} +65 -5
  16. package/dist/{chunk-CJ2232PQ.js → chunk-CRPH5AAB.js} +1 -1
  17. package/dist/chunk-D3XXPCCK.js +69 -0
  18. package/dist/chunk-DMSTDZCJ.js +305 -0
  19. package/dist/chunk-DTEGVSJ6.js +645 -0
  20. package/dist/chunk-DVAOCHIF.js +165 -0
  21. package/dist/chunk-G7O4CBMC.js +231 -0
  22. package/dist/{chunk-IGBPWD6S.js → chunk-GDTK33QT.js} +5 -3
  23. package/dist/chunk-ICHDIVQO.js +54 -0
  24. package/dist/{chunk-U2H3TIHD.js → chunk-IYATYH5I.js} +2 -52
  25. package/dist/chunk-L3NBMLRN.js +49 -0
  26. package/dist/{chunk-LEPYXLJ2.js → chunk-LFLM723H.js} +1 -1
  27. package/dist/chunk-M6VAZAQW.js +45 -0
  28. package/dist/{chunk-AJOVWB47.js → chunk-MLHZUN2X.js} +6 -3
  29. package/dist/chunk-N6K2Q5BM.js +393 -0
  30. package/dist/chunk-NMHQAYZU.js +439 -0
  31. package/dist/chunk-NYIIRZSA.js +286 -0
  32. package/dist/{chunk-ETN3TTRT.js → chunk-OGHTJKBV.js} +115 -8
  33. package/dist/{chunk-M7WWRZ5Z.js → chunk-QFGNRKIE.js} +1 -78
  34. package/dist/chunk-QFS2GZMV.js +515 -0
  35. package/dist/{chunk-OCVSPAKM.js → chunk-SB3IHM5Y.js} +1150 -4346
  36. package/dist/{chunk-4CW2C5BD.js → chunk-SEYOVNS5.js} +1 -1
  37. package/dist/chunk-SN7X5N2A.js +116 -0
  38. package/dist/{chunk-PQ4B62HH.js → chunk-TX3UHDL5.js} +2 -2
  39. package/dist/chunk-VM2OWOXL.js +24 -0
  40. package/dist/{chunk-ZDKPHFTH.js → chunk-VWGCURZF.js} +5 -3
  41. package/dist/chunk-WDBNW44Z.js +49 -0
  42. package/dist/chunk-YQQ5GRUR.js +21 -0
  43. package/dist/{chunk-NHNTX6ZL.js → chunk-ZG6YJUT4.js} +3 -2
  44. package/dist/components/index.d.ts +228 -6
  45. package/dist/components/index.js +321 -35
  46. package/dist/components/navigation/index.js +6 -7
  47. package/dist/features/auth/index.d.ts +78 -2
  48. package/dist/features/auth/index.js +18 -9
  49. package/dist/features/clients/index.js +7 -7
  50. package/dist/features/content/index.d.ts +226 -5
  51. package/dist/features/content/index.js +270 -19
  52. package/dist/features/crm/index.d.ts +58 -0
  53. package/dist/features/crm/index.js +10 -8
  54. package/dist/features/dashboard/index.js +9 -8
  55. package/dist/features/delivery/index.d.ts +58 -0
  56. package/dist/features/delivery/index.js +23 -7
  57. package/dist/features/knowledge/index.js +5 -6
  58. package/dist/features/lead-gen/index.d.ts +9 -15
  59. package/dist/features/lead-gen/index.js +12 -8
  60. package/dist/features/monitoring/index.js +11 -9
  61. package/dist/features/monitoring/requests/index.js +8 -7
  62. package/dist/features/operations/index.js +15 -11
  63. package/dist/features/public-agent-chat/index.js +3 -1
  64. package/dist/features/settings/index.d.ts +66 -3
  65. package/dist/features/settings/index.js +9 -8
  66. package/dist/hooks/access/index.js +5 -6
  67. package/dist/hooks/delivery/index.d.ts +58 -0
  68. package/dist/hooks/delivery/index.js +3 -2
  69. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +1 -1
  70. package/dist/hooks/published.d.ts +181 -5
  71. package/dist/hooks/published.js +22 -6
  72. package/dist/initialization/index.d.ts +58 -0
  73. package/dist/knowledge/index.js +167 -11
  74. package/dist/{knowledge-search-index-RZLIVWPJ.js → knowledge-search-index-6GQK55IQ.js} +1 -1
  75. package/dist/layout/index.js +8 -9
  76. package/dist/profile/index.d.ts +58 -0
  77. package/dist/provider/index.d.ts +77 -1
  78. package/dist/provider/index.js +5 -6
  79. package/dist/provider/published.d.ts +105 -1
  80. package/dist/provider/published.js +5 -6
  81. package/dist/test-utils/index.d.ts +16 -5
  82. package/dist/test-utils/index.js +17 -18
  83. package/dist/types/index.d.ts +73 -1
  84. package/dist/utils/index.d.ts +83 -3
  85. package/dist/utils/index.js +1 -1
  86. package/package.json +10 -5
  87. package/dist/chunk-6M6OLGQY.js +0 -36
  88. package/dist/chunk-MKH2KOAO.js +0 -39
  89. package/dist/hooks/index.css +0 -659
  90. package/dist/hooks/index.d.ts +0 -14073
  91. package/dist/hooks/index.js +0 -27
  92. package/dist/supabase/index.d.ts +0 -7118
  93. package/dist/supabase/index.js +0 -3
  94. package/dist/typeform/index.d.ts +0 -462
  95. package/dist/typeform/index.js +0 -2051
  96. package/dist/typeform/schemas.d.ts +0 -67
  97. package/dist/typeform/schemas.js +0 -2
@@ -1,56 +1,28 @@
1
1
  import { useAvailablePresets } from './chunk-ZFISGKYW.js';
2
- import { AppShellLoader } from './chunk-3TS5U5BL.js';
2
+ import { MEMBERSHIP_STATUS_COLORS, PROVISIONING_STATE_DISPLAY, transformMembershipToTableRow, useUserMemberships, useUpdateWebhookEndpoint, useDeleteWebhookEndpoint, useCreateWebhookEndpoint, useListWebhookEndpoints, useOrgRoles, useAssignRole, useRevokeRole, useOrganizationMembers, usePermissionCatalog } from './chunk-QFS2GZMV.js';
3
+ import { useUpdateCredential, CredentialSchemas } from './chunk-G7O4CBMC.js';
4
+ import { AppShellLoader } from './chunk-5RH6NYZH.js';
3
5
  import { FilterBar } from './chunk-PDHTXPSF.js';
4
- import { useDeleteCredential, ListSkeleton, EmptyState, CustomModal, useCreateCredential, useCredentials, PageTitleCaption, MEMBERSHIP_STATUS_COLORS, PROVISIONING_STATE_DISPLAY, transformMembershipToTableRow, APIErrorAlert, useUserMemberships, useUpdateWebhookEndpoint, useResources, useDeleteWebhookEndpoint, useCreateWebhookEndpoint, useListWebhookEndpoints, StatCard, useOrgRoles, useAssignRole, useRevokeRole, useAccess, AccessKeys, useOrganizationMembers, usePermissionCatalog, AccessGuard, useUpdateCredential, CredentialSchemas } from './chunk-OCVSPAKM.js';
5
- import { showApiErrorNotification, showErrorNotification, showSuccessNotification } from './chunk-U2H3TIHD.js';
6
+ import { CustomModal, APIErrorAlert, EmptyState, PageTitleCaption, useResources, ListSkeleton, StatCard, useAccess, AccessKeys, AccessGuard } from './chunk-SB3IHM5Y.js';
7
+ import { showApiErrorNotification, showErrorNotification, showSuccessNotification } from './chunk-ICHDIVQO.js';
6
8
  import { CardHeader } from './chunk-62GVNH5U.js';
7
9
  import { useInitialization } from './chunk-P45GQ3ZW.js';
8
10
  import { RoleBadge } from './chunk-UD657ICS.js';
9
11
  import { useOrganization } from './chunk-DD3CCMCZ.js';
10
- import { isAPIClientError, formatDateTime, OAUTH_FLOW_TIMEOUT } from './chunk-IBCEAVB2.js';
12
+ import { isAPIClientError, formatDateTime, OAUTH_FLOW_TIMEOUT } from './chunk-A2SB32YV.js';
11
13
  import { useElevasisServices } from './chunk-BI5VDO2K.js';
12
14
  import { brandSupabaseOrgId } from './chunk-MQZE7SUI.js';
13
15
  import { useAuthContext } from './chunk-BRJ3QZ4E.js';
14
- import { createUseExternalEvents, Text, Table, Group, Tooltip, ActionIcon, Stack, Title, Button, Select, TextInput, Alert, PasswordInput, Anchor, Paper, Badge, Center, Loader, Box, Code, CopyButton, ThemeIcon, SimpleGrid, UnstyledButton, Card, Switch, Divider, Textarea, MultiSelect } from '@mantine/core';
15
- import { IconShieldOff, IconKey, IconCalendar, IconPencil, IconTrash, IconAlertTriangle, IconInfoCircle, IconExclamationMark, IconPlus, IconAlertCircle, IconUsers, IconSearch, IconBuilding, IconWebhook, IconCheck, IconCopy, IconUser, IconMail, IconPalette, IconEye, IconSparkles, IconTrendingUp, IconClock, IconPlayerPause, IconPlayerPlay, IconActivity, IconShieldLock, IconStar, IconUserCog, IconUsersGroup, IconSettings, IconRefresh, IconBrandDropbox, IconBrandGoogleDrive, IconPlug, IconEdit, IconUserX, IconUserCheck } from '@tabler/icons-react';
16
- import { randomId } from '@mantine/hooks';
16
+ import { Text, Stack, Title, Alert, TextInput, Group, Button, Paper, SimpleGrid, Card, ThemeIcon, Badge, Tooltip, Select, Table, Center, Loader, Box, Code, CopyButton, ActionIcon, UnstyledButton, Switch, Divider, Textarea, MultiSelect, PasswordInput } from '@mantine/core';
17
+ import { IconShieldOff, IconAlertCircle, IconBrandDropbox, IconBrandGoogleDrive, IconPlug, IconUsers, IconSearch, IconBuilding, IconWebhook, IconCheck, IconCopy, IconUser, IconMail, IconPalette, IconEye, IconSparkles, IconTrendingUp, IconExclamationMark, IconPencil, IconClock, IconPlayerPause, IconPlayerPlay, IconTrash, IconAlertTriangle, IconPlus, IconActivity, IconShieldLock, IconStar, IconUserCog, IconUsersGroup, IconSettings, IconRefresh, IconEdit, IconUserX, IconUserCheck } from '@tabler/icons-react';
18
+ import { modals } from '@mantine/modals';
17
19
  import { notifications } from '@mantine/notifications';
18
20
  import { z } from 'zod';
19
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
20
22
  import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
21
- import { useForm } from '@mantine/form';
22
- import { create } from 'zustand';
23
23
  import { useQueryClient } from '@tanstack/react-query';
24
-
25
- var [useModalsEvents, createEvent] = createUseExternalEvents("mantine-modals");
26
- var openModal = (payload) => {
27
- const id = payload.modalId || randomId();
28
- createEvent("openModal")({ ...payload, modalId: id });
29
- return id;
30
- };
31
- var openConfirmModal = (payload) => {
32
- const id = payload.modalId || randomId();
33
- createEvent("openConfirmModal")({ ...payload, modalId: id });
34
- return id;
35
- };
36
- var openContextModal = (payload) => {
37
- const id = payload.modalId || randomId();
38
- createEvent("openContextModal")({ ...payload, modalId: id });
39
- return id;
40
- };
41
- var closeModal = createEvent("closeModal");
42
- var closeAllModals = createEvent("closeAllModals");
43
- var updateModal = (payload) => createEvent("updateModal")(payload);
44
- var updateContextModal = (payload) => createEvent("updateContextModal")(payload);
45
- var modals = {
46
- open: openModal,
47
- close: closeModal,
48
- closeAll: closeAllModals,
49
- openConfirmModal,
50
- openContextModal,
51
- updateModal,
52
- updateContextModal
53
- };
24
+ import { create } from 'zustand';
25
+ import { useForm } from '@mantine/form';
54
26
 
55
27
  // ../core/src/integrations/oauth/provider-registry.ts
56
28
  var OAUTH_PROVIDERS = {
@@ -236,6 +208,31 @@ var CREDENTIAL_SCHEMAS = {
236
208
  ],
237
209
  docsUrl: "https://developer.clickup.com/docs/authentication",
238
210
  nameSuggestions: ["clickup-demo", "clickup-prod", "clickup-dev"]
211
+ },
212
+ instagram: {
213
+ type: "single_field",
214
+ label: "Instagram",
215
+ description: "Long-lived Instagram access token for publishing through Meta\u2019s Content Publishing API.",
216
+ fields: [
217
+ {
218
+ key: "accessToken",
219
+ label: "Access Token",
220
+ type: "password",
221
+ required: true,
222
+ placeholder: "IGAA...",
223
+ description: "Long-lived token from the Meta app dashboard. Valid 60 days from issue or last refresh."
224
+ },
225
+ {
226
+ key: "igUserId",
227
+ label: "Instagram User ID",
228
+ type: "text",
229
+ required: true,
230
+ placeholder: "17841400000000000",
231
+ description: "The Instagram professional account id shown beside the token on the same Meta screen."
232
+ }
233
+ ],
234
+ docsUrl: "https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/content-publishing",
235
+ nameSuggestions: ["elevasis-instagram", "instagram-prod", "instagram-dev"]
239
236
  }
240
237
  };
241
238
  function getCredentialSchema(type) {
@@ -288,279 +285,6 @@ function showAuthError(error) {
288
285
  }
289
286
  showApiErrorNotification(error);
290
287
  }
291
- function CredentialList({ credentials, isLoading, onEdit }) {
292
- const [deleteCredential, setDeleteCredential] = useState(null);
293
- const deleteMutation = useDeleteCredential();
294
- const handleDelete = () => {
295
- if (deleteCredential) {
296
- deleteMutation.mutate(deleteCredential.id);
297
- setDeleteCredential(null);
298
- }
299
- };
300
- const handleCloseDelete = () => {
301
- if (!deleteMutation.isPending) {
302
- setDeleteCredential(null);
303
- }
304
- };
305
- if (isLoading) {
306
- return /* @__PURE__ */ jsx(ListSkeleton, { rows: 3, rowHeight: 60 });
307
- }
308
- if (credentials.length === 0) {
309
- return /* @__PURE__ */ jsx(
310
- EmptyState,
311
- {
312
- icon: IconKey,
313
- title: "No credentials yet",
314
- description: "Create your first credential to enable external service integrations"
315
- }
316
- );
317
- }
318
- return /* @__PURE__ */ jsxs(Fragment, { children: [
319
- /* @__PURE__ */ jsxs(Table, { children: [
320
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
321
- /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
322
- /* @__PURE__ */ jsx(Table.Th, { children: "Created" }),
323
- /* @__PURE__ */ jsx(Table.Th, { w: 100 })
324
- ] }) }),
325
- /* @__PURE__ */ jsx(Table.Tbody, { children: credentials.map((credential) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
326
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
327
- /* @__PURE__ */ jsx(IconKey, { size: 16, style: { opacity: 0.6 } }),
328
- /* @__PURE__ */ jsx(Text, { fw: 500, children: credential.name })
329
- ] }) }),
330
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
331
- /* @__PURE__ */ jsx(IconCalendar, { size: 14, style: { opacity: 0.5 } }),
332
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: formatDateTime(credential.createdAt) })
333
- ] }) }),
334
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", children: [
335
- onEdit && /* @__PURE__ */ jsx(Tooltip, { label: "Edit credential", children: /* @__PURE__ */ jsx(
336
- ActionIcon,
337
- {
338
- variant: "subtle",
339
- color: "gray",
340
- onClick: () => onEdit(credential),
341
- disabled: deleteMutation.isPending,
342
- children: /* @__PURE__ */ jsx(IconPencil, { size: 16 })
343
- }
344
- ) }),
345
- /* @__PURE__ */ jsx(Tooltip, { label: "Delete credential", position: "left", children: /* @__PURE__ */ jsx(
346
- ActionIcon,
347
- {
348
- variant: "subtle",
349
- color: "red",
350
- onClick: () => setDeleteCredential(credential),
351
- disabled: deleteMutation.isPending,
352
- children: /* @__PURE__ */ jsx(IconTrash, { size: 16 })
353
- }
354
- ) })
355
- ] }) })
356
- ] }, credential.id)) })
357
- ] }),
358
- /* @__PURE__ */ jsx(CustomModal, { opened: !!deleteCredential, onClose: handleCloseDelete, size: "md", loading: deleteMutation.isPending, children: /* @__PURE__ */ jsxs(Stack, { children: [
359
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
360
- /* @__PURE__ */ jsx(IconAlertTriangle, { size: 24, color: "var(--color-error)" }),
361
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Delete Credential" })
362
- ] }),
363
- /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
364
- "Are you sure you want to delete",
365
- " ",
366
- /* @__PURE__ */ jsxs(Text, { span: true, fw: 600, children: [
367
- '"',
368
- deleteCredential?.name,
369
- '"'
370
- ] }),
371
- "?"
372
- ] }),
373
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "This action cannot be undone. Any agents or tools using this credential will stop working immediately." }),
374
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "sm", children: [
375
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleCloseDelete, disabled: deleteMutation.isPending, children: "Cancel" }),
376
- /* @__PURE__ */ jsx(
377
- Button,
378
- {
379
- color: "red",
380
- onClick: handleDelete,
381
- loading: deleteMutation.isPending,
382
- leftSection: /* @__PURE__ */ jsx(IconTrash, { size: 16 }),
383
- children: "Delete Credential"
384
- }
385
- )
386
- ] })
387
- ] }) })
388
- ] });
389
- }
390
- function CreateCredentialModal({ opened, onClose, onSuccess }) {
391
- const createCredential = useCreateCredential();
392
- const [selectedType, setSelectedType] = useState("api-key");
393
- const [schema, setSchema] = useState(getCredentialSchema("api-key"));
394
- useEffect(() => {
395
- setSchema(getCredentialSchema(selectedType));
396
- }, [selectedType]);
397
- const getInitialValues = (currentSchema) => {
398
- const values = { name: "" };
399
- if (currentSchema.fields) {
400
- currentSchema.fields.forEach((field) => {
401
- values[field.key] = "";
402
- });
403
- }
404
- return values;
405
- };
406
- const getValidation = (currentSchema) => {
407
- const validation = {
408
- name: (value) => {
409
- const result = CredentialSchemas.CreateRequest.shape.name.safeParse(value);
410
- return result.success ? null : result.error.issues[0]?.message || "Invalid credential name";
411
- }
412
- };
413
- if (currentSchema.fields) {
414
- currentSchema.fields.forEach((field) => {
415
- if (field.required) {
416
- validation[field.key] = (value) => !value.trim() ? `${field.label} is required` : null;
417
- }
418
- });
419
- }
420
- return validation;
421
- };
422
- const form = useForm({
423
- initialValues: getInitialValues(schema),
424
- validate: getValidation(schema)
425
- });
426
- useEffect(() => {
427
- const newValues = getInitialValues(schema);
428
- form.setValues(newValues);
429
- form.setFieldValue("name", form.values.name || "");
430
- form.resetDirty();
431
- }, [selectedType]);
432
- const handleSubmit = async (values) => {
433
- if (schema.type === "oauth") {
434
- console.error("OAuth credentials cannot be created via this modal");
435
- return;
436
- }
437
- const data = {
438
- name: values.name.trim(),
439
- type: selectedType,
440
- value: buildCredentialValue(selectedType, values)
441
- };
442
- const validationResult = CredentialSchemas.CreateRequest.safeParse(data);
443
- if (!validationResult.success) {
444
- console.error("Validation failed:", validationResult.error);
445
- return;
446
- }
447
- try {
448
- const result = await createCredential.mutateAsync(data);
449
- form.reset();
450
- setSelectedType("api-key");
451
- onSuccess(result);
452
- } catch (error) {
453
- console.error("Failed to create credential:", error);
454
- }
455
- };
456
- const handleClose = () => {
457
- if (!createCredential.isPending) {
458
- form.reset();
459
- setSelectedType("api-key");
460
- onClose();
461
- }
462
- };
463
- return /* @__PURE__ */ jsx(CustomModal, { opened, onClose: handleClose, size: "lg", loading: createCredential.isPending, children: /* @__PURE__ */ jsx("form", { onSubmit: form.onSubmit(handleSubmit), children: /* @__PURE__ */ jsxs(Stack, { children: [
464
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Create New Credential" }),
465
- /* @__PURE__ */ jsx(
466
- Select,
467
- {
468
- label: "Credential Type",
469
- description: "Select the integration type",
470
- placeholder: "Select credential type",
471
- data: Object.entries(CREDENTIAL_SCHEMAS).filter(([_, s]) => s.type !== "oauth").map(([key, s]) => ({ value: key, label: s.label })),
472
- value: selectedType,
473
- onChange: (value) => setSelectedType(value || "api-key"),
474
- required: true,
475
- disabled: createCredential.isPending
476
- }
477
- ),
478
- /* @__PURE__ */ jsx(
479
- TextInput,
480
- {
481
- label: "Credential Name",
482
- description: schema.nameSuggestions.length > 0 ? `Suggested: ${schema.nameSuggestions.join(", ")}` : "Lowercase letters, numbers, and hyphens only (e.g., service-dev, service-prod)",
483
- placeholder: schema.nameSuggestions[0] || "e.g., service-prod",
484
- leftSection: /* @__PURE__ */ jsx(IconKey, { size: 16 }),
485
- maxLength: 100,
486
- required: true,
487
- ...form.getInputProps("name"),
488
- disabled: createCredential.isPending
489
- }
490
- ),
491
- schema.type === "oauth" ? /* @__PURE__ */ jsxs(Alert, { icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: 16 }), color: "blue", children: [
492
- schema.label,
493
- " uses OAuth authentication. Please go to the OAuth Integrations page to connect your",
494
- " ",
495
- schema.label,
496
- " account."
497
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
498
- schema.fields?.map((field) => /* @__PURE__ */ jsx(
499
- PasswordInput,
500
- {
501
- label: field.label,
502
- description: field.description,
503
- placeholder: field.placeholder,
504
- required: field.required,
505
- value: form.values[field.key] || "",
506
- onChange: (e) => form.setFieldValue(field.key, e.target.value),
507
- error: form.errors[field.key],
508
- disabled: createCredential.isPending
509
- },
510
- field.key
511
- )),
512
- schema.docsUrl && /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
513
- "Get credentials from",
514
- " ",
515
- /* @__PURE__ */ jsx(Anchor, { href: schema.docsUrl, target: "_blank", rel: "noopener noreferrer", children: schema.docsUrl })
516
- ] })
517
- ] }),
518
- createCredential.error && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconExclamationMark, { size: 16 }), color: "red", children: createCredential.error instanceof Error ? createCredential.error.message : "An error occurred while creating the credential" }),
519
- /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "sm", children: [
520
- /* @__PURE__ */ jsx(Button, { variant: "subtle", onClick: handleClose, disabled: createCredential.isPending, children: "Cancel" }),
521
- /* @__PURE__ */ jsx(Button, { type: "submit", loading: createCredential.isPending, leftSection: /* @__PURE__ */ jsx(IconKey, { size: 16 }), children: "Create Credential" })
522
- ] })
523
- ] }) }) });
524
- }
525
- function CredentialSettings({ oauthSection }) {
526
- const { organizationReady } = useInitialization();
527
- const [showCreateModal, setShowCreateModal] = useState(false);
528
- const { data: credentials = [], isLoading } = useCredentials();
529
- if (!organizationReady) return /* @__PURE__ */ jsx(AppShellLoader, {});
530
- const handleCredentialCreated = () => {
531
- setShowCreateModal(false);
532
- };
533
- return /* @__PURE__ */ jsxs(Stack, { children: [
534
- /* @__PURE__ */ jsx(
535
- PageTitleCaption,
536
- {
537
- title: "Organization Credentials",
538
- caption: "Manage encrypted credentials for third-party service integrations"
539
- }
540
- ),
541
- oauthSection,
542
- /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
543
- /* @__PURE__ */ jsx(
544
- CardHeader,
545
- {
546
- icon: /* @__PURE__ */ jsx(IconKey, { size: 18 }),
547
- title: "Credentials",
548
- subtitle: "Configured API keys and credentials",
549
- rightSection: /* @__PURE__ */ jsx(Button, { leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 16 }), onClick: () => setShowCreateModal(true), variant: "light", children: "Create Credential" })
550
- }
551
- ),
552
- /* @__PURE__ */ jsx(CredentialList, { credentials, isLoading })
553
- ] }),
554
- /* @__PURE__ */ jsx(
555
- CreateCredentialModal,
556
- {
557
- opened: showCreateModal,
558
- onClose: () => setShowCreateModal(false),
559
- onSuccess: handleCredentialCreated
560
- }
561
- )
562
- ] });
563
- }
564
288
  function OAuthConnectModal({ opened, onClose, provider, onConnect, error, isLoading }) {
565
289
  const [credentialName, setCredentialName] = useState("");
566
290
  useEffect(() => {
@@ -598,25 +322,236 @@ function OAuthConnectModal({ opened, onClose, provider, onConnect, error, isLoad
598
322
  ] }),
599
323
  error && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), color: "red", title: "Connection Failed", children: error }),
600
324
  /* @__PURE__ */ jsx(
601
- TextInput,
325
+ TextInput,
326
+ {
327
+ label: "Credential Name",
328
+ placeholder: `${provider.id}-prod`,
329
+ value: credentialName,
330
+ onChange: (e) => setCredentialName(e.target.value),
331
+ required: true,
332
+ disabled: isLoading,
333
+ description: "Use naming convention to indicate environment (e.g., notion-dev, slack-prod)"
334
+ }
335
+ ),
336
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mt: "md", children: [
337
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, disabled: isLoading, children: "Cancel" }),
338
+ /* @__PURE__ */ jsxs(Button, { onClick: handleConnect, loading: isLoading, disabled: !credentialName.trim(), children: [
339
+ "Connect ",
340
+ provider.name
341
+ ] })
342
+ ] })
343
+ ] }) });
344
+ }
345
+ var OAUTH_COMPLETION_CHANNEL = "elevasis-oauth";
346
+ var OAUTH_COMPLETION_STORAGE_KEY = "elevasis:oauth-complete";
347
+ function useOAuthFlow({ apiUrl: apiUrlOverride } = {}) {
348
+ const [isAuthorizing, setIsAuthorizing] = useState(false);
349
+ const [error, setError] = useState(null);
350
+ const { isReady, apiUrl: contextApiUrl } = useElevasisServices();
351
+ const { getAccessToken, organizationId } = useAuthContext();
352
+ const apiUrl = apiUrlOverride ?? contextApiUrl;
353
+ const authorize = useCallback(
354
+ async (provider, credentialName) => {
355
+ if (!isReady || !organizationId) {
356
+ setError("Organization context not ready");
357
+ return;
358
+ }
359
+ setIsAuthorizing(true);
360
+ setError(null);
361
+ const width = 600;
362
+ const height = 700;
363
+ const left = Math.round(window.screen.width / 2 - width / 2);
364
+ const top = Math.round(window.screen.height / 2 - height / 2);
365
+ const popup = window.open(
366
+ "about:blank",
367
+ `oauth-${provider}`,
368
+ `width=${width},height=${height},left=${left},top=${top}`
369
+ );
370
+ if (!popup) {
371
+ setIsAuthorizing(false);
372
+ setError("Please enable popups and try again");
373
+ return;
374
+ }
375
+ let token;
376
+ try {
377
+ token = await getAccessToken();
378
+ } catch {
379
+ popup.close();
380
+ setIsAuthorizing(false);
381
+ setError("Authorization failed. Please sign in again.");
382
+ return;
383
+ }
384
+ try {
385
+ const authorizeUrl = new URL(`${apiUrl}/api/oauth/authorize/${provider}`);
386
+ authorizeUrl.searchParams.set("credentialName", credentialName);
387
+ authorizeUrl.searchParams.set("token", token);
388
+ authorizeUrl.searchParams.set("orgId", organizationId);
389
+ authorizeUrl.searchParams.set("appOrigin", window.location.origin);
390
+ popup.location.href = authorizeUrl.toString();
391
+ await waitForOAuthCallback(popup, Date.now());
392
+ } catch (err) {
393
+ const rawError = err instanceof Error ? err.message : "unknown";
394
+ if (rawError.includes("popup_blocked")) {
395
+ setError("Please enable popups and try again");
396
+ } else if (rawError.includes("timeout")) {
397
+ setError("Authorization timed out. Please try again.");
398
+ } else if (rawError.includes("popup_closed")) {
399
+ setError("Authorization was cancelled.");
400
+ } else if (rawError.includes("token_exchange_failed")) {
401
+ setError("Failed to obtain access token. Please try again.");
402
+ } else if (rawError.includes("invalid_state")) {
403
+ setError("Security validation failed. Please try again.");
404
+ } else if (rawError.includes("state_expired")) {
405
+ setError("Authorization expired. Please try again.");
406
+ } else {
407
+ setError(`Failed to connect: ${rawError}`);
408
+ }
409
+ throw err;
410
+ } finally {
411
+ setIsAuthorizing(false);
412
+ }
413
+ },
414
+ [isReady, organizationId, apiUrl, getAccessToken]
415
+ );
416
+ const waitForOAuthCallback = (popup, startedAt) => {
417
+ return new Promise((resolve, reject) => {
418
+ let broadcastChannel = null;
419
+ const complete = (data) => {
420
+ const payload = parseOAuthCompletionPayload(data, startedAt);
421
+ if (!payload) return;
422
+ cleanup();
423
+ if (payload.status === "success") {
424
+ resolve();
425
+ } else {
426
+ reject(new Error(payload.error || "oauth_failed"));
427
+ }
428
+ };
429
+ const messageHandler = (event) => {
430
+ if (!isTrustedCallbackOrigin(event.origin)) return;
431
+ complete(event.data);
432
+ };
433
+ const storageHandler = (event) => {
434
+ if (event.key !== OAUTH_COMPLETION_STORAGE_KEY || !event.newValue) return;
435
+ try {
436
+ complete(JSON.parse(event.newValue));
437
+ } catch {
438
+ }
439
+ };
440
+ const rejectIfPopupClosed = () => {
441
+ if (popup.closed) {
442
+ cleanup();
443
+ reject(new Error("popup_closed"));
444
+ }
445
+ };
446
+ window.addEventListener("message", messageHandler);
447
+ window.addEventListener("storage", storageHandler);
448
+ window.addEventListener("focus", rejectIfPopupClosed);
449
+ if ("BroadcastChannel" in window) {
450
+ broadcastChannel = new BroadcastChannel(OAUTH_COMPLETION_CHANNEL);
451
+ broadcastChannel.onmessage = (event) => complete(event.data);
452
+ }
453
+ const timeout = setTimeout(() => {
454
+ cleanup();
455
+ reject(new Error("timeout"));
456
+ }, OAUTH_FLOW_TIMEOUT);
457
+ const cleanup = () => {
458
+ clearTimeout(timeout);
459
+ broadcastChannel?.close();
460
+ window.removeEventListener("focus", rejectIfPopupClosed);
461
+ window.removeEventListener("storage", storageHandler);
462
+ window.removeEventListener("message", messageHandler);
463
+ };
464
+ });
465
+ };
466
+ return { authorize, isAuthorizing, error };
467
+ }
468
+ function parseOAuthCompletionPayload(data, startedAt) {
469
+ if (!data || typeof data !== "object") return null;
470
+ const payload = data;
471
+ if (payload.type !== "oauth-complete") return null;
472
+ if (payload.completedAt && payload.completedAt < startedAt) return null;
473
+ return payload;
474
+ }
475
+ function isTrustedCallbackOrigin(origin) {
476
+ if (origin === window.location.origin || origin === "https://app.elevasis.io") {
477
+ return true;
478
+ }
479
+ try {
480
+ const url = new URL(origin);
481
+ return url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
482
+ } catch {
483
+ return false;
484
+ }
485
+ }
486
+ var PROVIDER_ICONS = {
487
+ "google-sheets": IconBrandGoogleDrive,
488
+ dropbox: IconBrandDropbox
489
+ };
490
+ function OAuthIntegrationsCard({ apiUrl } = {}) {
491
+ const [selectedProviderId, setSelectedProviderId] = useState(null);
492
+ const [modalOpened, setModalOpened] = useState(false);
493
+ const { authorize, isAuthorizing, error } = useOAuthFlow({ apiUrl });
494
+ const queryClient = useQueryClient();
495
+ const handleConnect = async (credentialName) => {
496
+ if (!selectedProviderId) return;
497
+ try {
498
+ await authorize(selectedProviderId, credentialName);
499
+ setModalOpened(false);
500
+ setSelectedProviderId(null);
501
+ queryClient.invalidateQueries({ queryKey: ["credentials"] });
502
+ } catch (err) {
503
+ console.error("OAuth flow failed:", err);
504
+ }
505
+ };
506
+ const handleOpenModal = (providerId) => {
507
+ setSelectedProviderId(providerId);
508
+ setModalOpened(true);
509
+ };
510
+ useEffect(() => {
511
+ const params = new URLSearchParams(window.location.search);
512
+ const requested = params.get("connect");
513
+ if (requested && OAUTH_PROVIDERS[requested]) {
514
+ handleOpenModal(requested);
515
+ params.delete("connect");
516
+ const remaining = params.toString();
517
+ const newUrl = window.location.pathname + (remaining ? `?${remaining}` : "") + window.location.hash;
518
+ window.history.replaceState({}, "", newUrl);
519
+ }
520
+ }, []);
521
+ const providers = Object.values(OAUTH_PROVIDERS);
522
+ const selectedProvider = selectedProviderId ? OAUTH_PROVIDERS[selectedProviderId] : null;
523
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
524
+ /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { children: [
525
+ /* @__PURE__ */ jsx(Group, { justify: "space-between", children: /* @__PURE__ */ jsxs("div", { children: [
526
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "OAuth Integrations" }),
527
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mt: 4, children: "Connect third-party services using OAuth 2.0" })
528
+ ] }) }),
529
+ /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2, md: 3 }, children: providers.map((provider) => {
530
+ const Icon = PROVIDER_ICONS[provider.id] || IconPlug;
531
+ return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { children: [
532
+ /* @__PURE__ */ jsx(Group, { justify: "space-between", align: "flex-start", children: /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
533
+ /* @__PURE__ */ jsx(ThemeIcon, { size: "lg", variant: "light", children: /* @__PURE__ */ jsx(Icon, { size: 20 }) }),
534
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { fw: 600, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: provider.name }) })
535
+ ] }) }),
536
+ /* @__PURE__ */ jsx(Button, { variant: "filled", size: "sm", onClick: () => handleOpenModal(provider.id), fullWidth: true, children: "Connect" })
537
+ ] }) }, provider.id);
538
+ }) })
539
+ ] }) }),
540
+ /* @__PURE__ */ jsx(
541
+ OAuthConnectModal,
602
542
  {
603
- label: "Credential Name",
604
- placeholder: `${provider.id}-prod`,
605
- value: credentialName,
606
- onChange: (e) => setCredentialName(e.target.value),
607
- required: true,
608
- disabled: isLoading,
609
- description: "Use naming convention to indicate environment (e.g., notion-dev, slack-prod)"
543
+ opened: modalOpened,
544
+ onClose: () => {
545
+ setModalOpened(false);
546
+ setSelectedProviderId(null);
547
+ },
548
+ provider: selectedProvider,
549
+ onConnect: handleConnect,
550
+ error,
551
+ isLoading: isAuthorizing
610
552
  }
611
- ),
612
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mt: "md", children: [
613
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, disabled: isLoading, children: "Cancel" }),
614
- /* @__PURE__ */ jsxs(Button, { onClick: handleConnect, loading: isLoading, disabled: !credentialName.trim(), children: [
615
- "Connect ",
616
- provider.name
617
- ] })
618
- ] })
619
- ] }) });
553
+ )
554
+ ] });
620
555
  }
621
556
  function MembershipStatusBadge({ status, size = "sm", variant = "light" }) {
622
557
  const getStatusLabel = (status2) => {
@@ -1612,7 +1547,7 @@ function OrgMembersList({ orgId }) {
1612
1547
  const [selectedMember, setSelectedMember] = useState(null);
1613
1548
  const [modalOpened, setModalOpened] = useState(false);
1614
1549
  const [defaultTab, setDefaultTab] = useState("roles");
1615
- const openModal2 = (member, tab) => {
1550
+ const openModal = (member, tab) => {
1616
1551
  setSelectedMember(member);
1617
1552
  setDefaultTab(tab);
1618
1553
  setModalOpened(true);
@@ -1661,7 +1596,7 @@ function OrgMembersList({ orgId }) {
1661
1596
  /* @__PURE__ */ jsx(MembershipStatusBadge, { status: member.status }),
1662
1597
  /* @__PURE__ */ jsx(ProvisioningStateBadge, { state: member.provisioningState })
1663
1598
  ] }) }),
1664
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Tooltip, { label: "Edit member access", withArrow: true, children: /* @__PURE__ */ jsx(ActionIcon, { variant: "light", size: "sm", color: "gray", onClick: () => openModal2(member, "roles"), children: /* @__PURE__ */ jsx(IconPencil, { size: 14 }) }) }) })
1599
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Tooltip, { label: "Edit member access", withArrow: true, children: /* @__PURE__ */ jsx(ActionIcon, { variant: "light", size: "sm", color: "gray", onClick: () => openModal(member, "roles"), children: /* @__PURE__ */ jsx(IconPencil, { size: 14 }) }) }) })
1665
1600
  ] }, member.id);
1666
1601
  }) })
1667
1602
  ] }) }),
@@ -1813,145 +1748,6 @@ function MyRolesPage({ onManageMembers, onManageOrganizationRoles }) {
1813
1748
  ] }) }) })
1814
1749
  ] });
1815
1750
  }
1816
- var OAUTH_COMPLETION_CHANNEL = "elevasis-oauth";
1817
- var OAUTH_COMPLETION_STORAGE_KEY = "elevasis:oauth-complete";
1818
- function useOAuthFlow({ apiUrl }) {
1819
- const [isAuthorizing, setIsAuthorizing] = useState(false);
1820
- const [error, setError] = useState(null);
1821
- const { isReady } = useElevasisServices();
1822
- const { getAccessToken, organizationId } = useAuthContext();
1823
- const authorize = useCallback(
1824
- async (provider, credentialName) => {
1825
- if (!isReady || !organizationId) {
1826
- setError("Organization context not ready");
1827
- return;
1828
- }
1829
- setIsAuthorizing(true);
1830
- setError(null);
1831
- const width = 600;
1832
- const height = 700;
1833
- const left = Math.round(window.screen.width / 2 - width / 2);
1834
- const top = Math.round(window.screen.height / 2 - height / 2);
1835
- const popup = window.open(
1836
- "about:blank",
1837
- `oauth-${provider}`,
1838
- `width=${width},height=${height},left=${left},top=${top}`
1839
- );
1840
- if (!popup) {
1841
- setIsAuthorizing(false);
1842
- setError("Please enable popups and try again");
1843
- return;
1844
- }
1845
- let token;
1846
- try {
1847
- token = await getAccessToken();
1848
- } catch {
1849
- popup.close();
1850
- setIsAuthorizing(false);
1851
- setError("Authorization failed. Please sign in again.");
1852
- return;
1853
- }
1854
- try {
1855
- const authorizeUrl = new URL(`${apiUrl}/api/oauth/authorize/${provider}`);
1856
- authorizeUrl.searchParams.set("credentialName", credentialName);
1857
- authorizeUrl.searchParams.set("token", token);
1858
- authorizeUrl.searchParams.set("orgId", organizationId);
1859
- popup.location.href = authorizeUrl.toString();
1860
- await waitForOAuthCallback(popup, Date.now());
1861
- } catch (err) {
1862
- const rawError = err instanceof Error ? err.message : "unknown";
1863
- if (rawError.includes("popup_blocked")) {
1864
- setError("Please enable popups and try again");
1865
- } else if (rawError.includes("timeout")) {
1866
- setError("Authorization timed out. Please try again.");
1867
- } else if (rawError.includes("popup_closed")) {
1868
- setError("Authorization was cancelled.");
1869
- } else if (rawError.includes("token_exchange_failed")) {
1870
- setError("Failed to obtain access token. Please try again.");
1871
- } else if (rawError.includes("invalid_state")) {
1872
- setError("Security validation failed. Please try again.");
1873
- } else if (rawError.includes("state_expired")) {
1874
- setError("Authorization expired. Please try again.");
1875
- } else {
1876
- setError(`Failed to connect: ${rawError}`);
1877
- }
1878
- throw err;
1879
- } finally {
1880
- setIsAuthorizing(false);
1881
- }
1882
- },
1883
- [isReady, organizationId, apiUrl, getAccessToken]
1884
- );
1885
- const waitForOAuthCallback = (popup, startedAt) => {
1886
- return new Promise((resolve, reject) => {
1887
- let broadcastChannel = null;
1888
- const complete = (data) => {
1889
- const payload = parseOAuthCompletionPayload(data, startedAt);
1890
- if (!payload) return;
1891
- cleanup();
1892
- if (payload.status === "success") {
1893
- resolve();
1894
- } else {
1895
- reject(new Error(payload.error || "oauth_failed"));
1896
- }
1897
- };
1898
- const messageHandler = (event) => {
1899
- if (!isTrustedCallbackOrigin(event.origin)) return;
1900
- complete(event.data);
1901
- };
1902
- const storageHandler = (event) => {
1903
- if (event.key !== OAUTH_COMPLETION_STORAGE_KEY || !event.newValue) return;
1904
- try {
1905
- complete(JSON.parse(event.newValue));
1906
- } catch {
1907
- }
1908
- };
1909
- const rejectIfPopupClosed = () => {
1910
- if (popup.closed) {
1911
- cleanup();
1912
- reject(new Error("popup_closed"));
1913
- }
1914
- };
1915
- window.addEventListener("message", messageHandler);
1916
- window.addEventListener("storage", storageHandler);
1917
- window.addEventListener("focus", rejectIfPopupClosed);
1918
- if ("BroadcastChannel" in window) {
1919
- broadcastChannel = new BroadcastChannel(OAUTH_COMPLETION_CHANNEL);
1920
- broadcastChannel.onmessage = (event) => complete(event.data);
1921
- }
1922
- const timeout = setTimeout(() => {
1923
- cleanup();
1924
- reject(new Error("timeout"));
1925
- }, OAUTH_FLOW_TIMEOUT);
1926
- const cleanup = () => {
1927
- clearTimeout(timeout);
1928
- broadcastChannel?.close();
1929
- window.removeEventListener("focus", rejectIfPopupClosed);
1930
- window.removeEventListener("storage", storageHandler);
1931
- window.removeEventListener("message", messageHandler);
1932
- };
1933
- });
1934
- };
1935
- return { authorize, isAuthorizing, error };
1936
- }
1937
- function parseOAuthCompletionPayload(data, startedAt) {
1938
- if (!data || typeof data !== "object") return null;
1939
- const payload = data;
1940
- if (payload.type !== "oauth-complete") return null;
1941
- if (payload.completedAt && payload.completedAt < startedAt) return null;
1942
- return payload;
1943
- }
1944
- function isTrustedCallbackOrigin(origin) {
1945
- if (origin === window.location.origin || origin === "https://app.elevasis.io") {
1946
- return true;
1947
- }
1948
- try {
1949
- const url = new URL(origin);
1950
- return url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
1951
- } catch {
1952
- return false;
1953
- }
1954
- }
1955
1751
  function EditCredentialModal({ apiUrl, credential, onClose }) {
1956
1752
  const [credentialName, setCredentialName] = useState("");
1957
1753
  const [nameError, setNameError] = useState(null);
@@ -2088,18 +1884,21 @@ function EditCredentialModal({ apiUrl, credential, onClose }) {
2088
1884
  ] }),
2089
1885
  !isOAuth && /* @__PURE__ */ jsxs(Fragment, { children: [
2090
1886
  /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Current values are encrypted and cannot be displayed. Enter new values below to replace them." }),
2091
- schema.fields?.map((field) => /* @__PURE__ */ jsx(
2092
- PasswordInput,
2093
- {
2094
- label: `New ${field.label}`,
2095
- placeholder: field.placeholder || `Enter new ${field.label.toLowerCase()}`,
2096
- value: fieldValues[field.key] || "",
2097
- onChange: (e) => handleFieldChange(field.key, e.target.value),
2098
- description: field.description,
2099
- disabled: isPending
2100
- },
2101
- field.key
2102
- )),
1887
+ schema.fields?.map((field) => {
1888
+ const Input = field.type === "text" ? TextInput : PasswordInput;
1889
+ return /* @__PURE__ */ jsx(
1890
+ Input,
1891
+ {
1892
+ label: `New ${field.label}`,
1893
+ placeholder: field.placeholder || `Enter new ${field.label.toLowerCase()}`,
1894
+ value: fieldValues[field.key] || "",
1895
+ onChange: (e) => handleFieldChange(field.key, e.target.value),
1896
+ description: field.description,
1897
+ disabled: isPending
1898
+ },
1899
+ field.key
1900
+ );
1901
+ }),
2103
1902
  updateMutation.error && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), color: "red", title: "Update Failed", children: "Failed to update credential" }),
2104
1903
  /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "sm", children: [
2105
1904
  /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, disabled: isPending, children: "Cancel" }),
@@ -2120,75 +1919,5 @@ function EditCredentialModal({ apiUrl, credential, onClose }) {
2120
1919
  ] })
2121
1920
  ] }) });
2122
1921
  }
2123
- var PROVIDER_ICONS = {
2124
- "google-sheets": IconBrandGoogleDrive,
2125
- dropbox: IconBrandDropbox
2126
- };
2127
- function OAuthIntegrationsCard({ apiUrl }) {
2128
- const [selectedProviderId, setSelectedProviderId] = useState(null);
2129
- const [modalOpened, setModalOpened] = useState(false);
2130
- const { authorize, isAuthorizing, error } = useOAuthFlow({ apiUrl });
2131
- const queryClient = useQueryClient();
2132
- const handleConnect = async (credentialName) => {
2133
- if (!selectedProviderId) return;
2134
- try {
2135
- await authorize(selectedProviderId, credentialName);
2136
- setModalOpened(false);
2137
- setSelectedProviderId(null);
2138
- queryClient.invalidateQueries({ queryKey: ["credentials"] });
2139
- } catch (err) {
2140
- console.error("OAuth flow failed:", err);
2141
- }
2142
- };
2143
- const handleOpenModal = (providerId) => {
2144
- setSelectedProviderId(providerId);
2145
- setModalOpened(true);
2146
- };
2147
- useEffect(() => {
2148
- const params = new URLSearchParams(window.location.search);
2149
- const requested = params.get("connect");
2150
- if (requested && OAUTH_PROVIDERS[requested]) {
2151
- handleOpenModal(requested);
2152
- params.delete("connect");
2153
- const remaining = params.toString();
2154
- const newUrl = window.location.pathname + (remaining ? `?${remaining}` : "") + window.location.hash;
2155
- window.history.replaceState({}, "", newUrl);
2156
- }
2157
- }, []);
2158
- const providers = Object.values(OAUTH_PROVIDERS);
2159
- const selectedProvider = selectedProviderId ? OAUTH_PROVIDERS[selectedProviderId] : null;
2160
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2161
- /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { children: [
2162
- /* @__PURE__ */ jsx(Group, { justify: "space-between", children: /* @__PURE__ */ jsxs("div", { children: [
2163
- /* @__PURE__ */ jsx(Title, { order: 3, children: "OAuth Integrations" }),
2164
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mt: 4, children: "Connect third-party services using OAuth 2.0" })
2165
- ] }) }),
2166
- /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2, md: 3 }, children: providers.map((provider) => {
2167
- const Icon = PROVIDER_ICONS[provider.id] || IconPlug;
2168
- return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { children: [
2169
- /* @__PURE__ */ jsx(Group, { justify: "space-between", align: "flex-start", children: /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
2170
- /* @__PURE__ */ jsx(ThemeIcon, { size: "lg", variant: "light", color: "blue", children: /* @__PURE__ */ jsx(Icon, { size: 20 }) }),
2171
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { fw: 600, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: provider.name }) })
2172
- ] }) }),
2173
- /* @__PURE__ */ jsx(Button, { variant: "filled", size: "sm", onClick: () => handleOpenModal(provider.id), fullWidth: true, children: "Connect" })
2174
- ] }) }, provider.id);
2175
- }) })
2176
- ] }) }),
2177
- /* @__PURE__ */ jsx(
2178
- OAuthConnectModal,
2179
- {
2180
- opened: modalOpened,
2181
- onClose: () => {
2182
- setModalOpened(false);
2183
- setSelectedProviderId(null);
2184
- },
2185
- provider: selectedProvider,
2186
- onConnect: handleConnect,
2187
- error,
2188
- isLoading: isAuthorizing
2189
- }
2190
- )
2191
- ] });
2192
- }
2193
1922
 
2194
- export { AccountSettings, AppearanceSettings, CreateCredentialModal, CreateWebhookEndpointModal, CredentialList, CredentialSettings, EditCredentialModal, EditWebhookEndpointModal, MemberAccessModal, MembershipStatusBadge, MyRolesPage, OAuthConnectModal, OAuthIntegrationsCard, OrgMembersList, OrganizationMembershipsList, OrganizationSettings, ProvisioningStateBadge, WebhookEndpointList, WebhookEndpointSettings, WebhookUrlDisplayModal, showAuthError };
1923
+ export { AccountSettings, AppearanceSettings, CREDENTIAL_SCHEMAS, CreateWebhookEndpointModal, EditCredentialModal, EditWebhookEndpointModal, MemberAccessModal, MembershipStatusBadge, MyRolesPage, OAuthConnectModal, OAuthIntegrationsCard, OrgMembersList, OrganizationMembershipsList, OrganizationSettings, ProvisioningStateBadge, WebhookEndpointList, WebhookEndpointSettings, WebhookUrlDisplayModal, buildCredentialValue, getCredentialSchema, showAuthError };