@cobaltcore-dev/aurora 0.20.0 → 0.20.2

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 (62) hide show
  1. package/dist/client/{ContentHeader-BIScbvb4.mjs → ContentHeader-CIAzorGI.mjs} +2 -3
  2. package/dist/client/{ContentHeader-BIScbvb4.mjs.map → ContentHeader-CIAzorGI.mjs.map} +1 -1
  3. package/dist/client/{_flavorId-sS1sg_DZ.mjs → _flavorId-BMX239RH.mjs} +3 -3
  4. package/dist/client/{_flavorId-sS1sg_DZ.mjs.map → _flavorId-BMX239RH.mjs.map} +1 -1
  5. package/dist/client/{_flavorId-BQY7YhNx.mjs → _flavorId-BaNJ1CDY.mjs} +2 -2
  6. package/dist/client/{_flavorId-BQY7YhNx.mjs.map → _flavorId-BaNJ1CDY.mjs.map} +1 -1
  7. package/dist/client/{_floatingIpId-DFCaWI9K.mjs → _floatingIpId-DQFtZNeg.mjs} +2 -2
  8. package/dist/client/{_floatingIpId-DFCaWI9K.mjs.map → _floatingIpId-DQFtZNeg.mjs.map} +1 -1
  9. package/dist/client/{_floatingIpId-De0hCSSN2.mjs → _floatingIpId-E6x99cmW.mjs} +2 -2
  10. package/dist/client/_floatingIpId-E6x99cmW.mjs.map +1 -0
  11. package/dist/client/{_imageId-D8HiDS3P.mjs → _imageId-C2662dZr.mjs} +2 -2
  12. package/dist/client/{_imageId-D8HiDS3P.mjs.map → _imageId-C2662dZr.mjs.map} +1 -1
  13. package/dist/client/{_projectId-b4NGeECR.mjs → _projectId-B4ScifQf.mjs} +7 -7
  14. package/dist/client/_projectId-B4ScifQf.mjs.map +1 -0
  15. package/dist/client/{_projectId-D8FHe0gr.mjs → _projectId-CYq4KZXB.mjs} +3 -3
  16. package/dist/client/{_projectId-D8FHe0gr.mjs.map → _projectId-CYq4KZXB.mjs.map} +1 -1
  17. package/dist/client/{_projectId-Cq9JnhRj.mjs → _projectId-DJLjspKf.mjs} +24 -25
  18. package/dist/client/_projectId-DJLjspKf.mjs.map +1 -0
  19. package/dist/client/{_projectId-Ig3QqYzt.mjs → _projectId-DxgPaiA7.mjs} +2 -2
  20. package/dist/client/_projectId-DxgPaiA7.mjs.map +1 -0
  21. package/dist/client/{_storageType-CH2khFcZ.mjs → _storageType-DsbBodWF.mjs} +2 -2
  22. package/dist/client/{_storageType-CH2khFcZ.mjs.map → _storageType-DsbBodWF.mjs.map} +1 -1
  23. package/dist/client/{_storageType-D-1H6SX1.mjs → _storageType-WwAATdsa.mjs} +886 -886
  24. package/dist/client/{_storageType-D-1H6SX1.mjs.map → _storageType-WwAATdsa.mjs.map} +1 -1
  25. package/dist/client/{flavors-D5aTQJT1.mjs → flavors-Bwjig3k2.mjs} +3 -3
  26. package/dist/client/{flavors-D5aTQJT1.mjs.map → flavors-Bwjig3k2.mjs.map} +1 -1
  27. package/dist/client/{flavors-TqwbWt4R.mjs → flavors-C7PVJUqZ.mjs} +2 -2
  28. package/dist/client/{flavors-TqwbWt4R.mjs.map → flavors-C7PVJUqZ.mjs.map} +1 -1
  29. package/dist/client/{images-sNuJa6ce.mjs → images-CD7DNwru.mjs} +2 -2
  30. package/dist/client/{images-sNuJa6ce.mjs.map → images-CD7DNwru.mjs.map} +1 -1
  31. package/dist/client/{images-CkW8zNjs.mjs → images-CfBrglGJ.mjs} +9 -9
  32. package/dist/client/{images-CkW8zNjs.mjs.map → images-CfBrglGJ.mjs.map} +1 -1
  33. package/dist/client/index.js +454 -317
  34. package/dist/client/index.js.map +1 -1
  35. package/dist/client/{objects-B3Z8h4RU.mjs → objects-CEBrL7k-.mjs} +2 -2
  36. package/dist/client/{objects-B3Z8h4RU.mjs.map → objects-CEBrL7k-.mjs.map} +1 -1
  37. package/dist/client/{objects-CGOfO00N.mjs → objects-DvIxpzGI.mjs} +3 -3
  38. package/dist/client/{objects-CGOfO00N.mjs.map → objects-DvIxpzGI.mjs.map} +1 -1
  39. package/dist/client/{pca-BClYQElh.mjs → pca-CpMqoF00.mjs} +3 -3
  40. package/dist/client/{pca-BClYQElh.mjs.map → pca-CpMqoF00.mjs.map} +1 -1
  41. package/dist/client/{pca-B4_2DqT2.mjs → pca-ZgGU0UPF.mjs} +2 -2
  42. package/dist/client/{pca-B4_2DqT2.mjs.map → pca-ZgGU0UPF.mjs.map} +1 -1
  43. package/dist/client/projects-DvSiI5Vg.mjs.map +1 -1
  44. package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
  45. package/dist/client/routeInfo-Ct5r4Gen.mjs +56 -0
  46. package/dist/client/routeInfo-Ct5r4Gen.mjs.map +1 -0
  47. package/dist/client/trpcClient.d.ts +37 -0
  48. package/dist/server/index.d.ts +37 -0
  49. package/dist/server/index.js +44 -29
  50. package/package.json +1 -1
  51. package/dist/client/Slot-CWb612-_.mjs +0 -28
  52. package/dist/client/Slot-CWb612-_.mjs.map +0 -1
  53. package/dist/client/_floatingIpId-De0hCSSN2.mjs.map +0 -1
  54. package/dist/client/_projectId-Cq9JnhRj.mjs.map +0 -1
  55. package/dist/client/_projectId-Ig3QqYzt.mjs.map +0 -1
  56. package/dist/client/_projectId-b4NGeECR.mjs.map +0 -1
  57. package/dist/client/projects-CDFynG9q.mjs +0 -23
  58. package/dist/client/projects-CDFynG9q.mjs.map +0 -1
  59. package/dist/client/projects-sn_XPdCh.mjs +0 -107
  60. package/dist/client/projects-sn_XPdCh.mjs.map +0 -1
  61. package/dist/client/routeInfo-CdTRlSxv.mjs +0 -32
  62. package/dist/client/routeInfo-CdTRlSxv.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import { A as e, B as t, C as n, E as r, G as i, H as a, K as o, P as s, R as c, U as l, Y as u, at as d, o as f, r as p, rt as m, tt as h, y as g } from "./build-DgeVmENN.mjs";
2
2
  import { r as _ } from "./trpcClient-BxcNKnhv.mjs";
3
- import { t as v } from "./pca-B4_2DqT2.mjs";
3
+ import { t as v } from "./pca-ZgGU0UPF.mjs";
4
4
  import { t as y } from "./useProjectId-DBc5lpoU.mjs";
5
5
  import "./hooks-BsbKkpZc.mjs";
6
- import { t as b } from "./ContentHeader-BIScbvb4.mjs";
6
+ import { t as b } from "./ContentHeader-CIAzorGI.mjs";
7
7
  import { t as x } from "./useModal-DCs1OJh7.mjs";
8
8
  import { d as S, h as C, n as w, r as T, u as E } from "./md-CyCflQee.mjs";
9
9
  import { t as D } from "./DeletePcaModal-YUlNw8cw.mjs";
