@cobaltcore-dev/aurora 0.20.1 → 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.
- package/dist/client/{ContentHeader-BIScbvb4.mjs → ContentHeader-CIAzorGI.mjs} +2 -3
- package/dist/client/{ContentHeader-BIScbvb4.mjs.map → ContentHeader-CIAzorGI.mjs.map} +1 -1
- package/dist/client/{_flavorId-sS1sg_DZ.mjs → _flavorId-BMX239RH.mjs} +3 -3
- package/dist/client/{_flavorId-sS1sg_DZ.mjs.map → _flavorId-BMX239RH.mjs.map} +1 -1
- package/dist/client/{_flavorId-BQY7YhNx.mjs → _flavorId-BaNJ1CDY.mjs} +2 -2
- package/dist/client/{_flavorId-BQY7YhNx.mjs.map → _flavorId-BaNJ1CDY.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-DFCaWI9K.mjs → _floatingIpId-DQFtZNeg.mjs} +2 -2
- package/dist/client/{_floatingIpId-DFCaWI9K.mjs.map → _floatingIpId-DQFtZNeg.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-De0hCSSN2.mjs → _floatingIpId-E6x99cmW.mjs} +2 -2
- package/dist/client/_floatingIpId-E6x99cmW.mjs.map +1 -0
- package/dist/client/{_imageId-D8HiDS3P.mjs → _imageId-C2662dZr.mjs} +2 -2
- package/dist/client/{_imageId-D8HiDS3P.mjs.map → _imageId-C2662dZr.mjs.map} +1 -1
- package/dist/client/{_projectId-CoMD6nq6.mjs → _projectId-B4ScifQf.mjs} +3 -3
- package/dist/client/{_projectId-CoMD6nq6.mjs.map → _projectId-B4ScifQf.mjs.map} +1 -1
- package/dist/client/{_projectId-D8FHe0gr.mjs → _projectId-CYq4KZXB.mjs} +3 -3
- package/dist/client/{_projectId-D8FHe0gr.mjs.map → _projectId-CYq4KZXB.mjs.map} +1 -1
- package/dist/client/{_projectId-hMtrqW6m.mjs → _projectId-DJLjspKf.mjs} +23 -24
- package/dist/client/{_projectId-hMtrqW6m.mjs.map → _projectId-DJLjspKf.mjs.map} +1 -1
- package/dist/client/{_projectId-MjFv839t.mjs → _projectId-DxgPaiA7.mjs} +2 -2
- package/dist/client/{_projectId-MjFv839t.mjs.map → _projectId-DxgPaiA7.mjs.map} +1 -1
- package/dist/client/{_storageType-CH2khFcZ.mjs → _storageType-DsbBodWF.mjs} +2 -2
- package/dist/client/{_storageType-CH2khFcZ.mjs.map → _storageType-DsbBodWF.mjs.map} +1 -1
- package/dist/client/{_storageType-D-1H6SX1.mjs → _storageType-WwAATdsa.mjs} +886 -886
- package/dist/client/{_storageType-D-1H6SX1.mjs.map → _storageType-WwAATdsa.mjs.map} +1 -1
- package/dist/client/{flavors-D5aTQJT1.mjs → flavors-Bwjig3k2.mjs} +3 -3
- package/dist/client/{flavors-D5aTQJT1.mjs.map → flavors-Bwjig3k2.mjs.map} +1 -1
- package/dist/client/{flavors-TqwbWt4R.mjs → flavors-C7PVJUqZ.mjs} +2 -2
- package/dist/client/{flavors-TqwbWt4R.mjs.map → flavors-C7PVJUqZ.mjs.map} +1 -1
- package/dist/client/{images-sNuJa6ce.mjs → images-CD7DNwru.mjs} +2 -2
- package/dist/client/{images-sNuJa6ce.mjs.map → images-CD7DNwru.mjs.map} +1 -1
- package/dist/client/{images-CkW8zNjs.mjs → images-CfBrglGJ.mjs} +9 -9
- package/dist/client/{images-CkW8zNjs.mjs.map → images-CfBrglGJ.mjs.map} +1 -1
- package/dist/client/index.js +454 -317
- package/dist/client/index.js.map +1 -1
- package/dist/client/{objects-B3Z8h4RU.mjs → objects-CEBrL7k-.mjs} +2 -2
- package/dist/client/{objects-B3Z8h4RU.mjs.map → objects-CEBrL7k-.mjs.map} +1 -1
- package/dist/client/{objects-CGOfO00N.mjs → objects-DvIxpzGI.mjs} +3 -3
- package/dist/client/{objects-CGOfO00N.mjs.map → objects-DvIxpzGI.mjs.map} +1 -1
- package/dist/client/{pca-BClYQElh.mjs → pca-CpMqoF00.mjs} +3 -3
- package/dist/client/{pca-BClYQElh.mjs.map → pca-CpMqoF00.mjs.map} +1 -1
- package/dist/client/{pca-B4_2DqT2.mjs → pca-ZgGU0UPF.mjs} +2 -2
- package/dist/client/{pca-B4_2DqT2.mjs.map → pca-ZgGU0UPF.mjs.map} +1 -1
- package/dist/client/projects-DvSiI5Vg.mjs.map +1 -1
- package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
- package/dist/client/routeInfo-Ct5r4Gen.mjs +56 -0
- package/dist/client/routeInfo-Ct5r4Gen.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/client/Slot-CWb612-_.mjs +0 -28
- package/dist/client/Slot-CWb612-_.mjs.map +0 -1
- package/dist/client/_floatingIpId-De0hCSSN2.mjs.map +0 -1
- package/dist/client/projects-4wFhznPY.mjs +0 -34
- package/dist/client/projects-4wFhznPY.mjs.map +0 -1
- package/dist/client/projects-wd6Yc-GU.mjs +0 -107
- package/dist/client/projects-wd6Yc-GU.mjs.map +0 -1
- package/dist/client/routeInfo-CdTRlSxv.mjs +0 -32
- 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-
|
|
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-
|
|
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-
|
|
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-
|
|
20
|
+
component: r(() => import("./pca-CpMqoF00.mjs"), "component")
|
|
21
21
|
});
|
|
22
22
|
//#endregion
|
|
23
23
|
export { o as t };
|
|
24
24
|
|
|
25
|
-
//# sourceMappingURL=pca-
|
|
25
|
+
//# sourceMappingURL=pca-ZgGU0UPF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pca-
|
|
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 {
|
|
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 {
|
|
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"}
|
package/package.json
CHANGED
|
@@ -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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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { K as e, tt as t } from "./build-DgeVmENN.mjs";
|
|
2
|
-
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
|
-
import { createFileRoute as i, lazyRouteComponent as a } from "@tanstack/react-router";
|
|
4
|
-
import { z as o } from "zod";
|
|
5
|
-
//#region src/client/routes/_auth/projects/index.tsx
|
|
6
|
-
var s = () => import("./projects-yiK0HGSA.mjs"), c = () => import("./projects-DvSiI5Vg.mjs"), l = () => import("./projects-wd6Yc-GU.mjs"), u = o.object({ search: o.string().optional() }), d = i("/_auth/projects/")({
|
|
7
|
-
staticData: { analytics: { name: "projects.list" } },
|
|
8
|
-
component: a(l, "component"),
|
|
9
|
-
pendingComponent: () => /*#__PURE__*/ r(t, {
|
|
10
|
-
className: "fixed inset-0",
|
|
11
|
-
distribution: "center",
|
|
12
|
-
alignment: "center",
|
|
13
|
-
children: [/*#__PURE__*/ n("div", { className: "absolute inset-0 backdrop-blur-sm" }), /*#__PURE__*/ n(e, {
|
|
14
|
-
variant: "primary",
|
|
15
|
-
size: "large"
|
|
16
|
-
})]
|
|
17
|
-
}),
|
|
18
|
-
errorComponent: a(c, "errorComponent"),
|
|
19
|
-
notFoundComponent: a(s, "notFoundComponent"),
|
|
20
|
-
validateSearch: u,
|
|
21
|
-
loaderDeps: ({ search: e }) => ({ search: e.search || "" }),
|
|
22
|
-
loader: async ({ context: e, deps: t }) => {
|
|
23
|
-
let n = await e.trpcClient?.project.getAuthProjects.query(), r = n;
|
|
24
|
-
if (t.search && t.search.trim() !== "") {
|
|
25
|
-
let e = t.search.toLowerCase();
|
|
26
|
-
r = n?.filter((t) => t.name?.toLowerCase().includes(e) || t.description?.toLowerCase().includes(e));
|
|
27
|
-
}
|
|
28
|
-
return { projects: r };
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
//#endregion
|
|
32
|
-
export { d as t };
|
|
33
|
-
|
|
34
|
-
//# sourceMappingURL=projects-4wFhznPY.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"projects-4wFhznPY.mjs","names":["createFileRoute","Spinner","Stack","z","searchSchema","object","search","string","optional","Route","staticData","analytics","name","RouteInfo","component","lazyRouteComponent","$$splitComponentImporter","pendingComponent","errorComponent","$$splitErrorComponentImporter","notFoundComponent","$$splitNotFoundComponentImporter","validateSearch","loaderDeps","loader","context","deps","allProjects","trpcClient","project","getAuthProjects","query","projects","trim","searchTermLower","toLowerCase","filter","includes","description"],"sources":["../../src/client/routes/_auth/projects/index.tsx"],"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, Spinner, Stack } 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 pendingComponent: () => (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\">\n <div className=\"absolute inset-0 backdrop-blur-sm\" />\n <Spinner variant=\"primary\" size=\"large\" />\n </Stack>\n ),\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":";;;;;2IAYMI,IAAeD,EAAEE,OAAO,EAC5BC,QAAQH,EAAEI,OAAM,EAAGC,SAAQ,EAC7B,CAAA,GAEaC,IAAQT,EAAgB,kBAAA,EAAoB;CACvDU,YAAY,EACVC,WAAW,EACTC,MAAM,gBACR,EACF;CACAE,WAASC,EAAAC,GAAA,WAAA;CACTC,wBACE,gBAAC,GAAA;EAAM,WAAU;EAAgB,cAAa;EAAS,WAAU;aAC/D,gBAAC,OAAA,EAAI,WAAU,oCAAA,CAAA,GACf,gBAAC,GAAA;GAAQ,SAAQ;GAAU,MAAK;;;CAGpCC,gBAAcH,EAAAI,GAAA,gBAAA;CAGdC,mBAAiBL,EAAAM,GAAA,mBAAA;CAGjBC,gBAAgBlB;CAChBmB,aAAa,EAAEjB,iBAAc,EAC3BA,QAAQA,EAAOA,UAAU,GAC3B;CACAkB,QAAQ,OAAO,EAAEC,YAASC,cAAM;EAC9B,IAAMC,IAAc,MAAMF,EAAQG,YAAYC,QAAQC,gBAAgBC,MAAAA,GAElEC,IAAWL;EACf,IAAID,EAAKpB,UAAUoB,EAAKpB,OAAO2B,KAAI,MAAO,IAAI;GAC5C,IAAMC,IAAkBR,EAAKpB,OAAO6B,YAAW;GAC/CH,IAAWL,GAAaS,QACrBP,MACCA,EAAQjB,MAAMuB,YAAAA,EAAcE,SAASH,CAAAA,KACrCL,EAAQS,aAAaH,YAAAA,EAAcE,SAASH,CAAAA,CAAAA;EAElD;EAEA,OAAO,EAAEF,YAAS;CACpB;AACF,CAAA"}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { Y as e, Z as t, n, x as r } from "./build-DgeVmENN.mjs";
|
|
2
|
-
import { t as i } from "./Slot-CWb612-_.mjs";
|
|
3
|
-
import { t as a } from "./projects-4wFhznPY.mjs";
|
|
4
|
-
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
|
-
import { useEffect as c, useRef as l, useState as u } from "react";
|
|
6
|
-
import { useNavigate as d, useRouteContext as f } from "@tanstack/react-router";
|
|
7
|
-
import { Trans as p, useLingui as m } from "@lingui/react";
|
|
8
|
-
//#region src/client/routes/_auth/projects/-components/ProjectOverviewNavBar.tsx
|
|
9
|
-
function h({ onSearch: e, searchTerm: t = "" }) {
|
|
10
|
-
let { i18n: r, _: i } = m(), a = l(null), s = l(!1), [d, f] = u(t);
|
|
11
|
-
return c(() => {
|
|
12
|
-
!s.current && !a.current && t !== d && f(t);
|
|
13
|
-
}, [t]), c(() => () => {
|
|
14
|
-
a.current && clearTimeout(a.current);
|
|
15
|
-
}, []), /*#__PURE__*/ o(n, {
|
|
16
|
-
className: "w-full",
|
|
17
|
-
type: "text",
|
|
18
|
-
placeholder: r._({ id: "YIix5Y" }),
|
|
19
|
-
onChange: (t) => {
|
|
20
|
-
let n = t.target.value;
|
|
21
|
-
f(n), a.current && clearTimeout(a.current), a.current = setTimeout(() => {
|
|
22
|
-
a.current = null, e(n);
|
|
23
|
-
}, 300);
|
|
24
|
-
},
|
|
25
|
-
onFocus: () => {
|
|
26
|
-
s.current = !0;
|
|
27
|
-
},
|
|
28
|
-
onBlur: () => {
|
|
29
|
-
s.current = !1;
|
|
30
|
-
},
|
|
31
|
-
onClear: () => {
|
|
32
|
-
a.current &&= (clearTimeout(a.current), null), f(""), e("");
|
|
33
|
-
},
|
|
34
|
-
value: d
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region src/client/routes/_auth/projects/-components/ProjectCardView.tsx
|
|
39
|
-
function g({ project: e }) {
|
|
40
|
-
let t = d();
|
|
41
|
-
return /*#__PURE__*/ s(r, {
|
|
42
|
-
padding: !0,
|
|
43
|
-
onClick: () => t({
|
|
44
|
-
to: "/projects/$projectId",
|
|
45
|
-
params: { projectId: e.id }
|
|
46
|
-
}),
|
|
47
|
-
className: "flex flex-col gap-4",
|
|
48
|
-
children: [/*#__PURE__*/ s("div", {
|
|
49
|
-
className: "flex min-w-0 flex-col",
|
|
50
|
-
children: [/*#__PURE__*/ o("p", {
|
|
51
|
-
className: "text-theme-light text-xs leading-5 font-normal",
|
|
52
|
-
children: e.domain_name ?? e.domain_id ?? /*#__PURE__*/ o(p, { id: "ZkxxiR" })
|
|
53
|
-
}), /*#__PURE__*/ o("p", {
|
|
54
|
-
"data-testid": "project-name",
|
|
55
|
-
className: "text-theme-high text-lg leading-7 font-bold",
|
|
56
|
-
children: e.name
|
|
57
|
-
})]
|
|
58
|
-
}), e.description && /*#__PURE__*/ o("p", {
|
|
59
|
-
className: "text-theme-default line-clamp-2 text-sm font-normal",
|
|
60
|
-
children: e.description
|
|
61
|
-
})]
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
function _({ projects: e }) {
|
|
65
|
-
return /*#__PURE__*/ o("div", {
|
|
66
|
-
className: "w-full",
|
|
67
|
-
children: /*#__PURE__*/ o("div", {
|
|
68
|
-
className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4",
|
|
69
|
-
children: e?.length ? [...e].sort((e, t) => e.name.localeCompare(t.name)).map((e) => /*#__PURE__*/ o(g, { project: e }, e.id)) : /*#__PURE__*/ o("p", { children: /*#__PURE__*/ o(p, { id: "Zgp2Sm" }) })
|
|
70
|
-
})
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/client/routes/_auth/projects/index.tsx?tsr-split=component
|
|
75
|
-
function v() {
|
|
76
|
-
let { projects: n } = a.useLoaderData(), { search: r = "" } = a.useSearch(), c = a.useNavigate(), { slots: l } = f({ strict: !1 });
|
|
77
|
-
return /*#__PURE__*/ s(t, {
|
|
78
|
-
py: !0,
|
|
79
|
-
children: [
|
|
80
|
-
/*#__PURE__*/ o(e, {
|
|
81
|
-
className: "pb-4",
|
|
82
|
-
children: /*#__PURE__*/ o(p, { id: "+0B+ue" })
|
|
83
|
-
}),
|
|
84
|
-
l?.projectsBanner && /*#__PURE__*/ o(i, {
|
|
85
|
-
component: l.projectsBanner,
|
|
86
|
-
useShadowDOM: !1
|
|
87
|
-
}),
|
|
88
|
-
/*#__PURE__*/ o(h, {
|
|
89
|
-
searchTerm: r,
|
|
90
|
-
onSearch: (e) => {
|
|
91
|
-
c({
|
|
92
|
-
search: { search: e },
|
|
93
|
-
replace: !0
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}),
|
|
97
|
-
/*#__PURE__*/ o("div", {
|
|
98
|
-
className: "pt-5",
|
|
99
|
-
children: /*#__PURE__*/ o(_, { projects: n })
|
|
100
|
-
})
|
|
101
|
-
]
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
//#endregion
|
|
105
|
-
export { v as component };
|
|
106
|
-
|
|
107
|
-
//# sourceMappingURL=projects-wd6Yc-GU.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"projects-wd6Yc-GU.mjs","names":["useEffect","useRef","useState","SearchInput","ProjectsOverviewNavBar","onSearch","searchTerm","useLingui","timerRef","inputFocusedRef","inputValue","setInputValue","current","clearTimeout","handleSearchChange","e","value","target","setTimeout","handleClear","className","type","placeholder","t","onChange","onFocus","onBlur","onClear","useNavigate","Card","ProjectCard","project","navigate","padding","onClick","to","params","projectId","id","className","div","p","domain_name","domain_id","data-testid","name","description","ProjectCardView","projects","length","sort","a","b","localeCompare","map","useRouteContext","ProjectsOverviewNavBar","ProjectCardView","Container","ContentHeading","Trans","Slot","Route","ProjectsOverview","projects","useLoaderData","search","useSearch","navigate","useNavigate","slots","strict","handleSearch","value","replace","projectsBanner","component"],"sources":["../../src/client/routes/_auth/projects/-components/ProjectOverviewNavBar.tsx","../../src/client/routes/_auth/projects/-components/ProjectCardView.tsx","../../src/client/routes/_auth/projects/index.tsx?tsr-split=component"],"sourcesContent":["import { ChangeEvent, useEffect, useRef, useState } from \"react\"\nimport { SearchInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\n\ntype ProjectsOverviewNavBarProps = {\n searchTerm?: string\n onSearch: (value: string) => void\n}\n\nexport function ProjectsOverviewNavBar({ onSearch, searchTerm = \"\" }: ProjectsOverviewNavBarProps) {\n const { t } = useLingui()\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const inputFocusedRef = useRef(false)\n const [inputValue, setInputValue] = useState(searchTerm)\n\n useEffect(() => {\n if (!inputFocusedRef.current && !timerRef.current && searchTerm !== inputValue) {\n setInputValue(searchTerm)\n }\n }, [searchTerm])\n\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current)\n }\n }, [])\n\n const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n setInputValue(value)\n if (timerRef.current) clearTimeout(timerRef.current)\n timerRef.current = setTimeout(() => {\n timerRef.current = null\n onSearch(value)\n }, 300)\n }\n\n const handleClear = () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current)\n timerRef.current = null\n }\n setInputValue(\"\")\n onSearch(\"\")\n }\n\n return (\n <SearchInput\n className=\"w-full\"\n type=\"text\"\n placeholder={t`Search...`}\n onChange={handleSearchChange}\n onFocus={() => {\n inputFocusedRef.current = true\n }}\n onBlur={() => {\n inputFocusedRef.current = false\n }}\n onClear={handleClear}\n value={inputValue}\n />\n )\n}\n","import { useNavigate } from \"@tanstack/react-router\"\nimport { Project } from \"@/server/Project/types/models\"\nimport { Card } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\ntype ProjectCardProps = {\n project: Project\n}\ntype ProjectCardViewProps = {\n projects: Project[] | undefined\n}\n\nexport function ProjectCard({ project }: ProjectCardProps) {\n const navigate = useNavigate()\n return (\n <Card\n padding\n onClick={() => navigate({ to: \"/projects/$projectId\", params: { projectId: project.id } })}\n className=\"flex flex-col gap-4\"\n >\n <div className=\"flex min-w-0 flex-col\">\n <p className=\"text-theme-light text-xs leading-5 font-normal\">\n {project.domain_name ?? project.domain_id ?? <Trans>Unknown domain</Trans>}\n </p>\n <p data-testid=\"project-name\" className=\"text-theme-high text-lg leading-7 font-bold\">\n {project.name}\n </p>\n </div>\n {project.description && (\n <p className=\"text-theme-default line-clamp-2 text-sm font-normal\">{project.description}</p>\n )}\n </Card>\n )\n}\n\nexport function ProjectCardView({ projects }: ProjectCardViewProps) {\n return (\n <div className=\"w-full\">\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4\">\n {projects?.length ? (\n [...projects]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((project) => <ProjectCard key={project.id} project={project} />)\n ) : (\n <p>\n <Trans>No projects available.</Trans>\n </p>\n )}\n </div>\n </div>\n )\n}\n","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, Spinner, Stack } 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 pendingComponent: () => (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\">\n <div className=\"absolute inset-0 backdrop-blur-sm\" />\n <Spinner variant=\"primary\" size=\"large\" />\n </Stack>\n ),\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":"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"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { z as e } from "zod";
|
|
2
|
-
var t = e.object({
|
|
3
|
-
labelKey: e.enum([
|
|
4
|
-
"Compute",
|
|
5
|
-
"Network",
|
|
6
|
-
"Storage",
|
|
7
|
-
"Services",
|
|
8
|
-
"Images",
|
|
9
|
-
"Flavors",
|
|
10
|
-
"Security Groups",
|
|
11
|
-
"Floating IPs",
|
|
12
|
-
"PCA (Clavis)"
|
|
13
|
-
]).optional(),
|
|
14
|
-
to: e.string().optional(),
|
|
15
|
-
useParamAsLabel: e.string().optional(),
|
|
16
|
-
useParentTitleAsLabel: e.boolean().optional()
|
|
17
|
-
}), n = e.object({ name: e.string() }), r = e.object({
|
|
18
|
-
section: e.string().optional(),
|
|
19
|
-
service: e.string().optional(),
|
|
20
|
-
isDetail: e.boolean().optional(),
|
|
21
|
-
crumb: t.optional(),
|
|
22
|
-
sectionCrumb: t.optional(),
|
|
23
|
-
intermediateCrumb: t.optional(),
|
|
24
|
-
analytics: n.optional()
|
|
25
|
-
});
|
|
26
|
-
function i(e) {
|
|
27
|
-
return r.safeParse(e).success;
|
|
28
|
-
}
|
|
29
|
-
//#endregion
|
|
30
|
-
export { i as t };
|
|
31
|
-
|
|
32
|
-
//# sourceMappingURL=routeInfo-CdTRlSxv.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"routeInfo-CdTRlSxv.mjs","names":["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/routes/routeInfo.ts"],"sourcesContent":["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":";AAgBA,IAAME,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"}
|