@solidxai/core-ui 0.1.7-beta.6 → 0.1.7-beta.8

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 (119) hide show
  1. package/dist/adapters/auth/helper.d.ts +9 -0
  2. package/dist/adapters/auth/helper.d.ts.map +1 -0
  3. package/dist/adapters/auth/helper.js +37 -0
  4. package/dist/adapters/auth/helper.js.map +1 -0
  5. package/dist/adapters/auth/helper.ts +45 -0
  6. package/dist/adapters/auth/signInWithOtp.d.ts.map +1 -1
  7. package/dist/adapters/auth/signInWithOtp.js +3 -27
  8. package/dist/adapters/auth/signInWithOtp.js.map +1 -1
  9. package/dist/adapters/auth/signInWithOtp.ts +3 -23
  10. package/dist/components/auth/SolidOTPVerify.d.ts +3 -0
  11. package/dist/components/auth/SolidOTPVerify.d.ts.map +1 -0
  12. package/dist/components/auth/SolidOTPVerify.js +67 -0
  13. package/dist/components/auth/SolidOTPVerify.js.map +1 -0
  14. package/dist/components/auth/SolidOTPVerify.tsx +133 -0
  15. package/dist/components/common/AuthBanner.js.map +1 -1
  16. package/dist/components/core/common/LoadDynamicJsxComponent.d.ts +2 -0
  17. package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +1 -0
  18. package/dist/components/core/common/LoadDynamicJsxComponent.js +50 -0
  19. package/dist/components/core/common/LoadDynamicJsxComponent.js.map +1 -0
  20. package/dist/components/core/common/LoadDynamicJsxComponent.tsx +70 -0
  21. package/dist/components/core/kanban/SolidManyToOneFilterElement.d.ts.map +1 -1
  22. package/dist/components/core/kanban/SolidManyToOneFilterElement.js.map +1 -1
  23. package/dist/components/core/kanban/SolidManyToOneFilterElement.tsx +2 -1
  24. package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.d.ts.map +1 -1
  25. package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js +2 -2
  26. package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js.map +1 -1
  27. package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.tsx +10 -21
  28. package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.d.ts.map +1 -1
  29. package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js +2 -2
  30. package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js.map +1 -1
  31. package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.tsx +10 -18
  32. package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.d.ts.map +1 -1
  33. package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js +6 -3
  34. package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js.map +1 -1
  35. package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.tsx +24 -30
  36. package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.js.map +1 -1
  37. package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.tsx +2 -2
  38. package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts +1 -1
  39. package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts.map +1 -1
  40. package/dist/components/core/list/SolidListViewRowButtonContextMenu.js +7 -6
  41. package/dist/components/core/list/SolidListViewRowButtonContextMenu.js.map +1 -1
  42. package/dist/components/core/list/SolidListViewRowButtonContextMenu.tsx +10 -9
  43. package/dist/components/core/users/ApiKeysTab/ApiKeysTab.d.ts +7 -0
  44. package/dist/components/core/users/ApiKeysTab/ApiKeysTab.d.ts.map +1 -0
  45. package/dist/components/core/users/ApiKeysTab/ApiKeysTab.js +138 -0
  46. package/dist/components/core/users/ApiKeysTab/ApiKeysTab.js.map +1 -0
  47. package/dist/components/core/users/ApiKeysTab/ApiKeysTab.tsx +246 -0
  48. package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.d.ts +8 -0
  49. package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.d.ts.map +1 -0
  50. package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.js +156 -0
  51. package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.js.map +1 -0
  52. package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.tsx +184 -0
  53. package/dist/components/core/users/ApiKeysTab/RevealApiKeyModal.d.ts +9 -0
  54. package/dist/components/core/users/ApiKeysTab/RevealApiKeyModal.d.ts.map +1 -0
  55. package/dist/components/core/users/ApiKeysTab/RevealApiKeyModal.js +37 -0
  56. package/dist/components/core/users/ApiKeysTab/RevealApiKeyModal.js.map +1 -0
  57. package/dist/components/core/users/ApiKeysTab/RevealApiKeyModal.tsx +111 -0
  58. package/dist/components/core/users/ApiKeysTab/index.d.ts +4 -0
  59. package/dist/components/core/users/ApiKeysTab/index.d.ts.map +1 -0
  60. package/dist/components/core/users/ApiKeysTab/index.js +4 -0
  61. package/dist/components/core/users/ApiKeysTab/index.js.map +1 -0
  62. package/dist/components/core/users/ApiKeysTab/index.ts +3 -0
  63. package/dist/helpers/# no such endpoints exist, need to calle +3 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +1 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/index.ts +1 -0
  69. package/dist/nextAuth/authProviders.d.ts +4 -0
  70. package/dist/nextAuth/authProviders.d.ts.map +1 -0
  71. package/dist/nextAuth/authProviders.js +198 -0
  72. package/dist/nextAuth/authProviders.js.map +1 -0
  73. package/dist/nextAuth/authProviders.tsx +232 -0
  74. package/dist/nextAuth/handleLogout.d.ts +2 -0
  75. package/dist/nextAuth/handleLogout.d.ts.map +1 -0
  76. package/dist/nextAuth/handleLogout.js +36 -0
  77. package/dist/nextAuth/handleLogout.js.map +1 -0
  78. package/dist/nextAuth/handleLogout.tsx +39 -0
  79. package/dist/nextAuth/refreshAccessToken.d.ts +2 -0
  80. package/dist/nextAuth/refreshAccessToken.d.ts.map +1 -0
  81. package/dist/nextAuth/refreshAccessToken.js +24 -0
  82. package/dist/nextAuth/refreshAccessToken.js.map +1 -0
  83. package/dist/nextAuth/refreshAccessToken.tsx +28 -0
  84. package/dist/redux/api/apiKeyApi.d.ts +40 -0
  85. package/dist/redux/api/apiKeyApi.d.ts.map +1 -0
  86. package/dist/redux/api/apiKeyApi.js +36 -0
  87. package/dist/redux/api/apiKeyApi.js.map +1 -0
  88. package/dist/redux/api/apiKeyApi.ts +60 -0
  89. package/dist/redux/features/settingsSlice.d.ts +20 -0
  90. package/dist/redux/features/settingsSlice.d.ts.map +1 -0
  91. package/dist/redux/features/settingsSlice.js +39 -0
  92. package/dist/redux/features/settingsSlice.js.map +1 -0
  93. package/dist/redux/features/settingsSlice.ts +60 -0
  94. package/dist/routes/guards/AuthGuard.d.ts +5 -1
  95. package/dist/routes/guards/AuthGuard.d.ts.map +1 -1
  96. package/dist/routes/guards/AuthGuard.js +13 -2
  97. package/dist/routes/guards/AuthGuard.js.map +1 -1
  98. package/dist/routes/guards/AuthGuard.tsx +27 -3
  99. package/package.json +1 -1
  100. package/dist/components/core/list/SolidDataTablePagination.d.ts +0 -15
  101. package/dist/components/core/list/SolidDataTablePagination.d.ts.map +0 -1
  102. package/dist/components/core/list/SolidDataTablePagination.js +0 -22
  103. package/dist/components/core/list/SolidDataTablePagination.js.map +0 -1
  104. package/dist/components/core/list/SolidDataTablePagination.tsx +0 -71
  105. package/dist/components/solid-ui/SolidButton.d.ts +0 -14
  106. package/dist/components/solid-ui/SolidButton.d.ts.map +0 -1
  107. package/dist/components/solid-ui/SolidButton.js +0 -36
  108. package/dist/components/solid-ui/SolidButton.js.map +0 -1
  109. package/dist/components/solid-ui/SolidButton.tsx +0 -54
  110. package/dist/components/solid-ui/SolidTabs.d.ts +0 -18
  111. package/dist/components/solid-ui/SolidTabs.d.ts.map +0 -1
  112. package/dist/components/solid-ui/SolidTabs.js +0 -22
  113. package/dist/components/solid-ui/SolidTabs.js.map +0 -1
  114. package/dist/components/solid-ui/SolidTabs.tsx +0 -73
  115. package/dist/components/solid-ui/index.d.ts +0 -3
  116. package/dist/components/solid-ui/index.d.ts.map +0 -1
  117. package/dist/components/solid-ui/index.js +0 -3
  118. package/dist/components/solid-ui/index.js.map +0 -1
  119. package/dist/components/solid-ui/index.ts +0 -2