@@ -248,4 +248,4 @@ function W() {
248
248
  //#endregion
249
249
  export { W as component };
250
250
 
251
- //# sourceMappingURL=pca-BClYQElh.mjs.map
251
+ //# sourceMappingURL=pca-CpMqoF00.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pca-BClYQElh.mjs","names":["MdAutorenew","MdCheckCircle","MdHelpOutline","MdHourglassEmpty","MdReportProblem","useNavigate","DataGridCell","DataGridRow","PopupMenu","PopupMenuItem","PopupMenuOptions","useModal","useProjectId","DeletePcaModal","PcaTableRow","pca","useLingui","navigate","projectId","deletePcaModalOpen","toggleDeletePcaModal","navigateToDetailsPage","to","params","pcaId","id","STATE_CONFIG","CREATING","text","t","icon","size","color","fill","AWAITING_CERTIFICATE","READY","FAILED","UNEXPECTED","data-testid","onClick","div","className","state","display_subject","e","stopPropagation","label","open","onClose","z","useForm","useStore","useNavigate","Modal","Form","FormSection","Spinner","TextInput","Message","trpcReact","useProjectId","csrRegex","isValidCommonName","value","test","CreatePcaModal","open","onClose","useLingui","navigate","projectId","utils","useUtils","isPending","createPcaMutation","services","pca","create","useMutation","onSettled","list","invalidate","formSchema","object","common_name","string","trim","min","t","refine","message","form","defaultValues","validators","onSubmit","createdPca","mutateAsync","project_id","configuration","subject","named_attributes","cn","handleClose","to","params","pcaId","id","reset","isCreateDisabled","store","state","isSubmitting","values","length","size","title","onCancel","cancelButtonLabel","confirmButtonLabel","onConfirm","handleSubmit","disableConfirmButton","error","dismissible","variant","className","div","span","e","preventDefault","Field","name","children","field","onBlur","handleBlur","onChange","handleChange","target","label","placeholder","helptext","errortext","meta","errors","map","join","disabled","useState","Stack","Spinner","DataGrid","DataGridRow","DataGridCell","ContentHeading","DataGridHeadCell","Button","Pagination","trpcReact","useProjectId","useModal","PcaTableRow","CreatePcaModal","ITEMS_PER_PAGE","PcaListContainer","useLingui","projectId","createCaOpen","toggleCreateCa","pageMarkers","setPageMarkers","undefined","currentPage","setCurrentPage","currentMarker","data","isLoading","isError","error","services","pca","list","useQuery","project_id","limit","next_page_marker","pcas","certificate_authorities","nextMarker","computedTotal","totalPages","Math","max","length","goToPage","page","prev","updated","className","distribution","alignment","direction","variant","size","message","t","TABLE_COLUMNS","columnsLength","div","label","onClick","columns","data-testid","colSpan","p","map","id","pages","onPressPrevious","onPressNext","open","onClose","useLingui","ContentHeader","PcaListContainer","Route","RouteComponent","t","projectId","useParams","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-table/PcaTableRow.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-modals/CreatePcaModal.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-table/PcaListContainer.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/index.tsx?tsr-split=component"],"sourcesContent":["import { MdAutorenew, MdCheckCircle, MdHelpOutline, MdHourglassEmpty, MdReportProblem } from \"react-icons/md\"\nimport { useNavigate } from \"@tanstack/react-router\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport {\n DataGridCell,\n DataGridRow,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { CertificateAuthority } from \"@/server/Services/types/pca\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { DeletePcaModal } from \"../-modals/DeletePcaModal\"\n\ninterface PcaTableRowProps {\n pca: CertificateAuthority\n}\n\nexport const PcaTableRow = ({ pca }: PcaTableRowProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const projectId = useProjectId()\n const [deletePcaModalOpen, toggleDeletePcaModal] = useModal(false)\n\n const navigateToDetailsPage = () =>\n navigate({\n to: \"/projects/$projectId/services/pca/$pcaId\",\n params: { projectId, pcaId: pca.id },\n })\n\n const STATE_CONFIG = {\n CREATING: {\n text: t`Creating`,\n icon: <MdAutorenew size={20} color=\"white\" fill=\"#1976D2\" />,\n },\n AWAITING_CERTIFICATE: {\n text: t`Awaiting Certificate`,\n icon: <MdHourglassEmpty size={20} color=\"white\" fill=\"#FBC02D\" />,\n },\n READY: {\n text: t`Ready`,\n icon: <MdCheckCircle size={20} color=\"white\" fill=\"#4FB81C\" />,\n },\n FAILED: {\n text: t`Failed`,\n icon: <MdReportProblem size={20} color=\"white\" fill=\"#D32F2F\" />,\n },\n UNEXPECTED: {\n text: t`Unexpected`,\n icon: <MdHelpOutline size={20} color=\"white\" fill=\"#757575\" />,\n },\n } as const\n\n return (\n <>\n <DataGridRow key={pca.id} data-testid={`pca-row-${pca.id}`} onClick={navigateToDetailsPage}>\n <DataGridCell>\n <div className=\"flex items-center gap-2\">\n {STATE_CONFIG[pca.state].icon}\n {STATE_CONFIG[pca.state].text}\n </div>\n </DataGridCell>\n <DataGridCell>{pca.id}</DataGridCell>\n <DataGridCell>{pca.display_subject || \"—\"}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Show Details`} onClick={navigateToDetailsPage} />\n <PopupMenuItem label={t`Delete CA`} onClick={toggleDeletePcaModal} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n </DataGridRow>\n\n {deletePcaModalOpen && <DeletePcaModal pca={pca} open={deletePcaModalOpen} onClose={toggleDeletePcaModal} />}\n </>\n )\n}\n","import { z } from \"zod\"\nimport { useForm, useStore } from \"@tanstack/react-form\"\nimport { useNavigate } from \"@tanstack/react-router\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Modal, Form, FormSection, Spinner, TextInput, Message } from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\n\ninterface CreatePcaModalProps {\n open: boolean\n onClose: () => void\n}\n\nconst csrRegex = /^(?=.{1,253}$)(?:\\*\\.)?(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,63}$/\nconst isValidCommonName = (value: string) => csrRegex.test(value)\n\nexport const CreatePcaModal = ({ open, onClose }: CreatePcaModalProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const projectId = useProjectId()\n const utils = trpcReact.useUtils()\n\n const { isPending, ...createPcaMutation } = trpcReact.services.pca.create.useMutation({\n onSettled: () => utils.services.pca.list.invalidate(),\n })\n\n const formSchema = z.object({\n common_name: z\n .string()\n .trim()\n .min(1, t`Common name is required.`)\n .refine((value) => isValidCommonName(value), { message: t`Must be a valid common name (FQDN).` }),\n })\n\n const form = useForm({\n defaultValues: {\n common_name: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n if (isPending) return\n\n const createdPca = await createPcaMutation.mutateAsync({\n project_id: projectId,\n configuration: {\n subject: {\n named_attributes: {\n cn: value.common_name,\n },\n },\n },\n })\n handleClose()\n\n await navigate({\n to: \"/projects/$projectId/services/pca/$pcaId\",\n params: { projectId, pcaId: createdPca.id },\n })\n },\n })\n\n const handleClose = () => {\n if (isPending) return\n\n form.reset()\n createPcaMutation.reset()\n onClose()\n }\n\n // Reactive subscription used to control create action disabled state.\n const isCreateDisabled = useStore(\n form.store,\n (state) => state.isSubmitting || state.values.common_name.trim().length === 0\n )\n\n return (\n <Modal\n open={open}\n size=\"large\"\n title={t`Create Certificate Authority`}\n onCancel={handleClose}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Save`}\n onConfirm={form.handleSubmit}\n disableConfirmButton={isPending || isCreateDisabled}\n >\n {createPcaMutation.error?.message && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {createPcaMutation.error.message}\n </Message>\n )}\n\n {isPending && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-high text-sm\">\n <Trans>Creating Certificate Authority...</Trans>\n </span>\n </div>\n )}\n\n {!isPending && (\n <Form\n className=\"mb-0\"\n id=\"create-certificate-authority-form\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"common_name\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n label={t`Common name`}\n placeholder={t`Enter Common name (e.g., demo-ca.test.sci)`}\n helptext={t`Enter a valid common name in FQDN format (e.g., demo-ca.test.sci).`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending}\n />\n )}\n />\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useState } from \"react\"\nimport {\n Stack,\n Spinner,\n DataGrid,\n DataGridRow,\n DataGridCell,\n ContentHeading,\n DataGridHeadCell,\n Button,\n Pagination,\n} from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { PcaTableRow } from \"./PcaTableRow\"\nimport { CreatePcaModal } from \"../-modals/CreatePcaModal\"\n\nconst ITEMS_PER_PAGE = 50\n\nexport const PcaListContainer = () => {\n const { t } = useLingui()\n const projectId = useProjectId()\n const [createCaOpen, toggleCreateCa] = useModal(false)\n const [pageMarkers, setPageMarkers] = useState<(string | undefined)[]>([undefined])\n const [currentPage, setCurrentPage] = useState(1)\n const currentMarker = pageMarkers[currentPage - 1]\n\n const { data, isLoading, isError, error } = trpcReact.services.pca.list.useQuery({\n project_id: projectId,\n limit: ITEMS_PER_PAGE,\n next_page_marker: currentMarker,\n })\n\n const pcas = data?.certificate_authorities ?? []\n const nextMarker = data?.next_page_marker\n const computedTotal = nextMarker ? currentPage + 1 : currentPage\n const totalPages = Math.max(computedTotal, pageMarkers.length)\n\n const goToPage = (page: number) => {\n if (page < 1 || page > totalPages) return\n if (page > currentPage && nextMarker) {\n setPageMarkers((prev) => {\n const updated = [...prev]\n updated[page - 1] = nextMarker\n return updated\n })\n }\n setCurrentPage(page)\n }\n\n if (isLoading) {\n return (\n <Stack className=\"py-8\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading...</Trans>\n </Stack>\n )\n }\n\n if (isError) {\n return (\n <Stack className=\"py-8\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n {error?.message ?? t`Failed to load PCAs`}\n </Stack>\n )\n }\n\n const TABLE_COLUMNS = [\n t`State`,\n t`ID`,\n t`Subject information`,\n \"\", // empty column for item-action with context menu containing \"Delete CA\" button\n ] as const\n const columnsLength = TABLE_COLUMNS.length\n\n return (\n <div className=\"relative\">\n <Stack className=\"pt-3 pb-2\" distribution=\"end\">\n <Button variant=\"primary\" label={t`Create Certificate Authority`} onClick={toggleCreateCa} />\n </Stack>\n\n {pcas.length === 0 && currentPage === 1 ? (\n <DataGrid columns={columnsLength} className=\"pca\" data-testid=\"no-pcas\">\n <DataGridRow>\n <DataGridCell colSpan={columnsLength}>\n <ContentHeading>\n <Trans>No PCAs found</Trans>\n </ContentHeading>\n <p>\n <Trans>There are no PCAs available for this project.</Trans>\n </p>\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n ) : (\n <>\n <DataGrid columns={columnsLength}>\n <DataGridRow>\n {TABLE_COLUMNS.map((label) => (\n <DataGridHeadCell key={label}>{label}</DataGridHeadCell>\n ))}\n </DataGridRow>\n {pcas.map((pca) => (\n <PcaTableRow key={pca.id} pca={pca} />\n ))}\n </DataGrid>\n\n {totalPages > 1 && (\n <div className=\"flex justify-center py-4\">\n <Pagination\n variant=\"input\"\n currentPage={currentPage}\n pages={totalPages}\n onPressPrevious={() => goToPage(currentPage - 1)}\n onPressNext={() => goToPage(currentPage + 1)}\n />\n </div>\n )}\n </>\n )}\n\n {createCaOpen && <CreatePcaModal open={createCaOpen} onClose={toggleCreateCa} />}\n </div>\n )\n}\n","import { createFileRoute, redirect } from \"@tanstack/react-router\"\nimport { t } from \"@lingui/core/macro\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { canAccessClavisPca } from \"./-components/pcaAccess\"\nimport { PcaListContainer } from \"./-components/-table/PcaListContainer\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/services/pca/\")({\n staticData: {\n section: \"services\",\n service: \"pca\",\n analytics: {\n name: \"services.pca.list\",\n },\n sectionCrumb: { labelKey: \"Services\" },\n crumb: { labelKey: \"PCA (Clavis)\" },\n } satisfies RouteInfo,\n head: () => ({ meta: [{ title: t`PCA` }] }),\n beforeLoad: async ({ context, params }) => {\n const availableServices = (await context.trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!canAccessClavisPca(serviceIndex, context.enabledServices)) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId: params.projectId },\n })\n }\n },\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const { projectId } = Route.useParams()\n\n return (\n <>\n <ContentHeader title={t`PCA`} projectId={projectId} />\n <PcaListContainer />\n </>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pca-CpMqoF00.mjs","names":["MdAutorenew","MdCheckCircle","MdHelpOutline","MdHourglassEmpty","MdReportProblem","useNavigate","DataGridCell","DataGridRow","PopupMenu","PopupMenuItem","PopupMenuOptions","useModal","useProjectId","DeletePcaModal","PcaTableRow","pca","useLingui","navigate","projectId","deletePcaModalOpen","toggleDeletePcaModal","navigateToDetailsPage","to","params","pcaId","id","STATE_CONFIG","CREATING","text","t","icon","size","color","fill","AWAITING_CERTIFICATE","READY","FAILED","UNEXPECTED","data-testid","onClick","div","className","state","display_subject","e","stopPropagation","label","open","onClose","z","useForm","useStore","useNavigate","Modal","Form","FormSection","Spinner","TextInput","Message","trpcReact","useProjectId","csrRegex","isValidCommonName","value","test","CreatePcaModal","open","onClose","useLingui","navigate","projectId","utils","useUtils","isPending","createPcaMutation","services","pca","create","useMutation","onSettled","list","invalidate","formSchema","object","common_name","string","trim","min","t","refine","message","form","defaultValues","validators","onSubmit","createdPca","mutateAsync","project_id","configuration","subject","named_attributes","cn","handleClose","to","params","pcaId","id","reset","isCreateDisabled","store","state","isSubmitting","values","length","size","title","onCancel","cancelButtonLabel","confirmButtonLabel","onConfirm","handleSubmit","disableConfirmButton","error","dismissible","variant","className","div","span","e","preventDefault","Field","name","children","field","onBlur","handleBlur","onChange","handleChange","target","label","placeholder","helptext","errortext","meta","errors","map","join","disabled","useState","Stack","Spinner","DataGrid","DataGridRow","DataGridCell","ContentHeading","DataGridHeadCell","Button","Pagination","trpcReact","useProjectId","useModal","PcaTableRow","CreatePcaModal","ITEMS_PER_PAGE","PcaListContainer","useLingui","projectId","createCaOpen","toggleCreateCa","pageMarkers","setPageMarkers","undefined","currentPage","setCurrentPage","currentMarker","data","isLoading","isError","error","services","pca","list","useQuery","project_id","limit","next_page_marker","pcas","certificate_authorities","nextMarker","computedTotal","totalPages","Math","max","length","goToPage","page","prev","updated","className","distribution","alignment","direction","variant","size","message","t","TABLE_COLUMNS","columnsLength","div","label","onClick","columns","data-testid","colSpan","p","map","id","pages","onPressPrevious","onPressNext","open","onClose","useLingui","ContentHeader","PcaListContainer","Route","RouteComponent","t","projectId","useParams","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-table/PcaTableRow.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-modals/CreatePcaModal.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/-components/-table/PcaListContainer.tsx","../../src/client/routes/_auth/projects/$projectId/services/pca/index.tsx?tsr-split=component"],"sourcesContent":["import { MdAutorenew, MdCheckCircle, MdHelpOutline, MdHourglassEmpty, MdReportProblem } from \"react-icons/md\"\nimport { useNavigate } from \"@tanstack/react-router\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport {\n DataGridCell,\n DataGridRow,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { CertificateAuthority } from \"@/server/Services/types/pca\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { DeletePcaModal } from \"../-modals/DeletePcaModal\"\n\ninterface PcaTableRowProps {\n pca: CertificateAuthority\n}\n\nexport const PcaTableRow = ({ pca }: PcaTableRowProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const projectId = useProjectId()\n const [deletePcaModalOpen, toggleDeletePcaModal] = useModal(false)\n\n const navigateToDetailsPage = () =>\n navigate({\n to: \"/projects/$projectId/services/pca/$pcaId\",\n params: { projectId, pcaId: pca.id },\n })\n\n const STATE_CONFIG = {\n CREATING: {\n text: t`Creating`,\n icon: <MdAutorenew size={20} color=\"white\" fill=\"#1976D2\" />,\n },\n AWAITING_CERTIFICATE: {\n text: t`Awaiting Certificate`,\n icon: <MdHourglassEmpty size={20} color=\"white\" fill=\"#FBC02D\" />,\n },\n READY: {\n text: t`Ready`,\n icon: <MdCheckCircle size={20} color=\"white\" fill=\"#4FB81C\" />,\n },\n FAILED: {\n text: t`Failed`,\n icon: <MdReportProblem size={20} color=\"white\" fill=\"#D32F2F\" />,\n },\n UNEXPECTED: {\n text: t`Unexpected`,\n icon: <MdHelpOutline size={20} color=\"white\" fill=\"#757575\" />,\n },\n } as const\n\n return (\n <>\n <DataGridRow key={pca.id} data-testid={`pca-row-${pca.id}`} onClick={navigateToDetailsPage}>\n <DataGridCell>\n <div className=\"flex items-center gap-2\">\n {STATE_CONFIG[pca.state].icon}\n {STATE_CONFIG[pca.state].text}\n </div>\n </DataGridCell>\n <DataGridCell>{pca.id}</DataGridCell>\n <DataGridCell>{pca.display_subject || \"—\"}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Show Details`} onClick={navigateToDetailsPage} />\n <PopupMenuItem label={t`Delete CA`} onClick={toggleDeletePcaModal} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n </DataGridRow>\n\n {deletePcaModalOpen && <DeletePcaModal pca={pca} open={deletePcaModalOpen} onClose={toggleDeletePcaModal} />}\n </>\n )\n}\n","import { z } from \"zod\"\nimport { useForm, useStore } from \"@tanstack/react-form\"\nimport { useNavigate } from \"@tanstack/react-router\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Modal, Form, FormSection, Spinner, TextInput, Message } from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\n\ninterface CreatePcaModalProps {\n open: boolean\n onClose: () => void\n}\n\nconst csrRegex = /^(?=.{1,253}$)(?:\\*\\.)?(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,63}$/\nconst isValidCommonName = (value: string) => csrRegex.test(value)\n\nexport const CreatePcaModal = ({ open, onClose }: CreatePcaModalProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const projectId = useProjectId()\n const utils = trpcReact.useUtils()\n\n const { isPending, ...createPcaMutation } = trpcReact.services.pca.create.useMutation({\n onSettled: () => utils.services.pca.list.invalidate(),\n })\n\n const formSchema = z.object({\n common_name: z\n .string()\n .trim()\n .min(1, t`Common name is required.`)\n .refine((value) => isValidCommonName(value), { message: t`Must be a valid common name (FQDN).` }),\n })\n\n const form = useForm({\n defaultValues: {\n common_name: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n if (isPending) return\n\n const createdPca = await createPcaMutation.mutateAsync({\n project_id: projectId,\n configuration: {\n subject: {\n named_attributes: {\n cn: value.common_name,\n },\n },\n },\n })\n handleClose()\n\n await navigate({\n to: \"/projects/$projectId/services/pca/$pcaId\",\n params: { projectId, pcaId: createdPca.id },\n })\n },\n })\n\n const handleClose = () => {\n if (isPending) return\n\n form.reset()\n createPcaMutation.reset()\n onClose()\n }\n\n // Reactive subscription used to control create action disabled state.\n const isCreateDisabled = useStore(\n form.store,\n (state) => state.isSubmitting || state.values.common_name.trim().length === 0\n )\n\n return (\n <Modal\n open={open}\n size=\"large\"\n title={t`Create Certificate Authority`}\n onCancel={handleClose}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Save`}\n onConfirm={form.handleSubmit}\n disableConfirmButton={isPending || isCreateDisabled}\n >\n {createPcaMutation.error?.message && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {createPcaMutation.error.message}\n </Message>\n )}\n\n {isPending && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-high text-sm\">\n <Trans>Creating Certificate Authority...</Trans>\n </span>\n </div>\n )}\n\n {!isPending && (\n <Form\n className=\"mb-0\"\n id=\"create-certificate-authority-form\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"common_name\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n label={t`Common name`}\n placeholder={t`Enter Common name (e.g., demo-ca.test.sci)`}\n helptext={t`Enter a valid common name in FQDN format (e.g., demo-ca.test.sci).`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending}\n />\n )}\n />\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useState } from \"react\"\nimport {\n Stack,\n Spinner,\n DataGrid,\n DataGridRow,\n DataGridCell,\n ContentHeading,\n DataGridHeadCell,\n Button,\n Pagination,\n} from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { PcaTableRow } from \"./PcaTableRow\"\nimport { CreatePcaModal } from \"../-modals/CreatePcaModal\"\n\nconst ITEMS_PER_PAGE = 50\n\nexport const PcaListContainer = () => {\n const { t } = useLingui()\n const projectId = useProjectId()\n const [createCaOpen, toggleCreateCa] = useModal(false)\n const [pageMarkers, setPageMarkers] = useState<(string | undefined)[]>([undefined])\n const [currentPage, setCurrentPage] = useState(1)\n const currentMarker = pageMarkers[currentPage - 1]\n\n const { data, isLoading, isError, error } = trpcReact.services.pca.list.useQuery({\n project_id: projectId,\n limit: ITEMS_PER_PAGE,\n next_page_marker: currentMarker,\n })\n\n const pcas = data?.certificate_authorities ?? []\n const nextMarker = data?.next_page_marker\n const computedTotal = nextMarker ? currentPage + 1 : currentPage\n const totalPages = Math.max(computedTotal, pageMarkers.length)\n\n const goToPage = (page: number) => {\n if (page < 1 || page > totalPages) return\n if (page > currentPage && nextMarker) {\n setPageMarkers((prev) => {\n const updated = [...prev]\n updated[page - 1] = nextMarker\n return updated\n })\n }\n setCurrentPage(page)\n }\n\n if (isLoading) {\n return (\n <Stack className=\"py-8\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading...</Trans>\n </Stack>\n )\n }\n\n if (isError) {\n return (\n <Stack className=\"py-8\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n {error?.message ?? t`Failed to load PCAs`}\n </Stack>\n )\n }\n\n const TABLE_COLUMNS = [\n t`State`,\n t`ID`,\n t`Subject information`,\n \"\", // empty column for item-action with context menu containing \"Delete CA\" button\n ] as const\n const columnsLength = TABLE_COLUMNS.length\n\n return (\n <div className=\"relative\">\n <Stack className=\"pt-3 pb-2\" distribution=\"end\">\n <Button variant=\"primary\" label={t`Create Certificate Authority`} onClick={toggleCreateCa} />\n </Stack>\n\n {pcas.length === 0 && currentPage === 1 ? (\n <DataGrid columns={columnsLength} className=\"pca\" data-testid=\"no-pcas\">\n <DataGridRow>\n <DataGridCell colSpan={columnsLength}>\n <ContentHeading>\n <Trans>No PCAs found</Trans>\n </ContentHeading>\n <p>\n <Trans>There are no PCAs available for this project.</Trans>\n </p>\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n ) : (\n <>\n <DataGrid columns={columnsLength}>\n <DataGridRow>\n {TABLE_COLUMNS.map((label) => (\n <DataGridHeadCell key={label}>{label}</DataGridHeadCell>\n ))}\n </DataGridRow>\n {pcas.map((pca) => (\n <PcaTableRow key={pca.id} pca={pca} />\n ))}\n </DataGrid>\n\n {totalPages > 1 && (\n <div className=\"flex justify-center py-4\">\n <Pagination\n variant=\"input\"\n currentPage={currentPage}\n pages={totalPages}\n onPressPrevious={() => goToPage(currentPage - 1)}\n onPressNext={() => goToPage(currentPage + 1)}\n />\n </div>\n )}\n </>\n )}\n\n {createCaOpen && <CreatePcaModal open={createCaOpen} onClose={toggleCreateCa} />}\n </div>\n )\n}\n","import { createFileRoute, redirect } from \"@tanstack/react-router\"\nimport { t } from \"@lingui/core/macro\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { canAccessClavisPca } from \"./-components/pcaAccess\"\nimport { PcaListContainer } from \"./-components/-table/PcaListContainer\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/services/pca/\")({\n staticData: {\n section: \"services\",\n service: \"pca\",\n analytics: {\n name: \"services.pca.list\",\n },\n sectionCrumb: { labelKey: \"Services\" },\n crumb: { labelKey: \"PCA (Clavis)\" },\n } satisfies RouteInfo,\n head: () => ({ meta: [{ title: t`PCA` }] }),\n beforeLoad: async ({ context, params }) => {\n const availableServices = (await context.trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!canAccessClavisPca(serviceIndex, context.enabledServices)) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId: params.projectId },\n })\n }\n },\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const { projectId } = Route.useParams()\n\n return (\n <>\n <ContentHeader title={t`PCA`} projectId={projectId} />\n <PcaListContainer />\n </>\n )\n}\n"],"mappings":"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"}
@@ -17,9 +17,9 @@ var o = n("/_auth/projects/$projectId/services/pca/")({
17
17
  params: { projectId: r.projectId }
18
18
  });
19
19
  },
