@solidxai/core-ui 0.1.7-beta.7 → 0.1.7-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/auth/helper.d.ts +9 -0
- package/dist/adapters/auth/helper.d.ts.map +1 -0
- package/dist/adapters/auth/helper.js +37 -0
- package/dist/adapters/auth/helper.js.map +1 -0
- package/dist/adapters/auth/helper.ts +45 -0
- package/dist/adapters/auth/signInWithOtp.d.ts.map +1 -1
- package/dist/adapters/auth/signInWithOtp.js +3 -27
- package/dist/adapters/auth/signInWithOtp.js.map +1 -1
- package/dist/adapters/auth/signInWithOtp.ts +3 -23
- package/dist/components/common/GeneralSettings.d.ts.map +1 -1
- package/dist/components/common/GeneralSettings.js +68 -36
- package/dist/components/common/GeneralSettings.js.map +1 -1
- package/dist/components/common/GeneralSettings.tsx +81 -42
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts +27 -5
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js +25 -37
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.tsx +131 -52
- package/dist/components/core/chatter/SolidChatter.d.ts +2 -1
- package/dist/components/core/chatter/SolidChatter.d.ts.map +1 -1
- package/dist/components/core/chatter/SolidChatter.js +2 -2
- package/dist/components/core/chatter/SolidChatter.js.map +1 -1
- package/dist/components/core/chatter/SolidChatter.tsx +2 -1
- package/dist/components/core/chatter/SolidChatterHeader.d.ts +1 -0
- package/dist/components/core/chatter/SolidChatterHeader.d.ts.map +1 -1
- package/dist/components/core/chatter/SolidChatterHeader.js +3 -3
- package/dist/components/core/chatter/SolidChatterHeader.js.map +1 -1
- package/dist/components/core/chatter/SolidChatterHeader.tsx +4 -3
- package/dist/components/core/chatter/SolidMessageComposer.d.ts +2 -1
- package/dist/components/core/chatter/SolidMessageComposer.d.ts.map +1 -1
- package/dist/components/core/chatter/SolidMessageComposer.js +3 -1
- package/dist/components/core/chatter/SolidMessageComposer.js.map +1 -1
- package/dist/components/core/chatter/SolidMessageComposer.tsx +3 -1
- package/dist/components/core/common/SolidViewLayoutManager.d.ts +17 -0
- package/dist/components/core/common/SolidViewLayoutManager.d.ts.map +1 -1
- package/dist/components/core/common/SolidViewLayoutManager.js +58 -1
- package/dist/components/core/common/SolidViewLayoutManager.js.map +1 -1
- package/dist/components/core/common/SolidViewLayoutManager.ts +43 -2
- package/dist/components/core/extension/solid-core/chatterMessage/form/SolidChatterMessageCoModelEntityIdFormViewWidget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/chatterMessage/form/SolidChatterMessageCoModelEntityIdFormViewWidget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/chatterMessage/form/SolidChatterMessageCoModelEntityIdFormViewWidget.js +92 -0
- package/dist/components/core/extension/solid-core/chatterMessage/form/SolidChatterMessageCoModelEntityIdFormViewWidget.js.map +1 -0
- package/dist/components/core/extension/solid-core/chatterMessage/form/SolidChatterMessageCoModelEntityIdFormViewWidget.tsx +68 -0
- package/dist/components/core/extension/solid-core/chatterMessage/list/SolidChatterMessageCoModelEntityIdListViewWidget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/chatterMessage/list/SolidChatterMessageCoModelEntityIdListViewWidget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/chatterMessage/list/SolidChatterMessageCoModelEntityIdListViewWidget.js +87 -0
- package/dist/components/core/extension/solid-core/chatterMessage/list/SolidChatterMessageCoModelEntityIdListViewWidget.js.map +1 -0
- package/dist/components/core/extension/solid-core/chatterMessage/list/SolidChatterMessageCoModelEntityIdListViewWidget.tsx +70 -0
- package/dist/components/core/extension/solid-core/listOfValues/form/SolidLovTypeChangeFormEditWidget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/listOfValues/form/SolidLovTypeChangeFormEditWidget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/listOfValues/form/SolidLovTypeChangeFormEditWidget.js +111 -0
- package/dist/components/core/extension/solid-core/listOfValues/form/SolidLovTypeChangeFormEditWidget.js.map +1 -0
- package/dist/components/core/extension/solid-core/listOfValues/form/SolidLovTypeChangeFormEditWidget.tsx +122 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/SolidMqMessageStageFormViewWIdget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/SolidMqMessageStageFormViewWIdget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/SolidMqMessageStageFormViewWIdget.js +10 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/SolidMqMessageStageFormViewWIdget.js.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/SolidMqMessageStageFormViewWIdget.tsx +21 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/mqMessageOnFormLoadHandler.d.ts +8 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/mqMessageOnFormLoadHandler.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/mqMessageOnFormLoadHandler.js +62 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/mqMessageOnFormLoadHandler.js.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/form/mqMessageOnFormLoadHandler.tsx +27 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessageStageListViewWidget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessageStageListViewWidget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessageStageListViewWidget.js +8 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessageStageListViewWidget.js.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessageStageListViewWidget.tsx +15 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessagesSummarizeListHeaderAction.d.ts +3 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessagesSummarizeListHeaderAction.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessagesSummarizeListHeaderAction.js +158 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessagesSummarizeListHeaderAction.js.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/list/SolidMqMessagesSummarizeListHeaderAction.tsx +185 -0
- package/dist/components/core/extension/solid-core/mqMessage/ui/MqMessageStageBadge.d.ts +17 -0
- package/dist/components/core/extension/solid-core/mqMessage/ui/MqMessageStageBadge.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/ui/MqMessageStageBadge.js +52 -0
- package/dist/components/core/extension/solid-core/mqMessage/ui/MqMessageStageBadge.js.map +1 -0
- package/dist/components/core/extension/solid-core/mqMessage/ui/MqMessageStageBadge.tsx +83 -0
- package/dist/components/core/locales/SolidChatterLocaleTabView.d.ts.map +1 -1
- package/dist/components/core/locales/SolidChatterLocaleTabView.js +7 -5
- package/dist/components/core/locales/SolidChatterLocaleTabView.js.map +1 -1
- package/dist/components/core/locales/SolidChatterLocaleTabView.tsx +3 -0
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.css +38 -0
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.d.ts +1 -0
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.d.ts.map +1 -1
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.js +4 -3
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.js.map +1 -1
- package/dist/components/core/users/ApiKeysTab/ApiKeysTab.tsx +13 -3
- package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.d.ts +2 -1
- package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.d.ts.map +1 -1
- package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.js +6 -5
- package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.js.map +1 -1
- package/dist/components/core/users/ApiKeysTab/GenerateApiKeyModal.tsx +6 -7
- package/dist/components/core/users/CreateUser.d.ts.map +1 -1
- package/dist/components/core/users/CreateUser.js +89 -35
- package/dist/components/core/users/CreateUser.js.map +1 -1
- package/dist/components/core/users/CreateUser.tsx +291 -165
- package/dist/components/layout/SolidAiStudioLayout.d.ts.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.js +123 -8
- package/dist/components/layout/SolidAiStudioLayout.js.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.tsx +70 -6
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +10 -6
- package/dist/helpers/registry.js.map +1 -1
- package/dist/helpers/registry.ts +11 -7
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.ts +12 -0
- package/dist/redux/api/apiKeyApi.d.ts +8 -1
- package/dist/redux/api/apiKeyApi.d.ts.map +1 -1
- package/dist/redux/api/apiKeyApi.js +12 -1
- package/dist/redux/api/apiKeyApi.js.map +1 -1
- package/dist/redux/api/apiKeyApi.ts +9 -0
- package/dist/redux/store/defaultStoreConfig.d.ts +16 -1
- package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
- package/dist/redux/store/defaultStoreConfig.js +3 -1
- package/dist/redux/store/defaultStoreConfig.js.map +1 -1
- package/dist/redux/store/defaultStoreConfig.ts +3 -1
- package/dist/routes/guards/AuthGuard.d.ts +5 -1
- package/dist/routes/guards/AuthGuard.d.ts.map +1 -1
- package/dist/routes/guards/AuthGuard.js +13 -2
- package/dist/routes/guards/AuthGuard.js.map +1 -1
- package/dist/routes/guards/AuthGuard.tsx +27 -3
- package/dist/routes/guards/GuestGuard.d.ts +2 -0
- package/dist/routes/guards/GuestGuard.d.ts.map +1 -0
- package/dist/routes/guards/GuestGuard.js +23 -0
- package/dist/routes/guards/GuestGuard.js.map +1 -0
- package/dist/routes/guards/GuestGuard.tsx +24 -0
- package/dist/routes/solidRoutes.d.ts.map +1 -1
- package/dist/routes/solidRoutes.js +2 -1
- package/dist/routes/solidRoutes.js.map +1 -1
- package/dist/routes/solidRoutes.tsx +2 -1
- package/dist/types/solid-core.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeysTab.js","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/ApiKeysTab.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { KeyRound, Plus } from \"lucide-react\";\nimport { SolidButton, SolidSpinner, SolidSwitch, SolidTag } from \"../../../shad-cn-ui\";\nimport { showToast } from \"../../../../redux/features/toastSlice\";\nimport {\n useGetUserApiKeysQuery,\n useUpdateApiKeyMutation,\n type ApiKeyRecord,\n} from \"../../../../redux/api/apiKeyApi\";\nimport { GenerateApiKeyModal } from \"./GenerateApiKeyModal\";\nimport { RevealApiKeyModal } from \"./RevealApiKeyModal\";\n\nfunction formatDate(iso: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction getExpiryStatus(expiresAt: string | null): \"expired\" | \"expiring-soon\" | \"ok\" | \"never\" {\n if (!expiresAt) return \"never\";\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return \"expired\";\n if (diff < 7 * 24 * 60 * 60 * 1000) return \"expiring-soon\";\n return \"ok\";\n}\n\nfunction ApiKeysTable({\n keys,\n onToggleActive,\n isTogglingId,\n}: {\n keys: ApiKeyRecord[];\n onToggleActive: (key: ApiKeyRecord) => void;\n isTogglingId: string | null;\n}) {\n if (keys.length === 0) {\n return (\n <div\n className=\"flex flex-column align-items-center justify-content-center gap-3 py-6\"\n style={{ color: \"var(--solid-text-secondary, #888)\" }}\n >\n <KeyRound size={32} strokeWidth={1.5} />\n <div className=\"text-center\">\n <p className=\"m-0\" style={{ fontSize: 14, fontWeight: 500 }}>\n No API keys\n </p>\n <p className=\"m-0 mt-1\" style={{ fontSize: 12 }}>\n Generate a key to enable programmatic access.\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div style={{ overflowX: \"auto\" }}>\n <table style={{ width: \"100%\", borderCollapse: \"collapse\" }}>\n <thead>\n <tr>\n <th className=\"solid-api-keys-th\">Name</th>\n <th className=\"solid-api-keys-th\">Key</th>\n <th className=\"solid-api-keys-th\">Status</th>\n <th className=\"solid-api-keys-th\">Expires</th>\n <th className=\"solid-api-keys-th\">Last Used</th>\n <th className=\"solid-api-keys-th\">Active</th>\n </tr>\n </thead>\n <tbody>\n {keys.map((key) => {\n const expiryStatus = getExpiryStatus(key.expiresAt);\n const isExpired = expiryStatus === \"expired\";\n\n return (\n <tr key={key.id} className={isExpired ? \"solid-api-keys-row--expired\" : undefined}>\n <td className=\"solid-api-keys-td\">\n <span style={{ fontWeight: 500 }}>{key.name}</span>\n </td>\n\n <td className=\"solid-api-keys-td\">\n <code\n style={{\n fontFamily: \"monospace\",\n fontSize: 13,\n background: \"var(--solid-surface-secondary, #f5f5f5)\",\n padding: \"2px 6px\",\n borderRadius: 4,\n }}\n >\n {key.maskedKey}\n </code>\n </td>\n\n <td className=\"solid-api-keys-td\">\n {isExpired ? (\n <SolidTag tone=\"danger\">Expired</SolidTag>\n ) : !key.isActive ? (\n <SolidTag tone=\"warn\">Inactive</SolidTag>\n ) : expiryStatus === \"expiring-soon\" ? (\n <SolidTag tone=\"warn\">Expiring soon</SolidTag>\n ) : (\n <SolidTag tone=\"success\">Active</SolidTag>\n )}\n </td>\n\n <td\n className=\"solid-api-keys-td\"\n style={{\n color:\n expiryStatus === \"expired\"\n ? \"var(--solid-danger-color, #ef4444)\"\n : expiryStatus === \"expiring-soon\"\n ? \"var(--solid-warn-color, #f59e0b)\"\n : undefined,\n }}\n >\n {expiryStatus === \"never\" ? (\n <span style={{ color: \"var(--solid-text-secondary, #888)\" }}>Never</span>\n ) : (\n formatDate(key.expiresAt)\n )}\n </td>\n\n <td className=\"solid-api-keys-td\" style={{ color: \"var(--solid-text-secondary, #888)\" }}>\n {formatDate(key.lastUsedAt)}\n </td>\n\n <td className=\"solid-api-keys-td\">\n {isTogglingId === key.id ? (\n <SolidSpinner />\n ) : (\n <SolidSwitch\n checked={key.isActive}\n disabled={isExpired}\n onChange={() => onToggleActive(key)}\n />\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\ninterface ApiKeysTabProps {\n userId: string;\n canCreate?: boolean;\n}\n\nexport function ApiKeysTab({ userId, canCreate = false }: ApiKeysTabProps) {\n const dispatch = useDispatch();\n const { data, isLoading, isError } = useGetUserApiKeysQuery(userId);\n const [updateApiKey] = useUpdateApiKeyMutation();\n const [togglingId, setTogglingId] = useState<string | null>(null);\n const [showGenerate, setShowGenerate] = useState(false);\n const [revealKey, setRevealKey] = useState<{ apiKey: string; keyName: string } | null>(null);\n\n const keys: ApiKeyRecord[] = data?.data?.apiKeys ?? [];\n\n const handleToggle = async (key: ApiKeyRecord) => {\n setTogglingId(key.id);\n try {\n await updateApiKey({ id: key.id, isActive: !key.isActive }).unwrap();\n dispatch(\n showToast({\n severity: \"success\",\n summary: \"Updated\",\n detail: `API key \"${key.name}\" ${!key.isActive ? \"activated\" : \"deactivated\"}.`,\n })\n );\n } catch (err: any) {\n dispatch(\n showToast({\n severity: \"error\",\n summary: \"Error\",\n detail: err?.data?.message || \"Failed to update API key.\",\n })\n );\n } finally {\n setTogglingId(null);\n }\n };\n\n return (\n <>\n <div className=\"solid-api-keys-tab\">\n <div className=\"flex align-items-center justify-content-between mb-4\">\n <div>\n <p className=\"m-0\" style={{ fontWeight: 600, fontSize: 14 }}>\n API Keys\n </p>\n <p className=\"m-0 mt-1\" style={{ fontSize: 12, color: \"var(--solid-text-secondary, #888)\" }}>\n Keys grant programmatic access. Store them securely — they are shown only once.\n </p>\n </div>\n {canCreate && (\n <SolidButton size=\"small\" type=\"button\" onClick={() => setShowGenerate(true)}>\n <Plus size={14} />\n Generate Key\n </SolidButton>\n )}\n </div>\n\n {isLoading ? (\n <div className=\"flex justify-content-center py-5\">\n <SolidSpinner />\n </div>\n ) : isError && keys.length === 0 ? (\n <div\n className=\"flex flex-column align-items-center justify-content-center gap-2 py-5\"\n style={{ color: \"var(--solid-text-secondary, #888)\", fontSize: 13 }}\n >\n <p className=\"m-0\">Something went wrong while loading API keys.</p>\n <p className=\"m-0\">Please refresh the page and try again.</p>\n </div>\n ) : (\n <ApiKeysTable keys={keys} onToggleActive={handleToggle} isTogglingId={togglingId} />\n )}\n </div>\n\n <GenerateApiKeyModal\n open={showGenerate}\n onClose={() => setShowGenerate(false)}\n onCreated={(apiKey, keyName) => {\n setShowGenerate(false);\n setRevealKey({ apiKey, keyName });\n }}\n />\n\n {revealKey && (\n <RevealApiKeyModal\n open={true}\n apiKey={revealKey.apiKey}\n keyName={revealKey.keyName}\n onClose={() => setRevealKey(null)}\n />\n )}\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ApiKeysTab.js","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/ApiKeysTab.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { KeyRound, Plus } from \"lucide-react\";\nimport \"./ApiKeysTab.css\";\nimport { SolidButton, SolidSpinner, SolidSwitch, SolidTag } from \"../../../shad-cn-ui\";\nimport { showToast } from \"../../../../redux/features/toastSlice\";\nimport {\n useGetUserApiKeysQuery,\n useUpdateApiKeyMutation,\n type ApiKeyRecord,\n} from \"../../../../redux/api/apiKeyApi\";\nimport { GenerateApiKeyModal } from \"./GenerateApiKeyModal\";\nimport { RevealApiKeyModal } from \"./RevealApiKeyModal\";\n\nfunction formatDate(iso: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction getExpiryStatus(expiresAt: string | null): \"expired\" | \"expiring-soon\" | \"ok\" | \"never\" {\n if (!expiresAt) return \"never\";\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return \"expired\";\n if (diff < 7 * 24 * 60 * 60 * 1000) return \"expiring-soon\";\n return \"ok\";\n}\n\nfunction ApiKeysTable({\n keys,\n onToggleActive,\n isTogglingId,\n}: {\n keys: ApiKeyRecord[];\n onToggleActive: (key: ApiKeyRecord) => void;\n isTogglingId: string | null;\n}) {\n if (keys.length === 0) {\n return (\n <div\n className=\"flex flex-column align-items-center justify-content-center gap-3 py-6\"\n style={{ color: \"var(--solid-text-secondary, #888)\" }}\n >\n <KeyRound size={32} strokeWidth={1.5} />\n <div className=\"text-center\">\n <p className=\"m-0\" style={{ fontSize: 14, fontWeight: 500 }}>\n No API keys\n </p>\n <p className=\"m-0 mt-1\" style={{ fontSize: 12 }}>\n Generate a key to enable programmatic access.\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div style={{ overflowX: \"auto\" }}>\n <table style={{ width: \"100%\", borderCollapse: \"collapse\", tableLayout: \"fixed\" }}>\n <colgroup>\n <col style={{ width: \"18%\" }} />\n <col style={{ width: \"22%\" }} />\n <col style={{ width: \"14%\" }} />\n <col style={{ width: \"16%\" }} />\n <col style={{ width: \"18%\" }} />\n <col style={{ width: \"12%\" }} />\n </colgroup>\n <thead>\n <tr>\n <th className=\"solid-api-keys-th\">Name</th>\n <th className=\"solid-api-keys-th\">Key</th>\n <th className=\"solid-api-keys-th\">Status</th>\n <th className=\"solid-api-keys-th\">Expires</th>\n <th className=\"solid-api-keys-th\">Last Used</th>\n <th className=\"solid-api-keys-th\" style={{ textAlign: \"right\" }}>Active</th>\n </tr>\n </thead>\n <tbody>\n {keys.map((key) => {\n const expiryStatus = getExpiryStatus(key.expiresAt);\n const isExpired = expiryStatus === \"expired\";\n\n return (\n <tr key={key.id} className={isExpired ? \"solid-api-keys-row--expired\" : undefined}>\n <td className=\"solid-api-keys-td\">\n <span style={{ fontWeight: 500 }}>{key.name}</span>\n </td>\n\n <td className=\"solid-api-keys-td\">\n <code\n style={{\n fontFamily: \"monospace\",\n fontSize: 13,\n background: \"var(--solid-surface-secondary, #f5f5f5)\",\n padding: \"2px 6px\",\n borderRadius: 4,\n }}\n >\n {key.maskedKey}\n </code>\n </td>\n\n <td className=\"solid-api-keys-td\">\n {isExpired ? (\n <SolidTag tone=\"danger\">Expired</SolidTag>\n ) : !key.isActive ? (\n <SolidTag tone=\"warn\">Inactive</SolidTag>\n ) : expiryStatus === \"expiring-soon\" ? (\n <SolidTag tone=\"warn\">Expiring soon</SolidTag>\n ) : (\n <SolidTag tone=\"success\">Active</SolidTag>\n )}\n </td>\n\n <td\n className=\"solid-api-keys-td\"\n style={{\n color:\n expiryStatus === \"expired\"\n ? \"var(--solid-danger-color, #ef4444)\"\n : expiryStatus === \"expiring-soon\"\n ? \"var(--solid-warn-color, #f59e0b)\"\n : undefined,\n }}\n >\n {expiryStatus === \"never\" ? (\n <span style={{ color: \"var(--solid-text-secondary, #888)\" }}>Never</span>\n ) : (\n formatDate(key.expiresAt)\n )}\n </td>\n\n <td className=\"solid-api-keys-td\" style={{ color: \"var(--solid-text-secondary, #888)\" }}>\n {formatDate(key.lastUsedAt)}\n </td>\n\n <td className=\"solid-api-keys-td\" style={{ textAlign: \"right\" }}>\n {isTogglingId === key.id ? (\n <SolidSpinner />\n ) : (\n <SolidSwitch\n checked={key.isActive}\n disabled={isExpired}\n onChange={() => onToggleActive(key)}\n />\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\ninterface ApiKeysTabProps {\n userId: string;\n canCreate?: boolean;\n}\n\nexport function ApiKeysTab({ userId, canCreate = false }: ApiKeysTabProps) {\n const dispatch = useDispatch();\n const { data, isLoading, isError } = useGetUserApiKeysQuery(userId);\n const [updateApiKey] = useUpdateApiKeyMutation();\n const [togglingId, setTogglingId] = useState<string | null>(null);\n const [showGenerate, setShowGenerate] = useState(false);\n const [revealKey, setRevealKey] = useState<{ apiKey: string; keyName: string } | null>(null);\n\n const keys: ApiKeyRecord[] = data?.data?.apiKeys ?? [];\n\n const handleToggle = async (key: ApiKeyRecord) => {\n setTogglingId(key.id);\n try {\n await updateApiKey({ id: key.id, isActive: !key.isActive }).unwrap();\n dispatch(\n showToast({\n severity: \"success\",\n summary: \"Updated\",\n detail: `API key \"${key.name}\" ${!key.isActive ? \"activated\" : \"deactivated\"}.`,\n })\n );\n } catch (err: any) {\n dispatch(\n showToast({\n severity: \"error\",\n summary: \"Error\",\n detail: err?.data?.message || \"Failed to update API key.\",\n })\n );\n } finally {\n setTogglingId(null);\n }\n };\n\n return (\n <>\n <div className=\"solid-api-keys-tab\">\n <div className=\"flex align-items-center justify-content-between mb-4\">\n <div>\n <p className=\"m-0\" style={{ fontWeight: 600, fontSize: 14 }}>\n API Keys\n </p>\n <p className=\"m-0 mt-1\" style={{ fontSize: 12, color: \"var(--solid-text-secondary, #888)\" }}>\n Keys grant programmatic access. Store them securely — they are shown only once.\n </p>\n </div>\n {canCreate && (\n <SolidButton size=\"small\" type=\"button\" onClick={() => setShowGenerate(true)}>\n <Plus size={14} />\n Generate Key\n </SolidButton>\n )}\n </div>\n\n {isLoading ? (\n <div className=\"flex justify-content-center py-5\">\n <SolidSpinner />\n </div>\n ) : isError && keys.length === 0 ? (\n <div\n className=\"flex flex-column align-items-center justify-content-center gap-2 py-5\"\n style={{ color: \"var(--solid-text-secondary, #888)\", fontSize: 13 }}\n >\n <p className=\"m-0\">Something went wrong while loading API keys.</p>\n <p className=\"m-0\">Please refresh the page and try again.</p>\n </div>\n ) : (\n <ApiKeysTable keys={keys} onToggleActive={handleToggle} isTogglingId={togglingId} />\n )}\n </div>\n\n <GenerateApiKeyModal\n open={showGenerate}\n userId={Number(userId)}\n onClose={() => setShowGenerate(false)}\n onCreated={(apiKey, keyName) => {\n setShowGenerate(false);\n setRevealKey({ apiKey, keyName });\n }}\n />\n\n {revealKey && (\n <RevealApiKeyModal\n open={true}\n apiKey={revealKey.apiKey}\n keyName={revealKey.keyName}\n onClose={() => setRevealKey(null)}\n />\n )}\n </>\n );\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import { useDispatch } from "react-redux";
|
|
3
3
|
import { KeyRound, Plus } from "lucide-react";
|
|
4
|
+
import "./ApiKeysTab.css";
|
|
4
5
|
import { SolidButton, SolidSpinner, SolidSwitch, SolidTag } from "../../../shad-cn-ui";
|
|
5
6
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
6
7
|
import {
|
|
@@ -58,7 +59,15 @@ function ApiKeysTable({
|
|
|
58
59
|
|
|
59
60
|
return (
|
|
60
61
|
<div style={{ overflowX: "auto" }}>
|
|
61
|
-
<table style={{ width: "100%", borderCollapse: "collapse" }}>
|
|
62
|
+
<table style={{ width: "100%", borderCollapse: "collapse", tableLayout: "fixed" }}>
|
|
63
|
+
<colgroup>
|
|
64
|
+
<col style={{ width: "18%" }} />
|
|
65
|
+
<col style={{ width: "22%" }} />
|
|
66
|
+
<col style={{ width: "14%" }} />
|
|
67
|
+
<col style={{ width: "16%" }} />
|
|
68
|
+
<col style={{ width: "18%" }} />
|
|
69
|
+
<col style={{ width: "12%" }} />
|
|
70
|
+
</colgroup>
|
|
62
71
|
<thead>
|
|
63
72
|
<tr>
|
|
64
73
|
<th className="solid-api-keys-th">Name</th>
|
|
@@ -66,7 +75,7 @@ function ApiKeysTable({
|
|
|
66
75
|
<th className="solid-api-keys-th">Status</th>
|
|
67
76
|
<th className="solid-api-keys-th">Expires</th>
|
|
68
77
|
<th className="solid-api-keys-th">Last Used</th>
|
|
69
|
-
<th className="solid-api-keys-th">Active</th>
|
|
78
|
+
<th className="solid-api-keys-th" style={{ textAlign: "right" }}>Active</th>
|
|
70
79
|
</tr>
|
|
71
80
|
</thead>
|
|
72
81
|
<tbody>
|
|
@@ -128,7 +137,7 @@ function ApiKeysTable({
|
|
|
128
137
|
{formatDate(key.lastUsedAt)}
|
|
129
138
|
</td>
|
|
130
139
|
|
|
131
|
-
<td className="solid-api-keys-td">
|
|
140
|
+
<td className="solid-api-keys-td" style={{ textAlign: "right" }}>
|
|
132
141
|
{isTogglingId === key.id ? (
|
|
133
142
|
<SolidSpinner />
|
|
134
143
|
) : (
|
|
@@ -226,6 +235,7 @@ export function ApiKeysTab({ userId, canCreate = false }: ApiKeysTabProps) {
|
|
|
226
235
|
|
|
227
236
|
<GenerateApiKeyModal
|
|
228
237
|
open={showGenerate}
|
|
238
|
+
userId={Number(userId)}
|
|
229
239
|
onClose={() => setShowGenerate(false)}
|
|
230
240
|
onCreated={(apiKey, keyName) => {
|
|
231
241
|
setShowGenerate(false);
|
|
@@ -2,7 +2,8 @@ interface GenerateApiKeyModalProps {
|
|
|
2
2
|
open: boolean;
|
|
3
3
|
onClose: () => void;
|
|
4
4
|
onCreated: (rawApiKey: string, keyName: string) => void;
|
|
5
|
+
userId?: number;
|
|
5
6
|
}
|
|
6
|
-
export declare function GenerateApiKeyModal({ open, onClose, onCreated }: GenerateApiKeyModalProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function GenerateApiKeyModal({ open, onClose, onCreated, userId }: GenerateApiKeyModalProps): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=GenerateApiKeyModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenerateApiKeyModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/GenerateApiKeyModal.tsx"],"names":[],"mappings":"AAmDA,UAAU,wBAAwB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"GenerateApiKeyModal.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/users/ApiKeysTab/GenerateApiKeyModal.tsx"],"names":[],"mappings":"AAmDA,UAAU,wBAAwB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CA4HjG"}
|
|
@@ -52,7 +52,7 @@ import { useFormik } from "formik";
|
|
|
52
52
|
import * as Yup from "yup";
|
|
53
53
|
import { SolidButton, SolidDatePicker, SolidDialog, SolidDialogBody, SolidDialogFooter, SolidDialogHeader, SolidDialogSeparator, SolidDialogTitle, SolidInput, SolidMessage, SolidSelect, } from "../../../shad-cn-ui";
|
|
54
54
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
55
|
-
import {
|
|
55
|
+
import { useGenerateApiKeyForUserMutation } from "../../../../redux/api/apiKeyApi";
|
|
56
56
|
var EXPIRY_OPTIONS = [
|
|
57
57
|
{ label: "30 days", value: "30d" },
|
|
58
58
|
{ label: "60 days", value: "60d" },
|
|
@@ -83,9 +83,9 @@ function resolveExpiresAt(expiryOption, customDate) {
|
|
|
83
83
|
}
|
|
84
84
|
export function GenerateApiKeyModal(_a) {
|
|
85
85
|
var _this = this;
|
|
86
|
-
var open = _a.open, onClose = _a.onClose, onCreated = _a.onCreated;
|
|
86
|
+
var open = _a.open, onClose = _a.onClose, onCreated = _a.onCreated, userId = _a.userId;
|
|
87
87
|
var dispatch = useDispatch();
|
|
88
|
-
var _b =
|
|
88
|
+
var _b = useGenerateApiKeyForUserMutation(), generateApiKeyForUser = _b[0], isLoading = _b[1].isLoading;
|
|
89
89
|
var _c = useState(null), customDate = _c[0], setCustomDate = _c[1];
|
|
90
90
|
var formik = useFormik({
|
|
91
91
|
initialValues: {
|
|
@@ -101,7 +101,7 @@ export function GenerateApiKeyModal(_a) {
|
|
|
101
101
|
expiryOption: Yup.string().required("Expiry is required"),
|
|
102
102
|
}),
|
|
103
103
|
onSubmit: function (values, helpers) { return __awaiter(_this, void 0, void 0, function () {
|
|
104
|
-
var expiresAt, response, err_1, detail;
|
|
104
|
+
var expiresAt, body, response, err_1, detail;
|
|
105
105
|
var _a;
|
|
106
106
|
return __generator(this, function (_b) {
|
|
107
107
|
switch (_b.label) {
|
|
@@ -114,7 +114,8 @@ export function GenerateApiKeyModal(_a) {
|
|
|
114
114
|
_b.label = 1;
|
|
115
115
|
case 1:
|
|
116
116
|
_b.trys.push([1, 3, , 4]);
|
|
117
|
-
|
|
117
|
+
body = __assign({ name: values.name.trim() }, (expiresAt ? { expiresAt: expiresAt } : {}));
|
|
118
|
+
return [4 /*yield*/, generateApiKeyForUser({ userId: userId, body: body }).unwrap()];
|
|
118
119
|
case 2:
|
|
119
120
|
response = _b.sent();
|
|
120
121
|
onCreated(response.data.apiKey, values.name.trim());
|
|
@@ -1 +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"]}
|
|
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 { useGenerateApiKeyForUserMutation } 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 userId?: number;\n}\n\nexport function GenerateApiKeyModal({ open, onClose, onCreated, userId }: GenerateApiKeyModalProps) {\n const dispatch = useDispatch();\n const [generateApiKeyForUser, { isLoading }] = useGenerateApiKeyForUserMutation();\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 body = { name: values.name.trim(), ...(expiresAt ? { expiresAt } : {}) };\n const response = await generateApiKeyForUser({ userId: userId!, body }).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"]}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
SolidSelect,
|
|
17
17
|
} from "../../../shad-cn-ui";
|
|
18
18
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
19
|
-
import {
|
|
19
|
+
import { useGenerateApiKeyForUserMutation } from "../../../../redux/api/apiKeyApi";
|
|
20
20
|
|
|
21
21
|
const EXPIRY_OPTIONS = [
|
|
22
22
|
{ label: "30 days", value: "30d" },
|
|
@@ -53,11 +53,12 @@ interface GenerateApiKeyModalProps {
|
|
|
53
53
|
open: boolean;
|
|
54
54
|
onClose: () => void;
|
|
55
55
|
onCreated: (rawApiKey: string, keyName: string) => void;
|
|
56
|
+
userId?: number;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
export function GenerateApiKeyModal({ open, onClose, onCreated }: GenerateApiKeyModalProps) {
|
|
59
|
+
export function GenerateApiKeyModal({ open, onClose, onCreated, userId }: GenerateApiKeyModalProps) {
|
|
59
60
|
const dispatch = useDispatch();
|
|
60
|
-
const [
|
|
61
|
+
const [generateApiKeyForUser, { isLoading }] = useGenerateApiKeyForUserMutation();
|
|
61
62
|
const [customDate, setCustomDate] = useState<Date | null>(null);
|
|
62
63
|
|
|
63
64
|
const formik = useFormik({
|
|
@@ -82,10 +83,8 @@ export function GenerateApiKeyModal({ open, onClose, onCreated }: GenerateApiKey
|
|
|
82
83
|
const expiresAt = resolveExpiresAt(values.expiryOption, customDate);
|
|
83
84
|
|
|
84
85
|
try {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
...(expiresAt ? { expiresAt } : {}),
|
|
88
|
-
}).unwrap();
|
|
86
|
+
const body = { name: values.name.trim(), ...(expiresAt ? { expiresAt } : {}) };
|
|
87
|
+
const response = await generateApiKeyForUser({ userId: userId!, body }).unwrap();
|
|
89
88
|
|
|
90
89
|
onCreated(response.data.apiKey, values.name.trim());
|
|
91
90
|
handleClose();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateUser.d.ts","sourceRoot":"","sources":["../../../../src/components/core/users/CreateUser.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CreateUser.d.ts","sourceRoot":"","sources":["../../../../src/components/core/users/CreateUser.tsx"],"names":[],"mappings":"AAoCA,QAAA,MAAM,UAAU,qBAAsB,GAAG,4CAyQxC,CAAC;AAiMF,eAAe,UAAU,CAAC"}
|
|
@@ -57,7 +57,8 @@ import { useRegisterPrivateMutation, useUpdateUserMutation } from "../../../redu
|
|
|
57
57
|
import { useGetrolesQuery } from "../../../redux/api/roleApi";
|
|
58
58
|
import { useDeleteUserMutation } from "../../../redux/api/userApi";
|
|
59
59
|
import { showToast } from "../../../redux/features/toastSlice";
|
|
60
|
-
import { SolidButton, SolidCheckbox, SolidInput, SolidMessage, SolidPanel, SolidPasswordInput, } from "../../shad-cn-ui";
|
|
60
|
+
import { SolidButton, SolidCheckbox, SolidInput, SolidMessage, SolidPanel, SolidPasswordInput, SolidSwitch, SolidTabGroup, } from "../../shad-cn-ui";
|
|
61
|
+
import { ApiKeysTab, GenerateApiKeyModal, RevealApiKeyModal } from "./ApiKeysTab";
|
|
61
62
|
function cx() {
|
|
62
63
|
var parts = [];
|
|
63
64
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
@@ -71,9 +72,12 @@ var CreateUser = function (_a) {
|
|
|
71
72
|
var dispatch = useDispatch();
|
|
72
73
|
var router = useRouter();
|
|
73
74
|
var _j = useState([]), selectedRoles = _j[0], setSelectedRoles = _j[1];
|
|
74
|
-
var _k =
|
|
75
|
-
var
|
|
76
|
-
var
|
|
75
|
+
var _k = useState("userDetails"), activeTab = _k[0], setActiveTab = _k[1];
|
|
76
|
+
var _l = useState(null), newUserIdForApiKey = _l[0], setNewUserIdForApiKey = _l[1];
|
|
77
|
+
var _m = useState(null), revealKey = _m[0], setRevealKey = _m[1];
|
|
78
|
+
var _o = useRegisterPrivateMutation(), registerPrivate = _o[0], _p = _o[1], isLoading = _p.isLoading, userCreateError = _p.error;
|
|
79
|
+
var _q = useUpdateUserMutation(), updateUser = _q[0], _r = _q[1], isUserUpdating = _r.isLoading, isUpdateUserSuccess = _r.isSuccess, userUpdateError = _r.error;
|
|
80
|
+
var _s = useDeleteUserMutation(), deleteUser = _s[0], _t = _s[1], isUserDeleting = _t.isLoading, isDeleteUserSuccess = _t.isSuccess;
|
|
77
81
|
var rolesData = useGetrolesQuery("").data;
|
|
78
82
|
useEffect(function () {
|
|
79
83
|
if (data === null || data === void 0 ? void 0 : data.roles) {
|
|
@@ -88,6 +92,7 @@ var CreateUser = function (_a) {
|
|
|
88
92
|
password: "",
|
|
89
93
|
confirmPassword: "",
|
|
90
94
|
failedLoginAttempts: (_f = data === null || data === void 0 ? void 0 : data.failedLoginAttempts) !== null && _f !== void 0 ? _f : 0,
|
|
95
|
+
isAllowedToGenerateApiKeys: (_g = data === null || data === void 0 ? void 0 : data.isAllowedToGenerateApiKeys) !== null && _g !== void 0 ? _g : false,
|
|
91
96
|
};
|
|
92
97
|
var validationSchema = Yup.object({
|
|
93
98
|
fullName: Yup.string().required(ERROR_MESSAGES.FIELD_REUQIRED("Full Name")),
|
|
@@ -115,33 +120,56 @@ var CreateUser = function (_a) {
|
|
|
115
120
|
validationSchema: validationSchema,
|
|
116
121
|
enableReinitialize: true,
|
|
117
122
|
onSubmit: function (values) { return __awaiter(void 0, void 0, void 0, function () {
|
|
118
|
-
var userData;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
123
|
+
var userData, response, userId, _a;
|
|
124
|
+
var _b, _c;
|
|
125
|
+
return __generator(this, function (_d) {
|
|
126
|
+
switch (_d.label) {
|
|
127
|
+
case 0:
|
|
128
|
+
if (data) {
|
|
129
|
+
userData = {
|
|
130
|
+
fullName: values.fullName,
|
|
131
|
+
username: values.username,
|
|
132
|
+
email: values.email,
|
|
133
|
+
mobile: values.mobile,
|
|
134
|
+
roles: selectedRoles,
|
|
135
|
+
failedLoginAttempts: values.failedLoginAttempts,
|
|
136
|
+
isAllowedToGenerateApiKeys: values.isAllowedToGenerateApiKeys,
|
|
137
|
+
};
|
|
138
|
+
if (values.password) {
|
|
139
|
+
userData.password = values.password;
|
|
140
|
+
}
|
|
141
|
+
updateUser({ id: data.id, data: userData });
|
|
142
|
+
return [2 /*return*/];
|
|
143
|
+
}
|
|
144
|
+
_d.label = 1;
|
|
145
|
+
case 1:
|
|
146
|
+
_d.trys.push([1, 3, , 4]);
|
|
147
|
+
return [4 /*yield*/, registerPrivate({
|
|
148
|
+
fullName: values.fullName,
|
|
149
|
+
username: values.username,
|
|
150
|
+
email: values.email,
|
|
151
|
+
mobile: values.mobile,
|
|
152
|
+
password: values.password,
|
|
153
|
+
roles: selectedRoles,
|
|
154
|
+
failedLoginAttempts: values.failedLoginAttempts,
|
|
155
|
+
isAllowedToGenerateApiKeys: values.isAllowedToGenerateApiKeys,
|
|
156
|
+
}).unwrap()];
|
|
157
|
+
case 2:
|
|
158
|
+
response = _d.sent();
|
|
159
|
+
if (values.isAllowedToGenerateApiKeys) {
|
|
160
|
+
userId = (_c = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : response === null || response === void 0 ? void 0 : response.id;
|
|
161
|
+
if (userId) {
|
|
162
|
+
setNewUserIdForApiKey(userId);
|
|
163
|
+
return [2 /*return*/];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
router.back();
|
|
167
|
+
return [3 /*break*/, 4];
|
|
168
|
+
case 3:
|
|
169
|
+
_a = _d.sent();
|
|
170
|
+
return [3 /*break*/, 4];
|
|
171
|
+
case 4: return [2 /*return*/];
|
|
134
172
|
}
|
|
135
|
-
registerPrivate({
|
|
136
|
-
fullName: values.fullName,
|
|
137
|
-
username: values.username,
|
|
138
|
-
email: values.email,
|
|
139
|
-
mobile: values.mobile,
|
|
140
|
-
password: values.password,
|
|
141
|
-
roles: selectedRoles,
|
|
142
|
-
failedLoginAttempts: values.failedLoginAttempts,
|
|
143
|
-
});
|
|
144
|
-
return [2 /*return*/];
|
|
145
173
|
});
|
|
146
174
|
}); },
|
|
147
175
|
});
|
|
@@ -174,15 +202,41 @@ var CreateUser = function (_a) {
|
|
|
174
202
|
handleError(userUpdateError);
|
|
175
203
|
}, [dispatch, userCreateError, userUpdateError]);
|
|
176
204
|
useEffect(function () {
|
|
177
|
-
if (
|
|
205
|
+
if (isDeleteUserSuccess || isUpdateUserSuccess) {
|
|
178
206
|
router.back();
|
|
179
207
|
}
|
|
180
|
-
}, [isDeleteUserSuccess,
|
|
208
|
+
}, [isDeleteUserSuccess, isUpdateUserSuccess, router]);
|
|
181
209
|
var isEditMode = params.id !== "new";
|
|
182
210
|
var isSaving = isLoading || isUserUpdating;
|
|
183
|
-
return (
|
|
184
|
-
|
|
185
|
-
|
|
211
|
+
return (_jsxs("div", { className: "solid-form-wrapper", children: [_jsx("div", { className: "solid-form-section", children: _jsxs("form", { onSubmit: formik.handleSubmit, children: [_jsxs("div", { className: "solid-form-header flex align-items-center justify-content-between gap-3 flex-wrap", children: [_jsxs("div", { className: "solid-user-form-titleblock flex align-items-center gap-3", children: [_jsx(BackButton, {}), _jsxs("div", { children: [_jsx("div", { className: "form-wrapper-title", children: isEditMode ? "Update User" : "Create User" }), _jsx("p", { className: "solid-user-form-subtitle m-0", children: isEditMode
|
|
212
|
+
? "Update account details, access roles, and security controls."
|
|
213
|
+
: "Create a user account and assign the right access roles." })] })] }), _jsxs("div", { className: "gap-3 flex flex-wrap", children: [formik.dirty ? (_jsx(SolidButton, { size: "small", type: "submit", loading: isSaving, children: "Save" })) : null, data ? (_jsx(SolidButton, { size: "small", type: "button", variant: "destructive", loading: isUserDeleting, onClick: function () { return deleteUser(data.id); }, children: "Delete" })) : null, _jsx(CancelButton, {})] })] }), _jsx(SolidFormHeader, {}), _jsx("div", { className: "px-4 py-3 md:p-4 solid-form-content", children: isEditMode ? (_jsx(SolidTabGroup, { value: activeTab, onValueChange: setActiveTab, tabs: [
|
|
214
|
+
{
|
|
215
|
+
value: "userDetails",
|
|
216
|
+
label: "User Details",
|
|
217
|
+
content: _jsx(UserDetailsContent, { formik: formik, fieldError: fieldError, rolesData: rolesData, selectedRoles: selectedRoles, handleCheckboxChange: handleCheckboxChange, isEditMode: isEditMode }),
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
value: "apiKeys",
|
|
221
|
+
label: "API Keys",
|
|
222
|
+
content: _jsx("div", { className: "pt-4", children: _jsx(ApiKeysTab, { userId: data === null || data === void 0 ? void 0 : data.id, canCreate: (_h = data === null || data === void 0 ? void 0 : data.isAllowedToGenerateApiKeys) !== null && _h !== void 0 ? _h : false }) }),
|
|
223
|
+
},
|
|
224
|
+
] })) : (_jsx(UserDetailsContent, { formik: formik, fieldError: fieldError, rolesData: rolesData, selectedRoles: selectedRoles, handleCheckboxChange: handleCheckboxChange, isEditMode: isEditMode })) })] }) }), newUserIdForApiKey !== null && (_jsx(GenerateApiKeyModal, { open: true, userId: newUserIdForApiKey, onClose: function () {
|
|
225
|
+
setNewUserIdForApiKey(null);
|
|
226
|
+
router.back();
|
|
227
|
+
}, onCreated: function (apiKey, keyName) {
|
|
228
|
+
setNewUserIdForApiKey(null);
|
|
229
|
+
setRevealKey({ apiKey: apiKey, keyName: keyName });
|
|
230
|
+
} })), revealKey && (_jsx(RevealApiKeyModal, { open: true, apiKey: revealKey.apiKey, keyName: revealKey.keyName, onClose: function () {
|
|
231
|
+
setRevealKey(null);
|
|
232
|
+
router.back();
|
|
233
|
+
} }))] }));
|
|
186
234
|
};
|
|
235
|
+
/** Extracted form body so it can be used both inside and outside the tab wrapper */
|
|
236
|
+
function UserDetailsContent(_a) {
|
|
237
|
+
var _b, _c;
|
|
238
|
+
var formik = _a.formik, fieldError = _a.fieldError, rolesData = _a.rolesData, selectedRoles = _a.selectedRoles, handleCheckboxChange = _a.handleCheckboxChange, isEditMode = _a.isEditMode;
|
|
239
|
+
return (_jsx("div", { className: "grid", children: _jsxs("div", { className: "col-12 lg:col-10 xl:col-8 mx-auto", children: [_jsx(SolidPanel, { header: "Basic Info", className: "solid-column-panel solid-user-form-panel", children: _jsxs("div", { className: "grid formgrid", children: [_jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2", children: [_jsx("label", { htmlFor: "fullName", className: "form-field-label", children: "Full Name" }), _jsx(SolidInput, { type: "text", id: "fullName", name: "fullName", autoComplete: "off", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.fullName, className: cx(fieldError("fullName") && "solid-user-form-input-invalid") }), fieldError("fullName") ? _jsx(SolidMessage, { severity: "error", text: fieldError("fullName") }) : null] }), _jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2", children: [_jsx("label", { htmlFor: "username", className: "form-field-label", children: "Username" }), _jsx(SolidInput, { type: "text", id: "username", name: "username", autoComplete: "off", disabled: Boolean(formik.values.username) && isEditMode, onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.username, className: cx(fieldError("username") && "solid-user-form-input-invalid") }), fieldError("username") ? _jsx(SolidMessage, { severity: "error", text: fieldError("username") }) : null] }), _jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2 mt-3", children: [_jsx("label", { htmlFor: "email", className: "form-field-label", children: "Email" }), _jsx(SolidInput, { type: "email", id: "email", name: "email", autoComplete: "off", disabled: isEditMode, onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.email, className: cx(fieldError("email") && "solid-user-form-input-invalid") }), fieldError("email") ? _jsx(SolidMessage, { severity: "error", text: fieldError("email") }) : null] }), _jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2 mt-3", children: [_jsx("label", { htmlFor: "mobile", className: "form-field-label", children: "Mobile" }), _jsx(SolidInput, { type: "text", id: "mobile", name: "mobile", autoComplete: "off", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.mobile, className: cx(fieldError("mobile") && "solid-user-form-input-invalid") }), fieldError("mobile") ? _jsx(SolidMessage, { severity: "error", text: fieldError("mobile") }) : null] }), !isEditMode ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2 mt-3", children: [_jsx("label", { htmlFor: "password", className: "form-field-label", children: "Password" }), _jsx(SolidPasswordInput, { id: "password", name: "password", autoComplete: "off", value: formik.values.password, onChange: formik.handleChange, onBlur: formik.handleBlur, className: cx(fieldError("password") && "solid-user-form-input-invalid") }), fieldError("password") ? _jsx(SolidMessage, { severity: "error", text: fieldError("password") }) : null] }), _jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2 mt-3", children: [_jsx("label", { htmlFor: "confirmPassword", className: "form-field-label", children: "Confirm Password" }), _jsx(SolidPasswordInput, { id: "confirmPassword", name: "confirmPassword", autoComplete: "off", value: formik.values.confirmPassword, onChange: formik.handleChange, onBlur: formik.handleBlur, className: cx(fieldError("confirmPassword") && "solid-user-form-input-invalid") }), fieldError("confirmPassword") ? (_jsx(SolidMessage, { severity: "error", text: fieldError("confirmPassword") })) : null] })] })) : (_jsxs("div", { className: "field col-12 md:col-6 flex flex-column gap-2 mt-3", children: [_jsx("label", { htmlFor: "failedLoginAttempts", className: "form-field-label", children: "Failed Login Attempts" }), _jsx(SolidInput, { type: "number", id: "failedLoginAttempts", name: "failedLoginAttempts", autoComplete: "off", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.failedLoginAttempts, className: cx(fieldError("failedLoginAttempts") && "solid-user-form-input-invalid") }), fieldError("failedLoginAttempts") ? (_jsx(SolidMessage, { severity: "error", text: fieldError("failedLoginAttempts") })) : null, _jsx("p", { className: "solid-user-form-helper", children: "Your account has been locked due to repeated unsuccessful login attempts. Please contact your system admin." })] }))] }) }), _jsx(SolidPanel, { toggleable: true, header: "Access", className: "solid-column-panel solid-user-form-panel mt-5", children: _jsx("div", { className: "formgrid grid", children: _jsxs("div", { className: "field col-12 flex align-items-center justify-content-between gap-3", children: [_jsxs("div", { children: [_jsx("p", { className: "form-field-label m-0", children: "Allow API Key Generation" }), _jsx("p", { className: "solid-user-form-helper m-0 mt-1", children: "When enabled, this user can generate API keys for programmatic access." })] }), _jsx(SolidSwitch, { checked: formik.values.isAllowedToGenerateApiKeys, onChange: function (checked) { return formik.setFieldValue("isAllowedToGenerateApiKeys", checked); } })] }) }) }), _jsxs(SolidPanel, { toggleable: true, header: "Roles", className: "solid-column-panel solid-user-form-panel mt-5", children: [_jsx("p", { className: "solid-user-form-panel-copy", children: "Select the roles that should be assigned to this user." }), _jsx("div", { className: "formgrid grid solid-user-role-grid", children: (_c = (_b = rolesData === null || rolesData === void 0 ? void 0 : rolesData.data) === null || _b === void 0 ? void 0 : _b.records) === null || _c === void 0 ? void 0 : _c.map(function (role) { return (_jsx("div", { className: "field col-12 md:col-6 solid-user-role-item", children: _jsx(SolidCheckbox, { id: role.name, checked: selectedRoles.includes(role.name), onChange: function () { return handleCheckboxChange(role.name); }, label: role.name }) }, role.name)); }) })] })] }) }));
|
|
240
|
+
}
|
|
187
241
|
export default CreateUser;
|
|
188
242
|
//# sourceMappingURL=CreateUser.js.map
|