@elevasis/ui 1.26.1 → 1.27.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 (53) hide show
  1. package/dist/charts/index.js +2 -2
  2. package/dist/{chunk-AWT255UH.js → chunk-2IJCM3VQ.js} +37 -37
  3. package/dist/chunk-5COLSYBE.js +199 -0
  4. package/dist/{chunk-RMPXGBNI.js → chunk-5JSR6TL5.js} +2 -2
  5. package/dist/chunk-BAGYETKM.js +635 -0
  6. package/dist/{chunk-L3GVDMCA.js → chunk-C27LLJM6.js} +3 -195
  7. package/dist/{chunk-O4UB5DQQ.js → chunk-F2J7675J.js} +1 -1
  8. package/dist/chunk-ITCEULI5.js +238 -0
  9. package/dist/{chunk-4WKWLFBZ.js → chunk-P5EWG45B.js} +1 -1
  10. package/dist/{chunk-BS4J2LAW.js → chunk-QTD5HPKD.js} +1 -1
  11. package/dist/{chunk-ZVJKIJFG.js → chunk-RCQPWA5X.js} +13 -42
  12. package/dist/chunk-TLAIQC7B.js +6382 -0
  13. package/dist/{chunk-FEZZ3IDU.js → chunk-TXPUIHX2.js} +10 -10
  14. package/dist/{chunk-L4XXM55J.js → chunk-W4VYXIN7.js} +142 -3
  15. package/dist/chunk-WJ7W7JU4.js +2115 -0
  16. package/dist/{chunk-YNGQ7U5H.js → chunk-WLNEJ6JJ.js} +2 -2
  17. package/dist/{chunk-4INR75ZS.js → chunk-Y2SYGFRF.js} +589 -65
  18. package/dist/components/index.d.ts +333 -73
  19. package/dist/components/index.js +838 -686
  20. package/dist/features/auth/index.d.ts +125 -0
  21. package/dist/features/auth/index.js +2 -2
  22. package/dist/features/dashboard/index.d.ts +28 -2
  23. package/dist/features/dashboard/index.js +21 -635
  24. package/dist/features/monitoring/index.d.ts +28 -1
  25. package/dist/features/monitoring/index.js +19 -529
  26. package/dist/features/operations/index.d.ts +51 -8
  27. package/dist/features/operations/index.js +25 -3760
  28. package/dist/features/settings/index.d.ts +153 -1
  29. package/dist/features/settings/index.js +19 -1438
  30. package/dist/hooks/index.d.ts +262 -25
  31. package/dist/hooks/index.js +12 -8
  32. package/dist/hooks/published.d.ts +137 -25
  33. package/dist/hooks/published.js +11 -7
  34. package/dist/index.d.ts +310 -28
  35. package/dist/index.js +12 -11
  36. package/dist/initialization/index.d.ts +125 -0
  37. package/dist/layout/index.d.ts +2 -0
  38. package/dist/layout/index.js +6 -5
  39. package/dist/organization/index.js +1 -2
  40. package/dist/profile/index.d.ts +125 -0
  41. package/dist/provider/index.d.ts +48 -3
  42. package/dist/provider/index.js +10 -4
  43. package/dist/provider/published.d.ts +48 -3
  44. package/dist/provider/published.js +8 -2
  45. package/dist/supabase/index.d.ts +242 -0
  46. package/dist/theme/index.js +2 -2
  47. package/dist/types/index.d.ts +126 -1
  48. package/package.json +3 -3
  49. package/dist/chunk-LR4WVA7W.js +0 -682
  50. package/dist/chunk-R7WLWGPO.js +0 -126
  51. package/dist/chunk-TCKIAHDC.js +0 -2626
  52. package/dist/chunk-V7XHGJQZ.js +0 -145
  53. package/dist/{chunk-WWEMNIHW.js → chunk-YYBM5LNJ.js} +1 -1