20
- component: r(() => import("./pca-BClYQElh.mjs"), "component")
20
+ component: r(() => import("./pca-CpMqoF00.mjs"), "component")
21
21
  });
22
22
  //#endregion
23
23
  export { o as t };
24
24
 
25
- //# sourceMappingURL=pca-B4_2DqT2.mjs.map
25
+ //# sourceMappingURL=pca-ZgGU0UPF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pca-B4_2DqT2.mjs","names":["createFileRoute","redirect","t","getServiceIndex","canAccessClavisPca","Route","staticData","section","service","analytics","name","sectionCrumb","labelKey","crumb","RouteInfo","head","meta","title","beforeLoad","context","params","availableServices","trpcClient","auth","getAvailableServices","query","serviceIndex","enabledServices","to","projectId","component","lazyRouteComponent","$$splitComponentImporter"],"sources":["../../src/client/routes/_auth/projects/$projectId/services/pca/index.tsx"],"sourcesContent":["import { createFileRoute, redirect } from \"@tanstack/react-router\"\nimport { t } from \"@lingui/core/macro\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { canAccessClavisPca } from \"./-components/pcaAccess\"\nimport { PcaListContainer } from \"./-components/-table/PcaListContainer\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/services/pca/\")({\n staticData: {\n section: \"services\",\n service: \"pca\",\n analytics: {\n name: \"services.pca.list\",\n },\n sectionCrumb: { labelKey: \"Services\" },\n crumb: { labelKey: \"PCA (Clavis)\" },\n } satisfies RouteInfo,\n head: () => ({ meta: [{ title: t`PCA` }] }),\n beforeLoad: async ({ context, params }) => {\n const availableServices = (await context.trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!canAccessClavisPca(serviceIndex, context.enabledServices)) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId: params.projectId },\n })\n }\n },\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const { projectId } = Route.useParams()\n\n return (\n <>\n <ContentHeader title={t`PCA`} projectId={projectId} />\n <PcaListContainer />\n </>\n )\n}\n"],"mappings":";;;;AASA,IAAaK,IAAQL,EAAgB,0CAAA,EAA4C;CAC/EM,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,WAAW,EACTC,MAAM,oBACR;EACAC,cAAc,EAAEC,UAAU,WAAW;EACrCC,OAAO,EAAED,UAAU,eAAe;CACpC;CACAG,aAAa,EAAEC,MAAM,CAAC,EAAEC,OAAOf,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA,EAAM,CAAA,EAAG;CACzCgB,YAAY,OAAO,EAAEC,YAASC,gBAAQ;EAIpC,IAAI,CAAChB,EAFgBD,EADK,MAAOgB,EAAQG,YAAYC,KAAKC,qBAAqBC,MAAAA,KAAY,CAAA,CAGnEC,GAAcP,EAAQQ,eAAe,GAC3D,MAAM1B,EAAS;GACb2B,IAAI;GACJR,QAAQ,EAAES,WAAWT,EAAOS,UAAU;EACxC,CAAA;CAEJ;CACAC,WAASC,sCAAA,WAAA;AACX,CAAA"}
1
+ {"version":3,"file":"pca-ZgGU0UPF.mjs","names":["createFileRoute","redirect","t","getServiceIndex","canAccessClavisPca","Route","staticData","section","service","analytics","name","sectionCrumb","labelKey","crumb","RouteInfo","head","meta","title","beforeLoad","context","params","availableServices","trpcClient","auth","getAvailableServices","query","serviceIndex","enabledServices","to","projectId","component","lazyRouteComponent","$$splitComponentImporter"],"sources":["../../src/client/routes/_auth/projects/$projectId/services/pca/index.tsx"],"sourcesContent":["import { createFileRoute, redirect } from \"@tanstack/react-router\"\nimport { t } from \"@lingui/core/macro\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { canAccessClavisPca } from \"./-components/pcaAccess\"\nimport { PcaListContainer } from \"./-components/-table/PcaListContainer\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/services/pca/\")({\n staticData: {\n section: \"services\",\n service: \"pca\",\n analytics: {\n name: \"services.pca.list\",\n },\n sectionCrumb: { labelKey: \"Services\" },\n crumb: { labelKey: \"PCA (Clavis)\" },\n } satisfies RouteInfo,\n head: () => ({ meta: [{ title: t`PCA` }] }),\n beforeLoad: async ({ context, params }) => {\n const availableServices = (await context.trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!canAccessClavisPca(serviceIndex, context.enabledServices)) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId: params.projectId },\n })\n }\n },\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const { projectId } = Route.useParams()\n\n return (\n <>\n <ContentHeader title={t`PCA`} projectId={projectId} />\n <PcaListContainer />\n </>\n )\n}\n"],"mappings":";;;;AASA,IAAaK,IAAQL,EAAgB,0CAAA,EAA4C;CAC/EM,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,WAAW,EACTC,MAAM,oBACR;EACAC,cAAc,EAAEC,UAAU,WAAW;EACrCC,OAAO,EAAED,UAAU,eAAe;CACpC;CACAG,aAAa,EAAEC,MAAM,CAAC,EAAEC,OAAOf,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA,EAAM,CAAA,EAAG;CACzCgB,YAAY,OAAO,EAAEC,YAASC,gBAAQ;EAIpC,IAAI,CAAChB,EAFgBD,EADK,MAAOgB,EAAQG,YAAYC,KAAKC,qBAAqBC,MAAAA,KAAY,CAAA,CAGnEC,GAAcP,EAAQQ,eAAe,GAC3D,MAAM1B,EAAS;GACb2B,IAAI;GACJR,QAAQ,EAAES,WAAWT,EAAOS,UAAU;EACxC,CAAA;CAEJ;CACAC,WAASC,sCAAA,WAAA;AACX,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"projects-DvSiI5Vg.mjs","names":["RouteError","TRPCClientError","Route","SplitErrorComponent","error","message","undefined","errorComponent"],"sources":["../../src/client/routes/_auth/projects/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { createFileRoute } from \"@tanstack/react-router\"\nimport { useRouteContext } from \"@tanstack/react-router\"\nimport { ProjectsOverviewNavBar } from \"@/client/routes/_auth/projects/-components/ProjectOverviewNavBar\"\nimport { ProjectCardView } from \"@/client/routes/_auth/projects/-components/ProjectCardView\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { Container, ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { z } from \"zod\"\nimport { Slot } from \"@/client/components/Slot\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\n\nconst searchSchema = z.object({\n search: z.string().optional(),\n})\n\nexport const Route = createFileRoute(\"/_auth/projects/\")({\n staticData: {\n analytics: {\n name: \"projects.list\",\n },\n } satisfies RouteInfo,\n component: ProjectsOverview,\n errorComponent: ({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n ),\n notFoundComponent: () => {\n return <p>Projects not found</p>\n },\n validateSearch: searchSchema,\n loaderDeps: ({ search }) => ({\n search: search.search || \"\",\n }),\n loader: async ({ context, deps }) => {\n const allProjects = await context.trpcClient?.project.getAuthProjects.query()\n\n let projects = allProjects\n if (deps.search && deps.search.trim() !== \"\") {\n const searchTermLower = deps.search.toLowerCase()\n projects = allProjects?.filter(\n (project) =>\n project.name?.toLowerCase().includes(searchTermLower) ||\n project.description?.toLowerCase().includes(searchTermLower)\n )\n }\n\n return { projects }\n },\n})\n\nfunction ProjectsOverview() {\n const { projects } = Route.useLoaderData()\n const { search = \"\" } = Route.useSearch()\n const navigate = Route.useNavigate()\n const { slots } = useRouteContext({ strict: false })\n\n const handleSearch = (value: string) => {\n navigate({ search: { search: value }, replace: true })\n }\n\n return (\n <Container py>\n <ContentHeading className=\"pb-4\">\n <Trans>Projects</Trans>\n </ContentHeading>\n {slots?.projectsBanner && <Slot component={slots.projectsBanner} useShadowDOM={false} />}\n <ProjectsOverviewNavBar searchTerm={search} onSearch={handleSearch} />\n <div className=\"pt-5\">\n <ProjectCardView projects={projects} />\n </div>\n </Container>\n )\n}\n"],"mappings":";;;;AAK8C,IAAAG,KAkB3B,EAAEC,eACjB,gBAAC,GAAA;CAAkBA;CAAO,kBAAkBA,aAAiBH,IAAkBG,EAAMC,UAAUC,KAAAA"}
1
+ {"version":3,"file":"projects-DvSiI5Vg.mjs","names":["RouteError","TRPCClientError","Route","ProjectsContentProps","search","SplitErrorComponent","error","message","undefined","errorComponent"],"sources":["../../src/client/routes/_auth/projects/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { Suspense } from \"react\"\nimport { ErrorBoundary } from \"react-error-boundary\"\nimport { createFileRoute, useRouteContext } from \"@tanstack/react-router\"\nimport { ProjectsOverviewNavBar } from \"@/client/routes/_auth/projects/-components/ProjectOverviewNavBar\"\nimport { ProjectCardView } from \"@/client/routes/_auth/projects/-components/ProjectCardView\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { Container, ContentHeading, Spinner, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { z } from \"zod\"\nimport { Slot } from \"@/client/components/Slot\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\n\nconst searchSchema = z.object({\n search: z.string().optional(),\n})\n\nexport const Route = createFileRoute(\"/_auth/projects/\")({\n staticData: {\n analytics: {\n name: \"projects.list\",\n },\n } satisfies RouteInfo,\n component: ProjectsOverview,\n errorComponent: ({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n ),\n notFoundComponent: () => {\n return <p>Projects not found</p>\n },\n validateSearch: searchSchema,\n})\n\ninterface ProjectsContentProps {\n search: string\n}\n\nfunction ProjectsContent({ search }: ProjectsContentProps) {\n const [allProjects] = trpcReact.project.getAuthProjects.useSuspenseQuery()\n\n const normalizedSearch = search.trim().toLowerCase()\n const projects =\n allProjects && normalizedSearch\n ? allProjects.filter(\n (project) =>\n project.name?.toLowerCase().includes(normalizedSearch) ||\n project.description?.toLowerCase().includes(normalizedSearch)\n )\n : allProjects\n\n return <ProjectCardView projects={projects} />\n}\n\nexport function ProjectsOverview() {\n const { search = \"\" } = Route.useSearch()\n const navigate = Route.useNavigate()\n const { slots } = useRouteContext({ strict: false })\n\n const handleSearch = (value: string) => {\n navigate({ search: (prev) => ({ ...prev, search: value || undefined }), replace: true })\n }\n\n return (\n <Container py>\n <ContentHeading className=\"pb-4\">\n <Trans>Projects</Trans>\n </ContentHeading>\n {slots?.projectsBanner && (\n <ErrorBoundary fallbackRender={() => null}>\n <Suspense fallback={null}>\n <Slot component={slots.projectsBanner} useShadowDOM={false} />\n </Suspense>\n </ErrorBoundary>\n )}\n <ProjectsOverviewNavBar searchTerm={search} onSearch={handleSearch} />\n <div className=\"pt-5\">\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n )}\n >\n <Suspense\n fallback={\n <Stack distribution=\"center\" alignment=\"center\" direction=\"vertical\" className=\"py-12\">\n <Spinner variant=\"primary\" size=\"large\" />\n </Stack>\n }\n >\n <ProjectsContent search={search} />\n </Suspense>\n </ErrorBoundary>\n </div>\n </Container>\n )\n}\n"],"mappings":";;;;AAoCC,IAAAK,KAXkB,EAAEC,eACjB,gBAAC,GAAA;CAAkBA;CAAO,kBAAkBA,aAAiBL,IAAkBK,EAAMC,UAAUC,KAAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"projects-yiK0HGSA.mjs","names":["SplitNotFoundComponent","notFoundComponent"],"sources":["../../src/client/routes/_auth/projects/index.tsx?tsr-split=notFoundComponent"],"sourcesContent":["import { createFileRoute } from \"@tanstack/react-router\"\nimport { useRouteContext } from \"@tanstack/react-router\"\nimport { ProjectsOverviewNavBar } from \"@/client/routes/_auth/projects/-components/ProjectOverviewNavBar\"\nimport { ProjectCardView } from \"@/client/routes/_auth/projects/-components/ProjectCardView\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { Container, ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { z } from \"zod\"\nimport { Slot } from \"@/client/components/Slot\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\n\nconst searchSchema = z.object({\n search: z.string().optional(),\n})\n\nexport const Route = createFileRoute(\"/_auth/projects/\")({\n staticData: {\n analytics: {\n name: \"projects.list\",\n },\n } satisfies RouteInfo,\n component: ProjectsOverview,\n errorComponent: ({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n ),\n notFoundComponent: () => {\n return <p>Projects not found</p>\n },\n validateSearch: searchSchema,\n loaderDeps: ({ search }) => ({\n search: search.search || \"\",\n }),\n loader: async ({ context, deps }) => {\n const allProjects = await context.trpcClient?.project.getAuthProjects.query()\n\n let projects = allProjects\n if (deps.search && deps.search.trim() !== \"\") {\n const searchTermLower = deps.search.toLowerCase()\n projects = allProjects?.filter(\n (project) =>\n project.name?.toLowerCase().includes(searchTermLower) ||\n project.description?.toLowerCase().includes(searchTermLower)\n )\n }\n\n return { projects }\n },\n})\n\nfunction ProjectsOverview() {\n const { projects } = Route.useLoaderData()\n const { search = \"\" } = Route.useSearch()\n const navigate = Route.useNavigate()\n const { slots } = useRouteContext({ strict: false })\n\n const handleSearch = (value: string) => {\n navigate({ search: { search: value }, replace: true })\n }\n\n return (\n <Container py>\n <ContentHeading className=\"pb-4\">\n <Trans>Projects</Trans>\n </ContentHeading>\n {slots?.projectsBanner && <Slot component={slots.projectsBanner} useShadowDOM={false} />}\n <ProjectsOverviewNavBar searchTerm={search} onSearch={handleSearch} />\n <div className=\"pt-5\">\n <ProjectCardView projects={projects} />\n </div>\n </Container>\n )\n}\n"],"mappings":";;cA2BW,gBAAC,KAAA,EAAA,UAAE,qBAAA,CAAA"}
1
+ {"version":3,"file":"projects-yiK0HGSA.mjs","names":["ProjectsContentProps","search","SplitNotFoundComponent","notFoundComponent"],"sources":["../../src/client/routes/_auth/projects/index.tsx?tsr-split=notFoundComponent"],"sourcesContent":["import { Suspense } from \"react\"\nimport { ErrorBoundary } from \"react-error-boundary\"\nimport { createFileRoute, useRouteContext } from \"@tanstack/react-router\"\nimport { ProjectsOverviewNavBar } from \"@/client/routes/_auth/projects/-components/ProjectOverviewNavBar\"\nimport { ProjectCardView } from \"@/client/routes/_auth/projects/-components/ProjectCardView\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { Container, ContentHeading, Spinner, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { z } from \"zod\"\nimport { Slot } from \"@/client/components/Slot\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\n\nconst searchSchema = z.object({\n search: z.string().optional(),\n})\n\nexport const Route = createFileRoute(\"/_auth/projects/\")({\n staticData: {\n analytics: {\n name: \"projects.list\",\n },\n } satisfies RouteInfo,\n component: ProjectsOverview,\n errorComponent: ({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n ),\n notFoundComponent: () => {\n return <p>Projects not found</p>\n },\n validateSearch: searchSchema,\n})\n\ninterface ProjectsContentProps {\n search: string\n}\n\nfunction ProjectsContent({ search }: ProjectsContentProps) {\n const [allProjects] = trpcReact.project.getAuthProjects.useSuspenseQuery()\n\n const normalizedSearch = search.trim().toLowerCase()\n const projects =\n allProjects && normalizedSearch\n ? allProjects.filter(\n (project) =>\n project.name?.toLowerCase().includes(normalizedSearch) ||\n project.description?.toLowerCase().includes(normalizedSearch)\n )\n : allProjects\n\n return <ProjectCardView projects={projects} />\n}\n\nexport function ProjectsOverview() {\n const { search = \"\" } = Route.useSearch()\n const navigate = Route.useNavigate()\n const { slots } = useRouteContext({ strict: false })\n\n const handleSearch = (value: string) => {\n navigate({ search: (prev) => ({ ...prev, search: value || undefined }), replace: true })\n }\n\n return (\n <Container py>\n <ContentHeading className=\"pb-4\">\n <Trans>Projects</Trans>\n </ContentHeading>\n {slots?.projectsBanner && (\n <ErrorBoundary fallbackRender={() => null}>\n <Suspense fallback={null}>\n <Slot component={slots.projectsBanner} useShadowDOM={false} />\n </Suspense>\n </ErrorBoundary>\n )}\n <ProjectsOverviewNavBar searchTerm={search} onSearch={handleSearch} />\n <div className=\"pt-5\">\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n )}\n >\n <Suspense\n fallback={\n <Stack distribution=\"center\" alignment=\"center\" direction=\"vertical\" className=\"py-12\">\n <Spinner variant=\"primary\" size=\"large\" />\n </Stack>\n }\n >\n <ProjectsContent search={search} />\n </Suspense>\n </ErrorBoundary>\n </div>\n </Container>\n )\n}\n"],"mappings":";;AAoCC,IAAAE,UAPU,gBAAC,KAAA,EAAA,UAAE,qBAAA,CAAA"}
@@ -0,0 +1,56 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { useEffect as t, useRef as n, useState as r } from "react";
3
+ import { createPortal as i } from "react-dom";
4
+ import { useRouteContext as a } from "@tanstack/react-router";
5
+ import { z as o } from "zod";
6
+ //#region src/client/components/Slot.tsx
7
+ function s({ children: a }) {
8
+ let o = n(null), [s, c] = r(null);
9
+ return t(() => {
10
+ o.current && c(o.current.shadowRoot ?? o.current.attachShadow({ mode: "open" }));
11
+ }, []), /*#__PURE__*/ e("div", {
12
+ ref: o,
13
+ style: { display: "contents" },
14
+ children: s && /*#__PURE__*/ i(a, s)
15
+ });
16
+ }
17
+ function c({ component: t, useShadowDOM: n = !0, currentService: r }) {
18
+ let { trpcClient: i } = a({ strict: !1 });
19
+ if (!i) return null;
20
+ let o = /*#__PURE__*/ e(t, { auroraContext: {
21
+ client: i,
22
+ currentService: r
23
+ } });
24
+ return n ? /*#__PURE__*/ e(s, { children: o }) : o;
25
+ }
26
+ var l = o.object({
27
+ labelKey: o.enum([
28
+ "Compute",
29
+ "Network",
30
+ "Storage",
31
+ "Services",
32
+ "Images",
33
+ "Flavors",
34
+ "Security Groups",
35
+ "Floating IPs",
36
+ "PCA (Clavis)"
37
+ ]).optional(),
38
+ to: o.string().optional(),
39
+ useParamAsLabel: o.string().optional(),
40
+ useParentTitleAsLabel: o.boolean().optional()
41
+ }), u = o.object({ name: o.string() }), d = o.object({
42
+ section: o.string().optional(),
43
+ service: o.string().optional(),
44
+ isDetail: o.boolean().optional(),
45
+ crumb: l.optional(),
46
+ sectionCrumb: l.optional(),
47
+ intermediateCrumb: l.optional(),
48
+ analytics: u.optional()
49
+ });
50
+ function f(e) {
51
+ return d.safeParse(e).success;
52
+ }
53
+ //#endregion
54
+ export { c as n, f as t };
55
+
56
+ //# sourceMappingURL=routeInfo-Ct5r4Gen.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeInfo-Ct5r4Gen.mjs","names":["useRef","useState","useEffect","createPortal","useRouteContext","SlotShadowRoot","children","ref","root","setRoot","current","shadowRoot","attachShadow","mode","div","style","display","Slot","component","Component","useShadowDOM","currentService","trpcClient","strict","content","auroraContext","client","z","CRUMB_LABEL_KEYS","CrumbSchema","object","labelKey","enum","optional","to","string","useParamAsLabel","useParentTitleAsLabel","boolean","AnalyticsSchema","name","RouteInfoSchema","section","service","isDetail","crumb","sectionCrumb","intermediateCrumb","analytics","isRouteInfo","data","safeParse","success"],"sources":["../../src/client/components/Slot.tsx","../../src/client/routes/routeInfo.ts"],"sourcesContent":["import { useRef, useState, useEffect, type ReactNode, type FC } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useRouteContext } from \"@tanstack/react-router\"\nimport type { SlotProps } from \"../AuroraApp\"\n\nfunction SlotShadowRoot({ children }: { children: ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n const [root, setRoot] = useState<ShadowRoot | null>(null)\n\n useEffect(() => {\n if (!ref.current) return\n setRoot(ref.current.shadowRoot ?? ref.current.attachShadow({ mode: \"open\" }))\n }, [])\n\n return (\n <div ref={ref} style={{ display: \"contents\" }}>\n {root && createPortal(children, root)}\n </div>\n )\n}\n\nexport function Slot({\n component: Component,\n useShadowDOM = true,\n currentService,\n}: {\n component: FC<SlotProps>\n useShadowDOM?: boolean\n currentService?: string\n}) {\n const { trpcClient } = useRouteContext({ strict: false })\n\n if (!trpcClient) return null\n\n const content = <Component auroraContext={{ client: trpcClient, currentService }} />\n\n if (!useShadowDOM) {\n return content\n }\n\n return <SlotShadowRoot>{content}</SlotShadowRoot>\n}\n","import { z } from \"zod\"\n\nexport const CRUMB_LABEL_KEYS = [\n \"Compute\",\n \"Network\",\n \"Storage\",\n \"Services\",\n \"Images\",\n \"Flavors\",\n \"Security Groups\",\n \"Floating IPs\",\n \"PCA (Clavis)\",\n] as const\n\nexport type CrumbLabelKey = (typeof CRUMB_LABEL_KEYS)[number]\n\nconst CrumbSchema = z.object({\n labelKey: z.enum(CRUMB_LABEL_KEYS).optional(),\n to: z.string().optional(),\n useParamAsLabel: z.string().optional(),\n useParentTitleAsLabel: z.boolean().optional(),\n})\n\nconst AnalyticsSchema = z.object({\n name: z.string(),\n})\n\nconst RouteInfoSchema = z.object({\n section: z.string().optional(),\n service: z.string().optional(),\n isDetail: z.boolean().optional(),\n crumb: CrumbSchema.optional(),\n sectionCrumb: CrumbSchema.optional(),\n intermediateCrumb: CrumbSchema.optional(),\n analytics: AnalyticsSchema.optional(),\n})\n\nexport type Crumb = z.infer<typeof CrumbSchema>\nexport type Analytics = z.infer<typeof AnalyticsSchema>\nexport type RouteInfo = z.infer<typeof RouteInfoSchema>\n\nexport function isRouteInfo(data: unknown): data is RouteInfo {\n return RouteInfoSchema.safeParse(data).success\n}\n"],"mappings":";;;;;;AAKA,SAASK,EAAe,EAAEC,eAAmC;CAC3D,IAAMC,IAAMP,EAAuB,IAAA,GAC7B,CAACQ,GAAMC,KAAWR,EAA4B,IAAA;CAOpD,OALAC,QAAU;EACHK,EAAIG,WACTD,EAAQF,EAAIG,QAAQC,cAAcJ,EAAIG,QAAQE,aAAa,EAAEC,MAAM,OAAO,CAAA,CAAA;CAC5E,GAAG,CAAA,CAAE,GAGH,gBAACC,OAAAA;EAASP;EAAKQ,OAAO,EAAEC,SAAS,WAAW;YACzCR,KAAQL,gBAAaG,GAAUE,CAAAA;;AAGtC;AAEA,SAAgBS,EAAK,EACnBC,WAAWC,GACXC,kBAAe,IACfC,qBAKD;CACC,IAAM,EAAEC,kBAAelB,EAAgB,EAAEmB,QAAQ,GAAM,CAAA;CAEvD,IAAI,CAACD,GAAY,OAAO;CAExB,IAAME,IAAU,gBAACL,GAAAA,EAAUM,eAAe;EAAEC,QAAQJ;EAAYD;CAAe,EAAA,CAAA;CAM/E,OAJKD,IAIE,gBAACf,GAAAA,EAAAA,UAAgBmB,EAAAA,CAAAA,IAHfA;AAIX;ACzBA,IAAMK,IAAcF,EAAEG,OAAO;CAC3BC,UAAUJ,EAAEK,KAAKJ;EAdjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAMiBA,CAAAA,EAAkBK,SAAQ;CAC3CC,IAAIP,EAAEQ,OAAM,EAAGF,SAAQ;CACvBG,iBAAiBT,EAAEQ,OAAM,EAAGF,SAAQ;CACpCI,uBAAuBV,EAAEW,QAAO,EAAGL,SAAQ;AAC7C,CAAA,GAEMM,IAAkBZ,EAAEG,OAAO,EAC/BU,MAAMb,EAAEQ,OAAM,EAChB,CAAA,GAEMM,IAAkBd,EAAEG,OAAO;CAC/BY,SAASf,EAAEQ,OAAM,EAAGF,SAAQ;CAC5BU,SAAShB,EAAEQ,OAAM,EAAGF,SAAQ;CAC5BW,UAAUjB,EAAEW,QAAO,EAAGL,SAAQ;CAC9BY,OAAOhB,EAAYI,SAAQ;CAC3Ba,cAAcjB,EAAYI,SAAQ;CAClCc,mBAAmBlB,EAAYI,SAAQ;CACvCe,WAAWT,EAAgBN,SAAQ;AACrC,CAAA;AAMA,SAAgBgB,EAAYC,GAAa;CACvC,OAAOT,EAAgBU,UAAUD,CAAAA,EAAME;AACzC"}
@@ -1015,6 +1015,43 @@ export declare const trpcReactClient: TRPCClient<import('@trpc/server').TRPCBuil
1015
1015
  }[] | undefined;