@@ -0,0 +1,156 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
49
+ import { useEffect, useState } from "react";
50
+ import { useDispatch } from "react-redux";
51
+ import { useFormik } from "formik";
52
+ import * as Yup from "yup";
53
+ import { SolidButton, SolidDatePicker, SolidDialog, SolidDialogBody, SolidDialogFooter, SolidDialogHeader, SolidDialogSeparator, SolidDialogTitle, SolidInput, SolidMessage, SolidSelect, } from "../../../shad-cn-ui";
54
+ import { showToast } from "../../../../redux/features/toastSlice";
55
+ import { useCreateApiKeyMutation } from "../../../../redux/api/apiKeyApi";
56
+ var EXPIRY_OPTIONS = [
57
+ { label: "30 days", value: "30d" },
58
+ { label: "60 days", value: "60d" },
59
+ { label: "90 days", value: "90d" },
60
+ { label: "Never", value: "never" },
61
+ { label: "Custom date", value: "custom" },
62
+ ];
63
+ function addDays(days) {
64
+ var d = new Date();
65
+ d.setDate(d.getDate() + days);
66
+ return d.toISOString();
67
+ }
68
+ function resolveExpiresAt(expiryOption, customDate) {
69
+ switch (expiryOption) {
70
+ case "30d":
71
+ return addDays(30);
72
+ case "60d":
73
+ return addDays(60);
74
+ case "90d":
75
+ return addDays(90);
76
+ case "never":
77
+ return undefined;
78
+ case "custom":
79
+ return customDate ? customDate.toISOString() : undefined;
80
+ default:
81
+ return undefined;
82
+ }
83
+ }
84
+ export function GenerateApiKeyModal(_a) {
85
+ var _this = this;
86
+ var open = _a.open, onClose = _a.onClose, onCreated = _a.onCreated;
87
+ var dispatch = useDispatch();
88
+ var _b = useCreateApiKeyMutation(), createApiKey = _b[0], isLoading = _b[1].isLoading;
89
+ var _c = useState(null), customDate = _c[0], setCustomDate = _c[1];
90
+ var formik = useFormik({
91
+ initialValues: {
92
+ name: "",
93
+ expiryOption: "30d",
94
+ },
95
+ validationSchema: Yup.object({
96
+ name: Yup.string()
97
+ .trim()
98
+ .min(2, "Name must be at least 2 characters")
99
+ .max(64, "Name must be 64 characters or fewer")
100
+ .required("Key name is required"),
101
+ expiryOption: Yup.string().required("Expiry is required"),
102
+ }),
103
+ onSubmit: function (values, helpers) { return __awaiter(_this, void 0, void 0, function () {
104
+ var expiresAt, response, err_1, detail;
105
+ var _a;
106
+ return __generator(this, function (_b) {
107
+ switch (_b.label) {
108
+ case 0:
109
+ if (values.expiryOption === "custom" && !customDate) {
110
+ helpers.setFieldError("expiryOption", "Please select a custom expiry date");
111
+ return [2 /*return*/];
112
+ }
113
+ expiresAt = resolveExpiresAt(values.expiryOption, customDate);
114
+ _b.label = 1;
115
+ case 1:
116
+ _b.trys.push([1, 3, , 4]);
117
+ return [4 /*yield*/, createApiKey(__assign({ name: values.name.trim() }, (expiresAt ? { expiresAt: expiresAt } : {}))).unwrap()];
118
+ case 2:
119
+ response = _b.sent();
120
+ onCreated(response.data.apiKey, values.name.trim());
121
+ handleClose();
122
+ return [3 /*break*/, 4];
123
+ case 3:
124
+ err_1 = _b.sent();
125
+ detail = ((_a = err_1 === null || err_1 === void 0 ? void 0 : err_1.data) === null || _a === void 0 ? void 0 : _a.message) || "Failed to generate API key. Please try again.";
126
+ dispatch(showToast({ severity: "error", summary: "Error", detail: detail }));
127
+ return [3 /*break*/, 4];
128
+ case 4: return [2 /*return*/];
129
+ }
130
+ });
131
+ }); },
132
+ });
133
+ var handleClose = function () {
134
+ formik.resetForm();
135
+ setCustomDate(null);
136
+ onClose();
137
+ };
138
+ // Reset form when modal opens
139
+ useEffect(function () {
140
+ if (open) {
141
+ formik.resetForm();
142
+ setCustomDate(null);
143
+ }
144
+ }, [open]);
145
+ var nameError = formik.touched.name && formik.errors.name ? String(formik.errors.name) : "";
146
+ var expiryError = formik.touched.expiryOption && formik.errors.expiryOption
147
+ ? String(formik.errors.expiryOption)
148
+ : "";
149
+ return (_jsxs(SolidDialog, { open: open, onOpenChange: handleClose, style: { maxWidth: 480 }, children: [_jsx(SolidDialogHeader, { children: _jsx(SolidDialogTitle, { children: "Generate API Key" }) }), _jsx(SolidDialogSeparator, {}), _jsx(SolidDialogBody, { children: _jsx("form", { id: "generate-api-key-form", onSubmit: formik.handleSubmit, children: _jsxs("div", { className: "flex flex-column gap-3", children: [_jsxs("div", { className: "flex flex-column gap-2", children: [_jsxs("label", { htmlFor: "api-key-name", className: "form-field-label", children: ["Key Name ", _jsx("span", { style: { color: "var(--solid-danger-color, #ef4444)" }, children: "*" })] }), _jsx(SolidInput, { id: "api-key-name", name: "name", autoComplete: "off", placeholder: "e.g. CI/CD pipeline, Mobile app", value: formik.values.name, onChange: formik.handleChange, onBlur: formik.handleBlur }), nameError && _jsx(SolidMessage, { severity: "error", text: nameError })] }), _jsxs("div", { className: "flex flex-column gap-2", children: [_jsx("label", { htmlFor: "api-key-expiry", className: "form-field-label", children: "Expires" }), _jsx(SolidSelect, { value: formik.values.expiryOption, options: EXPIRY_OPTIONS, optionLabel: "label", optionValue: "value", onChange: function (_a) {
150
+ var value = _a.value;
151
+ formik.setFieldValue("expiryOption", value);
152
+ if (value !== "custom")
153
+ setCustomDate(null);
154
+ } }), formik.values.expiryOption === "custom" && (_jsx(SolidDatePicker, { selected: customDate, onChange: function (date) { return setCustomDate(date); }, minDate: new Date(), placeholderText: "Select expiry date", dateFormat: "dd/MM/yyyy" })), expiryError && _jsx(SolidMessage, { severity: "error", text: expiryError })] })] }) }) }), _jsx(SolidDialogSeparator, {}), _jsxs(SolidDialogFooter, { children: [_jsx(SolidButton, { variant: "outline", type: "button", onClick: handleClose, disabled: isLoading, children: "Cancel" }), _jsx(SolidButton, { type: "submit", form: "generate-api-key-form", loading: isLoading, children: "Generate Key" })] })] }));
155
+ }
156
+ //# sourceMappingURL=GenerateApiKeyModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenerateApiKeyModal.js","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/GenerateApiKeyModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { useFormik } from \"formik\";\nimport * as Yup from \"yup\";\nimport {\n SolidButton,\n SolidDatePicker,\n SolidDialog,\n SolidDialogBody,\n SolidDialogFooter,\n SolidDialogHeader,\n SolidDialogSeparator,\n SolidDialogTitle,\n SolidInput,\n SolidMessage,\n SolidSelect,\n} from \"../../../shad-cn-ui\";\nimport { showToast } from \"../../../../redux/features/toastSlice\";\nimport { useCreateApiKeyMutation } from \"../../../../redux/api/apiKeyApi\";\n\nconst EXPIRY_OPTIONS = [\n { label: \"30 days\", value: \"30d\" },\n { label: \"60 days\", value: \"60d\" },\n { label: \"90 days\", value: \"90d\" },\n { label: \"Never\", value: \"never\" },\n { label: \"Custom date\", value: \"custom\" },\n];\n\nfunction addDays(days: number): string {\n const d = new Date();\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nfunction resolveExpiresAt(expiryOption: string, customDate: Date | null): string | undefined {\n switch (expiryOption) {\n case \"30d\":\n return addDays(30);\n case \"60d\":\n return addDays(60);\n case \"90d\":\n return addDays(90);\n case \"never\":\n return undefined;\n case \"custom\":\n return customDate ? customDate.toISOString() : undefined;\n default:\n return undefined;\n }\n}\n\ninterface GenerateApiKeyModalProps {\n open: boolean;\n onClose: () => void;\n onCreated: (rawApiKey: string, keyName: string) => void;\n}\n\nexport function GenerateApiKeyModal({ open, onClose, onCreated }: GenerateApiKeyModalProps) {\n const dispatch = useDispatch();\n const [createApiKey, { isLoading }] = useCreateApiKeyMutation();\n const [customDate, setCustomDate] = useState<Date | null>(null);\n\n const formik = useFormik({\n initialValues: {\n name: \"\",\n expiryOption: \"30d\",\n },\n validationSchema: Yup.object({\n name: Yup.string()\n .trim()\n .min(2, \"Name must be at least 2 characters\")\n .max(64, \"Name must be 64 characters or fewer\")\n .required(\"Key name is required\"),\n expiryOption: Yup.string().required(\"Expiry is required\"),\n }),\n onSubmit: async (values, helpers) => {\n if (values.expiryOption === \"custom\" && !customDate) {\n helpers.setFieldError(\"expiryOption\", \"Please select a custom expiry date\");\n return;\n }\n\n const expiresAt = resolveExpiresAt(values.expiryOption, customDate);\n\n try {\n const response = await createApiKey({\n name: values.name.trim(),\n ...(expiresAt ? { expiresAt } : {}),\n }).unwrap();\n\n onCreated(response.data.apiKey, values.name.trim());\n handleClose();\n } catch (err: any) {\n const detail = err?.data?.message || \"Failed to generate API key. Please try again.\";\n dispatch(showToast({ severity: \"error\", summary: \"Error\", detail }));\n }\n },\n });\n\n const handleClose = () => {\n formik.resetForm();\n setCustomDate(null);\n onClose();\n };\n\n // Reset form when modal opens\n useEffect(() => {\n if (open) {\n formik.resetForm();\n setCustomDate(null);\n }\n }, [open]);\n\n const nameError =\n formik.touched.name && formik.errors.name ? String(formik.errors.name) : \"\";\n const expiryError =\n formik.touched.expiryOption && formik.errors.expiryOption\n ? String(formik.errors.expiryOption)\n : \"\";\n\n return (\n <SolidDialog open={open} onOpenChange={handleClose} style={{ maxWidth: 480 }}>\n <SolidDialogHeader>\n <SolidDialogTitle>Generate API Key</SolidDialogTitle>\n </SolidDialogHeader>\n <SolidDialogSeparator />\n <SolidDialogBody>\n <form id=\"generate-api-key-form\" onSubmit={formik.handleSubmit}>\n <div className=\"flex flex-column gap-3\">\n <div className=\"flex flex-column gap-2\">\n <label htmlFor=\"api-key-name\" className=\"form-field-label\">\n Key Name <span style={{ color: \"var(--solid-danger-color, #ef4444)\" }}>*</span>\n </label>\n <SolidInput\n id=\"api-key-name\"\n name=\"name\"\n autoComplete=\"off\"\n placeholder=\"e.g. CI/CD pipeline, Mobile app\"\n value={formik.values.name}\n onChange={formik.handleChange}\n onBlur={formik.handleBlur}\n />\n {nameError && <SolidMessage severity=\"error\" text={nameError} />}\n </div>\n\n <div className=\"flex flex-column gap-2\">\n <label htmlFor=\"api-key-expiry\" className=\"form-field-label\">\n Expires\n </label>\n <SolidSelect\n value={formik.values.expiryOption}\n options={EXPIRY_OPTIONS}\n optionLabel=\"label\"\n optionValue=\"value\"\n onChange={({ value }) => {\n formik.setFieldValue(\"expiryOption\", value);\n if (value !== \"custom\") setCustomDate(null);\n }}\n />\n {formik.values.expiryOption === \"custom\" && (\n <SolidDatePicker\n selected={customDate}\n onChange={(date: Date | null) => setCustomDate(date)}\n minDate={new Date()}\n placeholderText=\"Select expiry date\"\n dateFormat=\"dd/MM/yyyy\"\n />\n )}\n {expiryError && <SolidMessage severity=\"error\" text={expiryError} />}\n </div>\n </div>\n </form>\n </SolidDialogBody>\n <SolidDialogSeparator />\n <SolidDialogFooter>\n <SolidButton variant=\"outline\" type=\"button\" onClick={handleClose} disabled={isLoading}>\n Cancel\n </SolidButton>\n <SolidButton type=\"submit\" form=\"generate-api-key-form\" loading={isLoading}>\n Generate Key\n </SolidButton>\n </SolidDialogFooter>\n </SolidDialog>\n );\n}\n"]}
@@ -0,0 +1,184 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useDispatch } from "react-redux";
3
+ import { useFormik } from "formik";
4
+ import * as Yup from "yup";
5
+ import {
6
+ SolidButton,
7
+ SolidDatePicker,
8
+ SolidDialog,
9
+ SolidDialogBody,
10
+ SolidDialogFooter,
11
+ SolidDialogHeader,
12
+ SolidDialogSeparator,
13
+ SolidDialogTitle,
14
+ SolidInput,
15
+ SolidMessage,
16
+ SolidSelect,
17
+ } from "../../../shad-cn-ui";
18
+ import { showToast } from "../../../../redux/features/toastSlice";
19
+ import { useCreateApiKeyMutation } from "../../../../redux/api/apiKeyApi";
20
+
21
+ const EXPIRY_OPTIONS = [
22
+ { label: "30 days", value: "30d" },
23
+ { label: "60 days", value: "60d" },
24
+ { label: "90 days", value: "90d" },
25
+ { label: "Never", value: "never" },
26
+ { label: "Custom date", value: "custom" },
27
+ ];
28
+
29
+ function addDays(days: number): string {
30
+ const d = new Date();
31
+ d.setDate(d.getDate() + days);
32
+ return d.toISOString();
33
+ }
34
+
35
+ function resolveExpiresAt(expiryOption: string, customDate: Date | null): string | undefined {
36
+ switch (expiryOption) {
37
+ case "30d":
38
+ return addDays(30);
39
+ case "60d":
40
+ return addDays(60);
41
+ case "90d":
42
+ return addDays(90);
43
+ case "never":
44
+ return undefined;
45
+ case "custom":
46
+ return customDate ? customDate.toISOString() : undefined;
47
+ default:
48
+ return undefined;
49
+ }
50
+ }
51
+
52
+ interface GenerateApiKeyModalProps {
53
+ open: boolean;
54
+ onClose: () => void;
55
+ onCreated: (rawApiKey: string, keyName: string) => void;
56
+ }
57
+
58
+ export function GenerateApiKeyModal({ open, onClose, onCreated }: GenerateApiKeyModalProps) {
59
+ const dispatch = useDispatch();
60
+ const [createApiKey, { isLoading }] = useCreateApiKeyMutation();
61
+ const [customDate, setCustomDate] = useState<Date | null>(null);
62
+
63
+ const formik = useFormik({
64
+ initialValues: {
65
+ name: "",
66
+ expiryOption: "30d",
67
+ },
68
+ validationSchema: Yup.object({
69
+ name: Yup.string()
70
+ .trim()
71
+ .min(2, "Name must be at least 2 characters")
72
+ .max(64, "Name must be 64 characters or fewer")
73
+ .required("Key name is required"),
74
+ expiryOption: Yup.string().required("Expiry is required"),
75
+ }),
76
+ onSubmit: async (values, helpers) => {
77
+ if (values.expiryOption === "custom" && !customDate) {
78
+ helpers.setFieldError("expiryOption", "Please select a custom expiry date");
79
+ return;
80
+ }
81
+
82
+ const expiresAt = resolveExpiresAt(values.expiryOption, customDate);
83
+
84
+ try {
85
+ const response = await createApiKey({
86
+ name: values.name.trim(),
87
+ ...(expiresAt ? { expiresAt } : {}),
88
+ }).unwrap();
89
+
90
+ onCreated(response.data.apiKey, values.name.trim());
91
+ handleClose();
92
+ } catch (err: any) {
93
+ const detail = err?.data?.message || "Failed to generate API key. Please try again.";
94
+ dispatch(showToast({ severity: "error", summary: "Error", detail }));
95
+ }
96
+ },
97
+ });
98
+
99
+ const handleClose = () => {
100
+ formik.resetForm();
101
+ setCustomDate(null);
102
+ onClose();
103
+ };
104
+
105
+ // Reset form when modal opens
106
+ useEffect(() => {
107
+ if (open) {
108
+ formik.resetForm();
109
+ setCustomDate(null);
110
+ }
111
+ }, [open]);
112
+
113
+ const nameError =
114
+ formik.touched.name && formik.errors.name ? String(formik.errors.name) : "";
115
+ const expiryError =
116
+ formik.touched.expiryOption && formik.errors.expiryOption
117
+ ? String(formik.errors.expiryOption)
118
+ : "";
119
+
120
+ return (
121
+ <SolidDialog open={open} onOpenChange={handleClose} style={{ maxWidth: 480 }}>
122
+ <SolidDialogHeader>
123
+ <SolidDialogTitle>Generate API Key</SolidDialogTitle>
124
+ </SolidDialogHeader>
125
+ <SolidDialogSeparator />
126
+ <SolidDialogBody>
127
+ <form id="generate-api-key-form" onSubmit={formik.handleSubmit}>
128
+ <div className="flex flex-column gap-3">
129
+ <div className="flex flex-column gap-2">
130
+ <label htmlFor="api-key-name" className="form-field-label">
131
+ Key Name <span style={{ color: "var(--solid-danger-color, #ef4444)" }}>*</span>
132
+ </label>
133
+ <SolidInput
134
+ id="api-key-name"
135
+ name="name"
136
+ autoComplete="off"
137
+ placeholder="e.g. CI/CD pipeline, Mobile app"
138
+ value={formik.values.name}
139
+ onChange={formik.handleChange}
140
+ onBlur={formik.handleBlur}
141
+ />
142
+ {nameError && <SolidMessage severity="error" text={nameError} />}
143
+ </div>
144
+
145
+ <div className="flex flex-column gap-2">
146
+ <label htmlFor="api-key-expiry" className="form-field-label">
147
+ Expires
148
+ </label>
149
+ <SolidSelect
150
+ value={formik.values.expiryOption}
151
+ options={EXPIRY_OPTIONS}
152
+ optionLabel="label"
153
+ optionValue="value"
154
+ onChange={({ value }) => {
155
+ formik.setFieldValue("expiryOption", value);
156
+ if (value !== "custom") setCustomDate(null);
157
+ }}
158
+ />
159
+ {formik.values.expiryOption === "custom" && (
160
+ <SolidDatePicker
161
+ selected={customDate}
162
+ onChange={(date: Date | null) => setCustomDate(date)}
163
+ minDate={new Date()}
164
+ placeholderText="Select expiry date"
165
+ dateFormat="dd/MM/yyyy"
166
+ />
167
+ )}
168
+ {expiryError && <SolidMessage severity="error" text={expiryError} />}
169
+ </div>
170
+ </div>
171
+ </form>
172
+ </SolidDialogBody>
173
+ <SolidDialogSeparator />
174
+ <SolidDialogFooter>
175
+ <SolidButton variant="outline" type="button" onClick={handleClose} disabled={isLoading}>
176
+ Cancel
177
+ </SolidButton>
178
+ <SolidButton type="submit" form="generate-api-key-form" loading={isLoading}>
179
+ Generate Key
180
+ </SolidButton>
181
+ </SolidDialogFooter>
182
+ </SolidDialog>
183
+ );
184
+ }
@@ -0,0 +1,9 @@
1
+ interface RevealApiKeyModalProps {
2
+ open: boolean;
3
+ apiKey: string;
4
+ keyName: string;
5
+ onClose: () => void;
6
+ }
7
+ export declare function RevealApiKeyModal({ open, apiKey, keyName, onClose }: RevealApiKeyModalProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=RevealApiKeyModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RevealApiKeyModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/RevealApiKeyModal.tsx"],"names":[],"mappings":"AAYA,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,sBAAsB,2CA2F3F"}
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { AlertTriangle, CheckCircle, Copy } from "lucide-react";
4
+ import { SolidButton, SolidDialog, SolidDialogBody, SolidDialogFooter, SolidDialogHeader, SolidDialogSeparator, SolidDialogTitle, } from "../../../shad-cn-ui";
5
+ export function RevealApiKeyModal(_a) {
6
+ var open = _a.open, apiKey = _a.apiKey, keyName = _a.keyName, onClose = _a.onClose;
7
+ var _b = useState(false), copied = _b[0], setCopied = _b[1];
8
+ var handleCopy = function () {
9
+ navigator.clipboard.writeText(apiKey).then(function () {
10
+ setCopied(true);
11
+ setTimeout(function () { return setCopied(false); }, 3000);
12
+ });
13
+ };
14
+ var handleClose = function () {
15
+ setCopied(false);
16
+ onClose();
17
+ };
18
+ return (_jsxs(SolidDialog, { open: open, onOpenChange: handleClose, dismissible: false, style: { maxWidth: 520 }, children: [_jsx(SolidDialogHeader, { children: _jsx(SolidDialogTitle, { children: "API Key Created" }) }), _jsx(SolidDialogSeparator, {}), _jsxs(SolidDialogBody, { children: [_jsxs("div", { className: "solid-api-key-reveal-warning flex align-items-start gap-2 mb-4", children: [_jsx(AlertTriangle, { size: 16, className: "flex-shrink-0 mt-1" }), _jsxs("p", { className: "m-0", style: { fontSize: 13 }, children: [_jsx("strong", { children: "Copy this key now." }), " It will not be shown again once you close this dialog. Store it somewhere secure."] })] }), _jsx("p", { className: "form-field-label mb-2", children: keyName }), _jsxs("div", { className: "solid-api-key-reveal-box flex align-items-center gap-2 p-3", style: {
19
+ background: "var(--solid-surface-secondary, #f5f5f5)",
20
+ borderRadius: 6,
21
+ border: "1px solid var(--solid-border-color, #e0e0e0)",
22
+ }, children: [_jsx("code", { className: "flex-1", style: {
23
+ fontFamily: "monospace",
24
+ fontSize: 13,
25
+ wordBreak: "break-all",
26
+ userSelect: "all",
27
+ }, children: apiKey }), _jsx("button", { type: "button", title: copied ? "Copied!" : "Copy to clipboard", onClick: handleCopy, style: {
28
+ background: "none",
29
+ border: "none",
30
+ cursor: "pointer",
31
+ padding: "4px",
32
+ display: "flex",
33
+ alignItems: "center",
34
+ flexShrink: 0,
35
+ }, children: copied ? (_jsx(CheckCircle, { size: 16, style: { color: "var(--solid-success-color, #22c55e)" } })) : (_jsx(Copy, { size: 16 })) })] }), copied && (_jsx("p", { className: "m-0 mt-2", style: { fontSize: 12, color: "var(--solid-success-color, #22c55e)" }, children: "Copied to clipboard!" }))] }), _jsx(SolidDialogSeparator, {}), _jsxs(SolidDialogFooter, { children: [_jsx(SolidButton, { variant: "outline", onClick: handleClose, children: "Close" }), _jsx(SolidButton, { onClick: handleClose, children: "I've Saved This Key" })] })] }));
36
+ }
37
+ //# sourceMappingURL=RevealApiKeyModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RevealApiKeyModal.js","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/RevealApiKeyModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { AlertTriangle, CheckCircle, Copy } from \"lucide-react\";\nimport {\n SolidButton,\n SolidDialog,\n SolidDialogBody,\n SolidDialogFooter,\n SolidDialogHeader,\n SolidDialogSeparator,\n SolidDialogTitle,\n} from \"../../../shad-cn-ui\";\n\ninterface RevealApiKeyModalProps {\n open: boolean;\n apiKey: string;\n keyName: string;\n onClose: () => void;\n}\n\nexport function RevealApiKeyModal({ open, apiKey, keyName, onClose }: RevealApiKeyModalProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = () => {\n navigator.clipboard.writeText(apiKey).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 3000);\n });\n };\n\n const handleClose = () => {\n setCopied(false);\n onClose();\n };\n\n return (\n <SolidDialog open={open} onOpenChange={handleClose} dismissible={false} style={{ maxWidth: 520 }}>\n <SolidDialogHeader>\n <SolidDialogTitle>API Key Created</SolidDialogTitle>\n </SolidDialogHeader>\n <SolidDialogSeparator />\n <SolidDialogBody>\n <div className=\"solid-api-key-reveal-warning flex align-items-start gap-2 mb-4\">\n <AlertTriangle size={16} className=\"flex-shrink-0 mt-1\" />\n <p className=\"m-0\" style={{ fontSize: 13 }}>\n <strong>Copy this key now.</strong> It will not be shown again once you close this dialog. Store it somewhere secure.\n </p>\n </div>\n\n <p className=\"form-field-label mb-2\">\n {keyName}\n </p>\n\n <div\n className=\"solid-api-key-reveal-box flex align-items-center gap-2 p-3\"\n style={{\n background: \"var(--solid-surface-secondary, #f5f5f5)\",\n borderRadius: 6,\n border: \"1px solid var(--solid-border-color, #e0e0e0)\",\n }}\n >\n <code\n className=\"flex-1\"\n style={{\n fontFamily: \"monospace\",\n fontSize: 13,\n wordBreak: \"break-all\",\n userSelect: \"all\",\n }}\n >\n {apiKey}\n </code>\n <button\n type=\"button\"\n title={copied ? \"Copied!\" : \"Copy to clipboard\"}\n onClick={handleCopy}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n flexShrink: 0,\n }}\n >\n {copied ? (\n <CheckCircle size={16} style={{ color: \"var(--solid-success-color, #22c55e)\" }} />\n ) : (\n <Copy size={16} />\n )}\n </button>\n </div>\n\n {copied && (\n <p className=\"m-0 mt-2\" style={{ fontSize: 12, color: \"var(--solid-success-color, #22c55e)\" }}>\n Copied to clipboard!\n </p>\n )}\n </SolidDialogBody>\n <SolidDialogSeparator />\n <SolidDialogFooter>\n <SolidButton variant=\"outline\" onClick={handleClose}>\n Close\n </SolidButton>\n <SolidButton onClick={handleClose}>\n I've Saved This Key\n </SolidButton>\n </SolidDialogFooter>\n </SolidDialog>\n );\n}\n"]}
@@ -0,0 +1,111 @@
1
+ import { useState } from "react";
2
+ import { AlertTriangle, CheckCircle, Copy } from "lucide-react";
3
+ import {
4
+ SolidButton,
5
+ SolidDialog,
6
+ SolidDialogBody,
7
+ SolidDialogFooter,
8
+ SolidDialogHeader,
9
+ SolidDialogSeparator,
10
+ SolidDialogTitle,
11
+ } from "../../../shad-cn-ui";
12
+
13
+ interface RevealApiKeyModalProps {
14
+ open: boolean;
15
+ apiKey: string;
16
+ keyName: string;
17
+ onClose: () => void;
18
+ }
19
+
20
+ export function RevealApiKeyModal({ open, apiKey, keyName, onClose }: RevealApiKeyModalProps) {
21
+ const [copied, setCopied] = useState(false);
22
+
23
+ const handleCopy = () => {
24
+ navigator.clipboard.writeText(apiKey).then(() => {
25
+ setCopied(true);
26
+ setTimeout(() => setCopied(false), 3000);
27
+ });
28
+ };
29
+
30
+ const handleClose = () => {
31
+ setCopied(false);
32
+ onClose();
33
+ };
34
+
35
+ return (
36
+ <SolidDialog open={open} onOpenChange={handleClose} dismissible={false} style={{ maxWidth: 520 }}>
37
+ <SolidDialogHeader>
38
+ <SolidDialogTitle>API Key Created</SolidDialogTitle>
39
+ </SolidDialogHeader>
40
+ <SolidDialogSeparator />
41
+ <SolidDialogBody>
42
+ <div className="solid-api-key-reveal-warning flex align-items-start gap-2 mb-4">
43
+ <AlertTriangle size={16} className="flex-shrink-0 mt-1" />
44
+ <p className="m-0" style={{ fontSize: 13 }}>
45
+ <strong>Copy this key now.</strong> It will not be shown again once you close this dialog. Store it somewhere secure.
46
+ </p>
47
+ </div>
48
+
49
+ <p className="form-field-label mb-2">
50
+ {keyName}
51
+ </p>
52
+
53
+ <div
54
+ className="solid-api-key-reveal-box flex align-items-center gap-2 p-3"
55
+ style={{
56
+ background: "var(--solid-surface-secondary, #f5f5f5)",
57
+ borderRadius: 6,
58
+ border: "1px solid var(--solid-border-color, #e0e0e0)",
59
+ }}
60
+ >
61
+ <code
62
+ className="flex-1"
63
+ style={{
64
+ fontFamily: "monospace",
65
+ fontSize: 13,
66
+ wordBreak: "break-all",
67
+ userSelect: "all",
68
+ }}
69
+ >
70
+ {apiKey}
71
+ </code>
72
+ <button
73
+ type="button"
74
+ title={copied ? "Copied!" : "Copy to clipboard"}
75
+ onClick={handleCopy}
76
+ style={{
77
+ background: "none",
78
+ border: "none",
79
+ cursor: "pointer",
80
+ padding: "4px",
81
+ display: "flex",
82
+ alignItems: "center",
83
+ flexShrink: 0,
84
+ }}
85
+ >
86
+ {copied ? (
87
+ <CheckCircle size={16} style={{ color: "var(--solid-success-color, #22c55e)" }} />
88
+ ) : (
89
+ <Copy size={16} />
90
+ )}
91
+ </button>
92
+ </div>
93
+
94
+ {copied && (
95
+ <p className="m-0 mt-2" style={{ fontSize: 12, color: "var(--solid-success-color, #22c55e)" }}>
96
+ Copied to clipboard!
97
+ </p>
98
+ )}
99
+ </SolidDialogBody>
100
+ <SolidDialogSeparator />
101
+ <SolidDialogFooter>
102
+ <SolidButton variant="outline" onClick={handleClose}>
103
+ Close
104
+ </SolidButton>
105
+ <SolidButton onClick={handleClose}>
106
+ I've Saved This Key
107
+ </SolidButton>
108
+ </SolidDialogFooter>
109
+ </SolidDialog>
110
+ );
111
+ }
@@ -0,0 +1,4 @@
1
+ export { ApiKeysTab } from "./ApiKeysTab";
2
+ export { GenerateApiKeyModal } from "./GenerateApiKeyModal";
3
+ export { RevealApiKeyModal } from "./RevealApiKeyModal";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { ApiKeysTab } from "./ApiKeysTab";
2
+ export { GenerateApiKeyModal } from "./GenerateApiKeyModal";
3
+ export { RevealApiKeyModal } from "./RevealApiKeyModal";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export { ApiKeysTab } from \"./ApiKeysTab\";\nexport { GenerateApiKeyModal } from \"./GenerateApiKeyModal\";\nexport { RevealApiKeyModal } from \"./RevealApiKeyModal\";\n"]}
@@ -0,0 +1,3 @@
1
+ export { ApiKeysTab } from "./ApiKeysTab";
2
+ export { GenerateApiKeyModal } from "./GenerateApiKeyModal";
3
+ export { RevealApiKeyModal } from "./RevealApiKeyModal";
@@ -0,0 +1,3 @@
1
+ # no such endpoints exist, need to called user get with populate api key filter
2
+ useGetSelfApiKeysQuery() → GET /iam/api-keys (self mode)
3
+ useGetUserApiKeysQuery(userId) → GET /users/:id/api-keys (admin mode)
package/dist/index.d.ts CHANGED
@@ -234,5 +234,6 @@ export { InitiateGoogleOauthPage as AuthInitiateGoogleOauthPage } from './routes
234
234
  export { SsoPage as AuthSsoPage } from './routes/pages/auth/SsoPage';
235
235
  export { ErrorPage } from './routes/pages/ErrorPage';
236
236
  export { NotFoundPage } from './routes/pages/NotFoundPage';
237
+ export { handleAuthSuccess } from './adapters/auth/helper';
237
238
  export * from "./styles";
238
239
  //# sourceMappingURL=index.d.ts.map