@@ -1,682 +0,0 @@
1
- import { FilterBar } from './chunk-PDHTXPSF.js';
2
- import { CustomModal } from './chunk-GBMNCNHX.js';
3
- import { ListSkeleton, EmptyState, PageTitleCaption, CardHeader, APIErrorAlert } from './chunk-MCA6LOGM.js';
4
- import { AppShellLoader } from './chunk-WWEMNIHW.js';
5
- import { useDeleteCredential, useCreateCredential, useCredentials, MEMBERSHIP_STATUS_COLORS, transformMembershipToTableRow, CredentialSchemas } from './chunk-YNGQ7U5H.js';
6
- import { formatDateTime } from './chunk-IOKL7BKE.js';
7
- import { useInitialization } from './chunk-TUXTSEAF.js';
8
- import { useState, useEffect } from 'react';
9
- import { Table, Group, Text, Tooltip, ActionIcon, Stack, Title, Button, Select, TextInput, Alert, PasswordInput, Anchor, Paper, Card, Switch, Badge, Center, Loader, Box, Code, CopyButton } from '@mantine/core';
10
- import { IconKey, IconCalendar, IconPencil, IconTrash, IconAlertTriangle, IconInfoCircle, IconExclamationMark, IconPlus, IconAlertCircle, IconUsers, IconSearch, IconBuilding, IconEdit, IconUserX, IconUserCheck, IconWebhook, IconCheck, IconCopy } from '@tabler/icons-react';
11
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
12
- import { useForm } from '@mantine/form';
13
- import { z } from 'zod';
14
-
15
- function CredentialList({ credentials, isLoading, onEdit }) {
16
- const [deleteCredential, setDeleteCredential] = useState(null);
17
- const deleteMutation = useDeleteCredential();
18
- const handleDelete = () => {
19
- if (deleteCredential) {
20
- deleteMutation.mutate(deleteCredential.id);
21
- setDeleteCredential(null);
22
- }
23
- };
24
- const handleCloseDelete = () => {
25
- if (!deleteMutation.isPending) {
26
- setDeleteCredential(null);
27
- }
28
- };
29
- if (isLoading) {
30
- return /* @__PURE__ */ jsx(ListSkeleton, { rows: 3, rowHeight: 60 });
31
- }
32
- if (credentials.length === 0) {
33
- return /* @__PURE__ */ jsx(
34
- EmptyState,
35
- {
36
- icon: IconKey,
37
- title: "No credentials yet",
38
- description: "Create your first credential to enable external service integrations"
39
- }
40
- );
41
- }
42
- return /* @__PURE__ */ jsxs(Fragment, { children: [
43
- /* @__PURE__ */ jsxs(Table, { children: [
44
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
45
- /* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
46
- /* @__PURE__ */ jsx(Table.Th, { children: "Created" }),
47
- /* @__PURE__ */ jsx(Table.Th, { w: 100 })
48
- ] }) }),
49
- /* @__PURE__ */ jsx(Table.Tbody, { children: credentials.map((credential) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
50
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
51
- /* @__PURE__ */ jsx(IconKey, { size: 16, style: { opacity: 0.6 } }),
52
- /* @__PURE__ */ jsx(Text, { fw: 500, children: credential.name })
53
- ] }) }),
54
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
55
- /* @__PURE__ */ jsx(IconCalendar, { size: 14, style: { opacity: 0.5 } }),
56
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: formatDateTime(credential.createdAt) })
57
- ] }) }),
58
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", children: [
59
- onEdit && /* @__PURE__ */ jsx(Tooltip, { label: "Edit credential", children: /* @__PURE__ */ jsx(
60
- ActionIcon,
61
- {
62
- variant: "subtle",
63
- color: "gray",
64
- onClick: () => onEdit(credential),
65
- disabled: deleteMutation.isPending,
66
- children: /* @__PURE__ */ jsx(IconPencil, { size: 16 })
67
- }
68
- ) }),
69
- /* @__PURE__ */ jsx(Tooltip, { label: "Delete credential", position: "left", children: /* @__PURE__ */ jsx(
70
- ActionIcon,
71
- {
72
- variant: "subtle",
73
- color: "red",
74
- onClick: () => setDeleteCredential(credential),
75
- disabled: deleteMutation.isPending,
76
- children: /* @__PURE__ */ jsx(IconTrash, { size: 16 })
77
- }
78
- ) })
79
- ] }) })
80
- ] }, credential.id)) })
81
- ] }),
82
- /* @__PURE__ */ jsx(CustomModal, { opened: !!deleteCredential, onClose: handleCloseDelete, size: "md", loading: deleteMutation.isPending, children: /* @__PURE__ */ jsxs(Stack, { children: [
83
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
84
- /* @__PURE__ */ jsx(IconAlertTriangle, { size: 24, color: "var(--color-error)" }),
85
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Delete Credential" })
86
- ] }),
87
- /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
88
- "Are you sure you want to delete",
89
- " ",
90
- /* @__PURE__ */ jsxs(Text, { span: true, fw: 600, children: [
91
- '"',
92
- deleteCredential?.name,
93
- '"'
94
- ] }),
95
- "?"
96
- ] }),
97
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "This action cannot be undone. Any agents or tools using this credential will stop working immediately." }),
98
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "sm", children: [
99
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleCloseDelete, disabled: deleteMutation.isPending, children: "Cancel" }),
100
- /* @__PURE__ */ jsx(
101
- Button,
102
- {
103
- color: "red",
104
- onClick: handleDelete,
105
- loading: deleteMutation.isPending,
106
- leftSection: /* @__PURE__ */ jsx(IconTrash, { size: 16 }),
107
- children: "Delete Credential"
108
- }
109
- )
110
- ] })
111
- ] }) })
112
- ] });
113
- }
114
- var CredentialFieldSchema = z.object({
115
- key: z.string(),
116
- label: z.string(),
117
- type: z.enum(["password", "text"]),
118
- required: z.boolean(),
119
- placeholder: z.string().optional(),
120
- description: z.string().optional()
121
- });
122
- var CredentialSchemaZod = z.object({
123
- type: z.string(),
124
- label: z.string(),
125
- description: z.string(),
126
- fields: z.array(CredentialFieldSchema).optional(),
127
- docsUrl: z.string().url().optional(),
128
- nameSuggestions: z.array(z.string()),
129
- oauthProvider: z.string().optional()
130
- });
131
- var CREDENTIAL_SCHEMAS = {
132
- "google-sheets": {
133
- type: "oauth",
134
- label: "Google Sheets",
135
- description: "Google Sheets OAuth integration",
136
- oauthProvider: "google-sheets",
137
- nameSuggestions: ["google-sheets-prod", "google-sheets-dev", "sheets-workspace"]
138
- },
139
- dropbox: {
140
- type: "oauth",
141
- label: "Dropbox",
142
- description: "Dropbox OAuth integration",
143
- oauthProvider: "dropbox",
144
- nameSuggestions: ["dropbox-prod", "dropbox-dev", "elevasis-dropbox"]
145
- },
146
- oauth: {
147
- type: "oauth",
148
- label: "OAuth",
149
- description: "Generic OAuth credential",
150
- nameSuggestions: []
151
- },
152
- "api-key": {
153
- type: "single_field",
154
- label: "API Key",
155
- description: "Single-field API key credential",
156
- fields: [
157
- {
158
- key: "apiKey",
159
- label: "API Key",
160
- type: "password",
161
- required: true,
162
- placeholder: "Enter your API key",
163
- description: "API key for the service"
164
- }
165
- ],
166
- nameSuggestions: ["service-prod", "service-dev", "api-key"]
167
- },
168
- "webhook-secret": {
169
- type: "single_field",
170
- label: "Webhook Secret",
171
- description: "Webhook signing secret for signature validation",
172
- fields: [
173
- {
174
- key: "signingSecret",
175
- label: "Signing Secret",
176
- type: "password",
177
- required: true,
178
- placeholder: "whsec_...",
179
- description: "Webhook signing secret from provider dashboard"
180
- }
181
- ],
182
- nameSuggestions: ["my-org-cal-com-webhook", "my-org-stripe-webhook", "my-org-signature-api-webhook"]
183
- },
184
- "api-key-secret": {
185
- type: "api-key-secret",
186
- label: "API Key + Secret",
187
- description: "API key and secret pair authentication",
188
- fields: [
189
- {
190
- key: "apiKey",
191
- label: "API Key",
192
- type: "password",
193
- required: true
194
- },
195
- {
196
- key: "apiSecret",
197
- label: "API Secret",
198
- type: "password",
199
- required: true
200
- }
201
- ],
202
- nameSuggestions: []
203
- }
204
- };
205
- function getCredentialSchema(type) {
206
- const schema = CREDENTIAL_SCHEMAS[type] || CREDENTIAL_SCHEMAS["api-key"];
207
- return CredentialSchemaZod.parse(schema);
208
- }
209
-
210
- // ../core/src/integrations/credentials/utils.ts
211
- function buildCredentialValue(type, formValues) {
212
- const schema = getCredentialSchema(type);
213
- if (schema.type === "oauth") {
214
- throw new Error(`buildCredentialValue should not be used for OAuth type: ${type}`);
215
- }
216
- const value = {};
217
- if (schema.fields) {
218
- for (const field of schema.fields) {
219
- const fieldValue = formValues[field.key];
220
- if (fieldValue !== void 0 && fieldValue !== null) {
221
- value[field.key] = fieldValue.trim();
222
- }
223
- }
224
- }
225
- return value;
226
- }
227
- function CreateCredentialModal({ opened, onClose, onSuccess }) {
228
- const createCredential = useCreateCredential();
229
- const [selectedType, setSelectedType] = useState("api-key");
230
- const [schema, setSchema] = useState(getCredentialSchema("api-key"));
231
- useEffect(() => {
232
- setSchema(getCredentialSchema(selectedType));
233
- }, [selectedType]);
234
- const getInitialValues = (currentSchema) => {
235
- const values = { name: "" };
236
- if (currentSchema.fields) {
237
- currentSchema.fields.forEach((field) => {
238
- values[field.key] = "";
239
- });
240
- }
241
- return values;
242
- };
243
- const getValidation = (currentSchema) => {
244
- const validation = {
245
- name: (value) => {
246
- const result = CredentialSchemas.CreateRequest.shape.name.safeParse(value);
247
- return result.success ? null : result.error.issues[0]?.message || "Invalid credential name";
248
- }
249
- };
250
- if (currentSchema.fields) {
251
- currentSchema.fields.forEach((field) => {
252
- if (field.required) {
253
- validation[field.key] = (value) => !value.trim() ? `${field.label} is required` : null;
254
- }
255
- });
256
- }
257
- return validation;
258
- };
259
- const form = useForm({
260
- initialValues: getInitialValues(schema),
261
- validate: getValidation(schema)
262
- });
263
- useEffect(() => {
264
- const newValues = getInitialValues(schema);
265
- form.setValues(newValues);
266
- form.setFieldValue("name", form.values.name || "");
267
- form.resetDirty();
268
- }, [selectedType]);
269
- const handleSubmit = async (values) => {
270
- if (schema.type === "oauth") {
271
- console.error("OAuth credentials cannot be created via this modal");
272
- return;
273
- }
274
- const data = {
275
- name: values.name.trim(),
276
- type: selectedType,
277
- value: buildCredentialValue(selectedType, values)
278
- };
279
- const validationResult = CredentialSchemas.CreateRequest.safeParse(data);
280
- if (!validationResult.success) {
281
- console.error("Validation failed:", validationResult.error);
282
- return;
283
- }
284
- try {
285
- const result = await createCredential.mutateAsync(data);
286
- form.reset();
287
- setSelectedType("api-key");
288
- onSuccess(result);
289
- } catch (error) {
290
- console.error("Failed to create credential:", error);
291
- }
292
- };
293
- const handleClose = () => {
294
- if (!createCredential.isPending) {
295
- form.reset();
296
- setSelectedType("api-key");
297
- onClose();
298
- }
299
- };
300
- 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: [
301
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Create New Credential" }),
302
- /* @__PURE__ */ jsx(
303
- Select,
304
- {
305
- label: "Credential Type",
306
- description: "Select the integration type",
307
- placeholder: "Select credential type",
308
- data: Object.entries(CREDENTIAL_SCHEMAS).filter(([_, s]) => s.type !== "oauth").map(([key, s]) => ({ value: key, label: s.label })),
309
- value: selectedType,
310
- onChange: (value) => setSelectedType(value || "api-key"),
311
- required: true,
312
- disabled: createCredential.isPending
313
- }
314
- ),
315
- /* @__PURE__ */ jsx(
316
- TextInput,
317
- {
318
- label: "Credential Name",
319
- description: schema.nameSuggestions.length > 0 ? `Suggested: ${schema.nameSuggestions.join(", ")}` : "Lowercase letters, numbers, and hyphens only (e.g., service-dev, service-prod)",
320
- placeholder: schema.nameSuggestions[0] || "e.g., service-prod",
321
- leftSection: /* @__PURE__ */ jsx(IconKey, { size: 16 }),
322
- maxLength: 100,
323
- required: true,
324
- ...form.getInputProps("name"),
325
- disabled: createCredential.isPending
326
- }
327
- ),
328
- schema.type === "oauth" ? /* @__PURE__ */ jsxs(Alert, { icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: 16 }), color: "blue", children: [
329
- schema.label,
330
- " uses OAuth authentication. Please go to the OAuth Integrations page to connect your",
331
- " ",
332
- schema.label,
333
- " account."
334
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
335
- schema.fields?.map((field) => /* @__PURE__ */ jsx(
336
- PasswordInput,
337
- {
338
- label: field.label,
339
- description: field.description,
340
- placeholder: field.placeholder,
341
- required: field.required,
342
- value: form.values[field.key] || "",
343
- onChange: (e) => form.setFieldValue(field.key, e.target.value),
344
- error: form.errors[field.key],
345
- disabled: createCredential.isPending
346
- },
347
- field.key
348
- )),
349
- schema.docsUrl && /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
350
- "Get credentials from",
351
- " ",
352
- /* @__PURE__ */ jsx(Anchor, { href: schema.docsUrl, target: "_blank", rel: "noopener noreferrer", children: schema.docsUrl })
353
- ] })
354
- ] }),
355
- 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" }),
356
- /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "sm", children: [
357
- /* @__PURE__ */ jsx(Button, { variant: "subtle", onClick: handleClose, disabled: createCredential.isPending, children: "Cancel" }),
358
- /* @__PURE__ */ jsx(Button, { type: "submit", loading: createCredential.isPending, leftSection: /* @__PURE__ */ jsx(IconKey, { size: 16 }), children: "Create Credential" })
359
- ] })
360
- ] }) }) });
361
- }
362
- function CredentialSettings({ oauthSection }) {
363
- const { organizationReady } = useInitialization();
364
- const [showCreateModal, setShowCreateModal] = useState(false);
365
- const { data: credentials = [], isLoading } = useCredentials();
366
- if (!organizationReady) return /* @__PURE__ */ jsx(AppShellLoader, {});
367
- const handleCredentialCreated = (result) => {
368
- console.log("Credential created:", result);
369
- setShowCreateModal(false);
370
- };
371
- return /* @__PURE__ */ jsxs(Fragment, { children: [
372
- /* @__PURE__ */ jsx(
373
- PageTitleCaption,
374
- {
375
- title: "Organization Credentials",
376
- caption: "Manage encrypted credentials for third-party service integrations"
377
- }
378
- ),
379
- oauthSection,
380
- /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
381
- /* @__PURE__ */ jsx(
382
- CardHeader,
383
- {
384
- icon: /* @__PURE__ */ jsx(IconKey, { size: 18 }),
385
- title: "Credentials",
386
- subtitle: "Configured API keys and credentials",
387
- rightSection: /* @__PURE__ */ jsx(Button, { leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 16 }), onClick: () => setShowCreateModal(true), variant: "light", children: "Create Credential" })
388
- }
389
- ),
390
- /* @__PURE__ */ jsx(CredentialList, { credentials, isLoading })
391
- ] }),
392
- /* @__PURE__ */ jsx(
393
- CreateCredentialModal,
394
- {
395
- opened: showCreateModal,
396
- onClose: () => setShowCreateModal(false),
397
- onSuccess: handleCredentialCreated
398
- }
399
- )
400
- ] });
401
- }
402
- function OAuthConnectModal({ opened, onClose, provider, onConnect, error, isLoading }) {
403
- const [credentialName, setCredentialName] = useState("");
404
- useEffect(() => {
405
- if (opened && provider) {
406
- setCredentialName(`${provider.id}-prod`);
407
- }
408
- }, [opened, provider]);
409
- useEffect(() => {
410
- if (!opened) {
411
- setCredentialName("");
412
- }
413
- }, [opened]);
414
- const handleConnect = async () => {
415
- if (!credentialName.trim() || !provider) return;
416
- await onConnect(credentialName);
417
- };
418
- const handleClose = () => {
419
- if (!isLoading) {
420
- onClose();
421
- }
422
- };
423
- return /* @__PURE__ */ jsx(CustomModal, { opened: opened && !!provider, onClose: handleClose, size: "md", loading: isLoading, children: provider && /* @__PURE__ */ jsxs(Stack, { children: [
424
- /* @__PURE__ */ jsxs(Title, { order: 3, children: [
425
- "Connect ",
426
- provider.name
427
- ] }),
428
- /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
429
- "Authorize Elevasis to access your ",
430
- provider.name,
431
- " account"
432
- ] }),
433
- provider.scopes && provider.scopes.length > 0 && /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
434
- "Permissions requested: ",
435
- provider.scopes.join(", ")
436
- ] }),
437
- error && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), color: "red", title: "Connection Failed", children: error }),
438
- /* @__PURE__ */ jsx(
439
- TextInput,
440
- {
441
- label: "Credential Name",
442
- placeholder: `${provider.id}-prod`,
443
- value: credentialName,
444
- onChange: (e) => setCredentialName(e.target.value),
445
- required: true,
446
- disabled: isLoading,
447
- description: "Use naming convention to indicate environment (e.g., notion-dev, slack-prod)"
448
- }
449
- ),
450
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mt: "md", children: [
451
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, disabled: isLoading, children: "Cancel" }),
452
- /* @__PURE__ */ jsxs(Button, { onClick: handleConnect, loading: isLoading, disabled: !credentialName.trim(), children: [
453
- "Connect ",
454
- provider.name
455
- ] })
456
- ] })
457
- ] }) });
458
- }
459
- var FEATURES = [
460
- { key: "acquisition", label: "Acquisition" },
461
- { key: "calibration", label: "Calibration" },
462
- { key: "seo", label: "SEO" }
463
- ];
464
- function MembershipFeaturePanel({
465
- currentConfig,
466
- onConfigChange,
467
- disabled = false
468
- }) {
469
- const handleFeatureToggle = (featureKey, enabled) => {
470
- const newConfig = {
471
- ...currentConfig,
472
- features: {
473
- ...currentConfig?.features,
474
- [featureKey]: enabled
475
- }
476
- };
477
- onConfigChange(newConfig);
478
- };
479
- return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
480
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Toggle features this member can access." }),
481
- FEATURES.map(({ key, label }) => {
482
- const isEnabled = currentConfig?.features?.[key] !== false;
483
- return /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
484
- /* @__PURE__ */ jsx(Text, { size: "sm", children: label }),
485
- /* @__PURE__ */ jsx(
486
- Switch,
487
- {
488
- checked: isEnabled,
489
- onChange: (e) => handleFeatureToggle(key, e.currentTarget.checked),
490
- disabled,
491
- size: "md"
492
- }
493
- )
494
- ] }, key);
495
- })
496
- ] }) });
497
- }
498
- function MembershipStatusBadge({ status, size = "sm", variant = "light" }) {
499
- const getStatusLabel = (status2) => {
500
- switch (status2) {
501
- case "active":
502
- return "Active";
503
- case "inactive":
504
- return "Inactive";
505
- default:
506
- return status2;
507
- }
508
- };
509
- return /* @__PURE__ */ jsx(Badge, { color: MEMBERSHIP_STATUS_COLORS[status], size, variant, children: getStatusLabel(status) });
510
- }
511
- function OrganizationMembershipsList({
512
- memberships,
513
- loading,
514
- error,
515
- onEditRole,
516
- onLeaveOrganization
517
- }) {
518
- const [searchTerm, setSearchTerm] = useState("");
519
- const [statusFilter, setStatusFilter] = useState("");
520
- const tableRows = memberships?.map(transformMembershipToTableRow) || [];
521
- const filteredRows = tableRows.filter((row) => {
522
- const matchesSearch = row.organizationName.toLowerCase().includes(searchTerm.toLowerCase()) || row.role.toLowerCase().includes(searchTerm.toLowerCase());
523
- const matchesStatus = !statusFilter || row.status === statusFilter;
524
- return matchesSearch && matchesStatus;
525
- });
526
- if (error) {
527
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(APIErrorAlert, { error, title: "Failed to load memberships" }) });
528
- }
529
- return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
530
- /* @__PURE__ */ jsx(
531
- CardHeader,
532
- {
533
- icon: /* @__PURE__ */ jsx(IconUsers, { size: 18 }),
534
- title: `Your Organizations (${loading ? "..." : filteredRows.length})`,
535
- subtitle: loading ? "Loading memberships..." : `Showing ${filteredRows.length} ${filteredRows.length === 1 ? "membership" : "memberships"}`
536
- }
537
- ),
538
- /* @__PURE__ */ jsxs(Stack, { children: [
539
- /* @__PURE__ */ jsxs(FilterBar, { children: [
540
- /* @__PURE__ */ jsx(
541
- TextInput,
542
- {
543
- placeholder: "Search organizations or roles...",
544
- leftSection: /* @__PURE__ */ jsx(IconSearch, { size: 16 }),
545
- value: searchTerm,
546
- onChange: (event) => setSearchTerm(event.currentTarget.value),
547
- style: { flex: 1 },
548
- disabled: loading
549
- }
550
- ),
551
- /* @__PURE__ */ jsx(
552
- Select,
553
- {
554
- placeholder: "Filter by status",
555
- value: statusFilter,
556
- onChange: (value) => setStatusFilter(value),
557
- data: [
558
- { value: "", label: "All Statuses" },
559
- { value: "active", label: "Active" },
560
- { value: "inactive", label: "Inactive" }
561
- ],
562
- style: { minWidth: 150 },
563
- clearable: true,
564
- disabled: loading
565
- }
566
- )
567
- ] }),
568
- /* @__PURE__ */ jsx(Table.ScrollContainer, { minWidth: 700, children: /* @__PURE__ */ jsxs(Table, { children: [
569
- /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
570
- /* @__PURE__ */ jsx(Table.Th, { children: "Organization" }),
571
- /* @__PURE__ */ jsx(Table.Th, { children: "Role" }),
572
- /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
573
- /* @__PURE__ */ jsx(Table.Th, { children: "Joined" }),
574
- /* @__PURE__ */ jsx(Table.Th, { align: "right", children: "Actions" })
575
- ] }) }),
576
- /* @__PURE__ */ jsx(Table.Tbody, { children: loading ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: 5, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) }) }) : filteredRows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: 5, children: /* @__PURE__ */ jsx(
577
- EmptyState,
578
- {
579
- icon: IconBuilding,
580
- title: "No memberships found",
581
- description: searchTerm || statusFilter ? "Try adjusting your search or filter criteria" : "You are not a member of any organizations yet"
582
- }
583
- ) }) }) : filteredRows.map((row) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
584
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
585
- /* @__PURE__ */ jsx(IconBuilding, { size: 16 }),
586
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", children: row.organizationName }) })
587
- ] }) }),
588
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { variant: "light", color: "blue", size: "sm", children: row.role }) }),
589
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(MembershipStatusBadge, { status: row.status }) }),
590
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: row.joinedAt.toLocaleDateString() }) }),
591
- /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
592
- row.canEdit && onEditRole && /* @__PURE__ */ jsx(
593
- ActionIcon,
594
- {
595
- variant: "subtle",
596
- size: "sm",
597
- color: "blue",
598
- onClick: () => onEditRole(row.id),
599
- disabled: row.status !== "active",
600
- children: /* @__PURE__ */ jsx(IconEdit, { size: 16 })
601
- }
602
- ),
603
- row.canRemove && onLeaveOrganization && row.status === "active" && /* @__PURE__ */ jsx(
604
- ActionIcon,
605
- {
606
- variant: "subtle",
607
- size: "sm",
608
- color: "red",
609
- onClick: () => onLeaveOrganization(row.id),
610
- children: /* @__PURE__ */ jsx(IconUserX, { size: 16 })
611
- }
612
- ),
613
- row.status === "inactive" && /* @__PURE__ */ jsx(
614
- ActionIcon,
615
- {
616
- variant: "subtle",
617
- size: "sm",
618
- color: "green",
619
- disabled: true,
620
- title: "Contact admin to reactivate",
621
- children: /* @__PURE__ */ jsx(IconUserCheck, { size: 16 })
622
- }
623
- )
624
- ] }) })
625
- ] }, row.id)) })
626
- ] }) })
627
- ] })
628
- ] });
629
- }
630
- function WebhookUrlDisplayModal({ opened, endpoint, webhookUrl, onClose }) {
631
- return /* @__PURE__ */ jsx(CustomModal, { opened, onClose, size: "lg", loading: false, children: /* @__PURE__ */ jsxs(Stack, { children: [
632
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
633
- /* @__PURE__ */ jsx(IconWebhook, { size: 24, color: "var(--color-success)" }),
634
- /* @__PURE__ */ jsx(Title, { order: 3, children: "Webhook Endpoint Created" })
635
- ] }),
636
- /* @__PURE__ */ jsxs(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, {}), color: "yellow", variant: "light", children: [
637
- /* @__PURE__ */ jsx(Text, { fw: 600, size: "sm", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Save this URL \u2014 it contains your secret key." }),
638
- /* @__PURE__ */ jsx(Text, { size: "sm", mt: 4, children: "The URL includes a unique key that acts as the credential for this endpoint. Treat it like a password. You can always copy it again from the Webhooks settings page." })
639
- ] }),
640
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
641
- /* @__PURE__ */ jsxs(Text, { size: "sm", fw: 500, children: [
642
- "Webhook URL for ",
643
- /* @__PURE__ */ jsx("strong", { children: endpoint.name }),
644
- ":"
645
- ] }),
646
- /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
647
- /* @__PURE__ */ jsx(IconWebhook, { size: 16, style: { opacity: 0.6, flexShrink: 0 } }),
648
- /* @__PURE__ */ jsx(
649
- Code,
650
- {
651
- block: true,
652
- style: {
653
- fontSize: "13px",
654
- wordBreak: "break-all",
655
- backgroundColor: "transparent",
656
- padding: 0,
657
- flex: 1
658
- },
659
- children: webhookUrl
660
- }
661
- ),
662
- /* @__PURE__ */ jsx(CopyButton, { value: webhookUrl, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
663
- ActionIcon,
664
- {
665
- color: copied ? "teal" : "gray",
666
- variant: copied ? "filled" : "subtle",
667
- onClick: copy,
668
- size: "lg",
669
- children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 18 }) : /* @__PURE__ */ jsx(IconCopy, { size: 18 })
670
- }
671
- ) })
672
- ] }) })
673
- ] }),
674
- endpoint.resourceId && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
675
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Target resource:" }),
676
- /* @__PURE__ */ jsx(Code, { block: true, style: { fontSize: "13px", backgroundColor: "transparent", padding: "8px" }, children: endpoint.resourceId })
677
- ] }),
678
- /* @__PURE__ */ jsx(Group, { justify: "right", children: /* @__PURE__ */ jsx(Button, { onClick: onClose, size: "sm", leftSection: /* @__PURE__ */ jsx(IconCheck, { size: 16 }), children: "Done" }) })
679
- ] }) });
680
- }
681
-
682
- export { CreateCredentialModal, CredentialList, CredentialSettings, MembershipFeaturePanel, MembershipStatusBadge, OAuthConnectModal, OrganizationMembershipsList, WebhookUrlDisplayModal, buildCredentialValue, getCredentialSchema };