1016
1016
  meta: object;
1017
1017
  }>;
1018
+ getProject: import('@trpc/server').TRPCQueryProcedure<{
1019
+ input: {
1020
+ projectId: string;
1021
+ };
1022
+ output: {
1023
+ id: string;
1024
+ name: string;
1025
+ enabled: boolean;
1026
+ domain_id?: string | null | undefined;
1027
+ parent_id?: string | null | undefined;
1028
+ is_domain?: boolean | null | undefined;
1029
+ tags?: string[] | null | undefined;
1030
+ options?: Record<string, string | boolean> | null | undefined;
1031
+ description?: string | null | undefined;
1032
+ links?: {
1033
+ self?: string | null | undefined;
1034
+ } | undefined;
1035
+ domain_name?: string | undefined;
1036
+ parents?: {
1037
+ project: {
1038
+ id: string;
1039
+ name: string;
1040
+ enabled: boolean;
1041
+ domain_id?: string | null | undefined;
1042
+ parent_id?: string | null | undefined;
1043
+ is_domain?: boolean | null | undefined;
1044
+ tags?: string[] | null | undefined;
1045
+ options?: Record<string, string | boolean> | null | undefined;
1046
+ description?: string | null | undefined;
1047
+ links?: {
1048
+ self?: string | null | undefined;
1049
+ } | undefined;
1050
+ };
1051
+ }[] | undefined;
1052
+ } | null;
1053
+ meta: object;
1054
+ }>;
1018
1055
  }>>;
1019
1056
  }> & import('@trpc/server').TRPCDecorateCreateRouterOptions<{
1020
1057
  storage: {
@@ -1668,6 +1668,43 @@ declare const buildBaseRouter: (policyDir: string) => _trpc_server.TRPCBuiltRout
1668
1668
  }[] | undefined;
1669
1669
  meta: object;
1670
1670
  }>;
1671
+ getProject: _trpc_server.TRPCQueryProcedure<{
1672
+ input: {
1673
+ projectId: string;
1674
+ };
1675
+ output: {
1676
+ id: string;
1677
+ name: string;
1678
+ enabled: boolean;
1679
+ domain_id?: string | null | undefined;
1680
+ parent_id?: string | null | undefined;
1681
+ is_domain?: boolean | null | undefined;
1682
+ tags?: string[] | null | undefined;
1683
+ options?: Record<string, string | boolean> | null | undefined;
1684
+ description?: string | null | undefined;
1685
+ links?: {
1686
+ self?: string | null | undefined;
1687
+ } | undefined;
1688
+ domain_name?: string | undefined;
1689
+ parents?: {
1690
+ project: {
1691
+ id: string;
1692
+ name: string;
1693
+ enabled: boolean;
1694
+ domain_id?: string | null | undefined;
1695
+ parent_id?: string | null | undefined;
1696
+ is_domain?: boolean | null | undefined;
1697
+ tags?: string[] | null | undefined;
1698
+ options?: Record<string, string | boolean> | null | undefined;
1699
+ description?: string | null | undefined;
1700
+ links?: {
1701
+ self?: string | null | undefined;
1702
+ } | undefined;
1703
+ };
1704
+ }[] | undefined;
1705
+ } | null;
1706
+ meta: object;
1707
+ }>;
1671
1708
  }>>;
1672
1709
  }> & _trpc_server.TRPCDecorateCreateRouterOptions<{
1673
1710
  storage: {
@@ -33490,36 +33490,29 @@ __name(createS3Client, "createS3Client");
33490
33490
  // src/server/Storage/cephProcedure.ts
33491
33491
  var NO_CEPH_CREDENTIALS = "NO_CEPH_CREDENTIALS";
33492
33492
  function resolveS3Config(ctx) {
33493
- try {
33494
- const service = ctx.openstack?.service("ceph");
33495
- if (!service) {
33496
- throw new Error("Ceph service not found in OpenStack service catalog");
33497
- }
33498
- const endpoint = service.getEndpoint?.();
33499
- if (!endpoint) {
33500
- throw new Error("Ceph service endpoint not found in catalog. Ensure the Ceph service is registered in OpenStack.");
33501
- }
33502
- const swiftIndex = endpoint.indexOf("/swift/");
33503
- const baseEndpoint = swiftIndex !== -1 ? endpoint.substring(0, swiftIndex) : endpoint;
33504
- const endpoints = service.availableEndpoints?.();
33505
- const openstackRegion = endpoints?.[0]?.region;
33506
- if (!openstackRegion) {
33507
- throw new Error("Region not found in Ceph service endpoints");
33508
- }
33509
- if (!ctx.cephRegion) {
33510
- throw new Error("cephRegion is required. Pass it via createServer({ cephRegion: '...' }).");
33511
- }
33512
- const region = ctx.cephRegion;
33513
- return {
33514
- endpoint: baseEndpoint,
33515
- region
33516
- };
33517
- } catch (error) {
33518
- console.error("[ceph] Failed to resolve Ceph service from catalog:", error);
33519
- throw new Error("Ceph service not found in catalog. Ensure the Ceph service is registered in OpenStack.", {
33520
- cause: error
33521
- });
33493
+ const service = ctx.openstack?.service("ceph");
33494
+ if (!service) {
33495
+ throw new Error("Ceph service not found in OpenStack service catalog");
33496
+ }
33497
+ const endpoint = service.getEndpoint?.();
33498
+ if (!endpoint) {
33499
+ throw new Error("Ceph service endpoint not found in catalog. Ensure the Ceph service is registered in OpenStack.");
33522
33500
  }
33501
+ const swiftIndex = endpoint.indexOf("/swift/");
33502
+ const baseEndpoint = swiftIndex !== -1 ? endpoint.substring(0, swiftIndex) : endpoint;
33503
+ const endpoints = service.availableEndpoints?.();
33504
+ const openstackRegion = endpoints?.[0]?.region;
33505
+ if (!openstackRegion) {
33506
+ throw new Error("Region not found in Ceph service endpoints");
33507
+ }
33508
+ if (!ctx.cephRegion) {
33509
+ throw new Error("Ceph region not configured");
33510
+ }
33511
+ const region = ctx.cephRegion;
33512
+ return {
33513
+ endpoint: baseEndpoint,
33514
+ region
33515
+ };
33523
33516
  }
33524
33517
  __name(resolveS3Config, "resolveS3Config");
33525
33518
  var cephCredentialMiddleware = projectScopedProcedure.use(/* @__PURE__ */ __name(async function resolveCeph(opts) {
@@ -35884,6 +35877,28 @@ var projectRouter = {
35884
35877
  }
35885
35878
  projects.sort((a, b) => a.name.localeCompare(b.name));
35886
35879
  return projects;
35880
+ }),
35881
+ getProject: protectedProcedure.input(import_zod20.z.object({
35882
+ projectId: import_zod20.z.string()
35883
+ })).query(async ({ ctx, input }) => {
35884
+ if (!ctx.openstack) {
35885
+ throw new import_server16.TRPCError({
35886
+ code: "UNAUTHORIZED",
35887
+ message: "No authenticated session"
35888
+ });
35889
+ }
35890
+ const token = ctx.openstack.getToken();
35891
+ if (!token?.authToken) {
35892
+ throw new import_server16.TRPCError({
35893
+ code: "UNAUTHORIZED",
35894
+ message: "No auth token available"
35895
+ });
35896
+ }
35897
+ const response = await callIdentityAPI(ctx.identityEndpoint, token.authToken, `projects/${input.projectId}`).catch(() => null);
35898
+ if (!response) return null;
35899
+ const data = await response.json();
35900
+ const parsed = projectResponseSchema.safeParse(data);
35901
+ return parsed.success ? parsed.data.project : null;
35887
35902
  })
35888
35903
  };
35889
35904
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobaltcore-dev/aurora",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "private": false,
5
5
  "description": "Aurora OpenStack dashboard — server and client library",
6
6
  "license": "Apache-2.0",
@@ -1,28 +0,0 @@
1
- import { jsx as e } from "react/jsx-runtime";
2
- import { useEffect as t, useRef as n, useState as r } from "react";
3
- import { createPortal as i } from "react-dom";
4
- import { useRouteContext as a } from "@tanstack/react-router";
5
- //#region src/client/components/Slot.tsx
6
- function o({ children: a }) {
7
- let o = n(null), [s, c] = r(null);
8
- return t(() => {
9
- o.current && c(o.current.shadowRoot ?? o.current.attachShadow({ mode: "open" }));
10
- }, []), /*#__PURE__*/ e("div", {
11
- ref: o,
12
- style: { display: "contents" },
13
- children: s && /*#__PURE__*/ i(a, s)
14
- });
15
- }
16
- function s({ component: t, useShadowDOM: n = !0, currentService: r }) {
17
- let { trpcClient: i } = a({ strict: !1 });
18
- if (!i) return null;
19
- let s = /*#__PURE__*/ e(t, { auroraContext: {
20
- client: i,
21
- currentService: r
22
- } });
23
- return n ? /*#__PURE__*/ e(o, { children: s }) : s;
24
- }
25
- //#endregion
26
- export { s as t };
27
-
28
- //# sourceMappingURL=Slot-CWb612-_.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Slot-CWb612-_.mjs","names":["useRef","useState","useEffect","createPortal","useRouteContext","SlotShadowRoot","children","ref","root","setRoot","current","shadowRoot","attachShadow","mode","div","style","display","Slot","component","Component","useShadowDOM","currentService","trpcClient","strict","content","auroraContext","client"],"sources":["../../src/client/components/Slot.tsx"],"sourcesContent":["import { useRef, useState, useEffect, type ReactNode, type FC } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useRouteContext } from \"@tanstack/react-router\"\nimport type { SlotProps } from \"../AuroraApp\"\n\nfunction SlotShadowRoot({ children }: { children: ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n const [root, setRoot] = useState<ShadowRoot | null>(null)\n\n useEffect(() => {\n if (!ref.current) return\n setRoot(ref.current.shadowRoot ?? ref.current.attachShadow({ mode: \"open\" }))\n }, [])\n\n return (\n <div ref={ref} style={{ display: \"contents\" }}>\n {root && createPortal(children, root)}\n </div>\n )\n}\n\nexport function Slot({\n component: Component,\n useShadowDOM = true,\n currentService,\n}: {\n component: FC<SlotProps>\n useShadowDOM?: boolean\n currentService?: string\n}) {\n const { trpcClient } = useRouteContext({ strict: false })\n\n if (!trpcClient) return null\n\n const content = <Component auroraContext={{ client: trpcClient, currentService }} />\n\n if (!useShadowDOM) {\n return content\n }\n\n return <SlotShadowRoot>{content}</SlotShadowRoot>\n}\n"],"mappings":";;;;;AAKA,SAASK,EAAe,EAAEC,eAAmC;CAC3D,IAAMC,IAAMP,EAAuB,IAAA,GAC7B,CAACQ,GAAMC,KAAWR,EAA4B,IAAA;CAOpD,OALAC,QAAU;EACHK,EAAIG,WACTD,EAAQF,EAAIG,QAAQC,cAAcJ,EAAIG,QAAQE,aAAa,EAAEC,MAAM,OAAO,CAAA,CAAA;CAC5E,GAAG,CAAA,CAAE,GAGH,gBAACC,OAAAA;EAASP;EAAKQ,OAAO,EAAEC,SAAS,WAAW;YACzCR,KAAQL,gBAAaG,GAAUE,CAAAA;;AAGtC;AAEA,SAAgBS,EAAK,EACnBC,WAAWC,GACXC,kBAAe,IACfC,qBAKD;CACC,IAAM,EAAEC,kBAAelB,EAAgB,EAAEmB,QAAQ,GAAM,CAAA;CAEvD,IAAI,CAACD,GAAY,OAAO;CAExB,IAAME,IAAU,gBAACL,GAAAA,EAAUM,eAAe;EAAEC,QAAQJ;EAAYD;CAAe,EAAA,CAAA;CAM/E,OAJKD,IAIE,gBAACf,GAAAA,EAAAA,UAAgBmB,EAAAA,CAAAA,IAHfA;AAIX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_floatingIpId-De0hCSSN2.mjs","names":["formatFloatingIpStatus","status","charAt","slice","toLowerCase","Fragment","DescriptionDefinition","DescriptionList","DescriptionTerm","Stack","TwoColumnDescriptionList","items","mid","Math","ceil","length","firstColumn","slice","secondColumn","gap","className","alignTerms","map","label","value","Stack","ButtonRow","Button","ContentHeading","formatFloatingIpStatus","TwoColumnDescriptionList","FloatingIpActionModals","FloatingIpDetailsView","floatingIp","useLingui","basicInfoItems","label","t","value","id","description","project_id","status","created_at","Date","toLocaleString","updated_at","tags","join","networkRoutingItems","floating_ip_address","floating_network_id","fixed_ip_address","port_details","name","mac_address","network_id","device_owner","device_id","router_id","port_id","qos_policy_id","port_forwardings","map","port","dnsItems","dns_domain","dns_name","p","className","toggleEditModal","toggleAttachModal","toggleDetachModal","toggleReleaseModal","onClick","direction","gap","items","useNavigate","Button","ContentHeading","Stack","Spinner","Trans","useProjectId","trpcReact","FloatingIpDetailsView","Route","RouteComponent","floatingIpId","useParams","projectId","navigate","data","floatingIp","isLoading","isError","error","network","getById","useQuery","project_id","floatingip_id","handleBack","to","params","errorMessage","message","floating_ip_address","component"],"sources":["../../src/client/utils/formatFloatingIpStatus.ts","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/-components/TwoColumnDescriptionList.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/-components/-details/FloatingIpDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/index.tsx?tsr-split=component"],"sourcesContent":["import type { FloatingIpStatus } from \"@/server/Network/types/floatingIp\"\n\n/**\n * Formats a floating IP status value from uppercase enum to title case.\n * Example: \"ACTIVE\" → \"Active\", \"DOWN\" → \"Down\", \"ERROR\" → \"Error\"\n */\nexport const formatFloatingIpStatus = (status: FloatingIpStatus) => {\n return status.charAt(0) + status.slice(1).toLowerCase()\n}\n","import { Fragment } from \"react\"\nimport { DescriptionDefinition, DescriptionList, DescriptionTerm, Stack } from \"@cloudoperators/juno-ui-components\"\n\nexport type DetailListItem = {\n label: string\n value: string\n}\n\ninterface TwoColumnDescriptionListProps {\n items: DetailListItem[]\n}\n\nexport const TwoColumnDescriptionList = ({ items }: TwoColumnDescriptionListProps) => {\n const mid = Math.ceil(items.length / 2)\n const firstColumn = items.slice(0, mid)\n const secondColumn = items.slice(mid)\n\n return (\n <Stack gap=\"6\" className=\"grid grid-cols-2\">\n <DescriptionList alignTerms=\"right\">\n {firstColumn.map(({ label, value }) => (\n <Fragment key={label}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>{value}</DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n\n <DescriptionList alignTerms=\"right\">\n {secondColumn.map(({ label, value }) => (\n <Fragment key={label}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>{value}</DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n </Stack>\n )\n}\n","import { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Stack, ButtonRow, Button, ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport type { FloatingIp } from \"@/server/Network/types/floatingIp\"\nimport { formatFloatingIpStatus } from \"@/client/utils/formatFloatingIpStatus\"\nimport { DetailListItem, TwoColumnDescriptionList } from \"../TwoColumnDescriptionList\"\nimport { FloatingIpActionModals } from \"../../../-components/-modals/FloatingIpActionModals\"\n\ninterface FloatingIpDetailsViewProps {\n floatingIp: FloatingIp\n}\n\nexport const FloatingIpDetailsView = ({ floatingIp }: FloatingIpDetailsViewProps) => {\n const { t } = useLingui()\n\n const basicInfoItems: DetailListItem[] = [\n { label: t`ID`, value: floatingIp.id },\n { label: t`Description`, value: floatingIp.description || `—` },\n { label: t`Project ID`, value: floatingIp.project_id || `—` },\n { label: t`Status`, value: formatFloatingIpStatus(floatingIp.status) },\n { label: t`Created At`, value: floatingIp.created_at ? new Date(floatingIp.created_at).toLocaleString() : `—` },\n { label: t`Updated At`, value: floatingIp.updated_at ? new Date(floatingIp.updated_at).toLocaleString() : `—` },\n { label: t`Tags`, value: floatingIp.tags?.join(\", \") || `—` },\n ]\n\n const networkRoutingItems: DetailListItem[] = [\n { label: t`Floating IP Address`, value: floatingIp.floating_ip_address || `—` },\n { label: t`Floating Network`, value: floatingIp.floating_network_id || `—` },\n { label: t`Fixed IP Address`, value: floatingIp.fixed_ip_address || `—` },\n { label: t`Port Name`, value: floatingIp.port_details?.name || `—` },\n { label: t`MAC Address`, value: floatingIp.port_details?.mac_address || `—` },\n { label: t`Network ID`, value: floatingIp.port_details?.network_id || `—` },\n { label: t`Device Owner`, value: floatingIp.port_details?.device_owner || `—` },\n { label: t`Device ID`, value: floatingIp.port_details?.device_id || `—` },\n { label: t`Router ID`, value: floatingIp.router_id || `—` },\n { label: t`Port ID`, value: floatingIp.port_id || `—` },\n { label: t`QoS Policy ID`, value: floatingIp.qos_policy_id || `—` },\n { label: t`Port Forwarding`, value: floatingIp.port_forwardings?.map((port) => port.id).join(\", \") || `—` },\n ]\n\n const dnsItems: DetailListItem[] = [\n { label: t`DNS Domain`, value: floatingIp.dns_domain || `—` },\n { label: t`DNS Name`, value: floatingIp.dns_name || `—` },\n ]\n\n return (\n <>\n <p className=\"text-theme-secondary mt-2 text-sm\">\n <Trans>\n Full lifecycle management of Floating IPs, including attachment, port association/disassociation, DNS\n settings, and deletion\n </Trans>\n </p>\n\n <FloatingIpActionModals floatingIp={floatingIp}>\n {({ toggleEditModal, toggleAttachModal, toggleDetachModal, toggleReleaseModal }) => (\n <ButtonRow>\n <Button onClick={toggleEditModal}>{t`Edit Description`}</Button>\n <Button onClick={toggleAttachModal}>{t`Attach`}</Button>\n <Button onClick={toggleDetachModal}>{t`Detach`}</Button>\n <Button onClick={toggleReleaseModal}>{t`Release`}</Button>\n </ButtonRow>\n )}\n </FloatingIpActionModals>\n\n <Stack direction=\"vertical\" gap=\"6\" className=\"my-6\">\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Basic Info</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={basicInfoItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Network & Routing</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={networkRoutingItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>DNS</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={dnsItems} />\n </Stack>\n </Stack>\n </>\n )\n}\n","import { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport { Button, ContentHeading, Stack, Spinner } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { FloatingIpDetailsView } from \"./-components/-details/FloatingIpDetailsView\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/$floatingIpId/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.detail\",\n },\n isDetail: true,\n sectionCrumb: { labelKey: \"Network\" },\n crumb: { labelKey: \"Floating IPs\", to: \"/projects/$projectId/network/floatingips\" },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const floatingIp = await context.trpcClient?.network.floatingIp.getById.query({\n project_id: params.projectId,\n floatingip_id: params.floatingIpId,\n })\n return { floatingIpAddress: floatingIp?.floating_ip_address ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.floatingIpAddress ?? \"Floating IP\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { floatingIpId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n\n // Fetch floating IP details\n const {\n data: floatingIp,\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.getById.useQuery({\n project_id: projectId,\n floatingip_id: floatingIpId,\n })\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId },\n })\n }\n\n // Loading state\n if (isLoading) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading Floating IP Details...</Trans>\n </Stack>\n )\n }\n\n // Error state\n if (isError) {\n const errorMessage = error?.message || \"Unknown error\"\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-error font-semibold\">\n <Trans>Error loading floating IP</Trans>\n </p>\n <p className=\"text-theme-highest\">{errorMessage}</p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n </Stack>\n )\n }\n\n // No data state\n if (!floatingIp) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-secondary\">\n <Trans>Floating IP not found</Trans>\n </p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Success state\n return (\n <>\n <ContentHeading>{floatingIp.floating_ip_address}</ContentHeading>\n <FloatingIpDetailsView floatingIp={floatingIp} />\n </>\n )\n}\n"],"mappings":"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"}