@cobaltcore-dev/aurora 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -13
- package/dist/client/{ContentHeader-xQVhO2yT.mjs → ContentHeader-kx1Th5Sq.mjs} +18 -18
- package/dist/client/{ContentHeader-xQVhO2yT.mjs.map → ContentHeader-kx1Th5Sq.mjs.map} +1 -1
- package/dist/client/{DeleteFlavorModal-CHTUZ3YV.mjs → DeleteFlavorModal-C3cb7YiJ.mjs} +155 -155
- package/dist/client/{DeleteFlavorModal-CHTUZ3YV.mjs.map → DeleteFlavorModal-C3cb7YiJ.mjs.map} +1 -1
- package/dist/client/{EditSecurityGroupModal-CWHHx2Xk.mjs → EditSecurityGroupModal-CpP54WIK.mjs} +18 -18
- package/dist/client/{EditSecurityGroupModal-CWHHx2Xk.mjs.map → EditSecurityGroupModal-CpP54WIK.mjs.map} +1 -1
- package/dist/client/{FiltersInput-UKJpNFdr.mjs → FiltersInput-DxcyR6Bp.mjs} +18 -18
- package/dist/client/{FiltersInput-UKJpNFdr.mjs.map → FiltersInput-DxcyR6Bp.mjs.map} +1 -1
- package/dist/client/{FloatingIpActionModals-caXn6bYo.mjs → FloatingIpActionModals-BP8RWHbu.mjs} +55 -55
- package/dist/client/{FloatingIpActionModals-caXn6bYo.mjs.map → FloatingIpActionModals-BP8RWHbu.mjs.map} +1 -1
- package/dist/client/{ImageToastNotifications-BWimIzu_.mjs → ImageToastNotifications-TZ3EfQg-.mjs} +323 -371
- package/dist/client/ImageToastNotifications-TZ3EfQg-.mjs.map +1 -0
- package/dist/client/{RouteError-CUj_m3gu.mjs → RouteError-QSV7qOoJ.mjs} +2 -2
- package/dist/client/{RouteError-CUj_m3gu.mjs.map → RouteError-QSV7qOoJ.mjs.map} +1 -1
- package/dist/client/{SortInput-GQlQBlAj.mjs → SortInput-CYv2_Pur.mjs} +5 -5
- package/dist/client/{SortInput-GQlQBlAj.mjs.map → SortInput-CYv2_Pur.mjs.map} +1 -1
- package/dist/client/_auth-DXJkv9QO.mjs.map +1 -1
- package/dist/client/{_flavorId-sUWG0xuy.mjs → _flavorId-C2x43-6S.mjs} +9 -9
- package/dist/client/{_flavorId-sUWG0xuy.mjs.map → _flavorId-C2x43-6S.mjs.map} +1 -1
- package/dist/client/{_flavorId-C5dc1N_j.mjs → _flavorId-CR8ZUI-P.mjs} +46 -46
- package/dist/client/{_flavorId-C5dc1N_j.mjs.map → _flavorId-CR8ZUI-P.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-CT4y-60o.mjs → _floatingIpId-BCk41_Lb.mjs} +2 -2
- package/dist/client/{_floatingIpId-CT4y-60o.mjs.map → _floatingIpId-BCk41_Lb.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-COK_TBrz2.mjs → _floatingIpId-BGrOAmPT.mjs} +33 -33
- package/dist/client/_floatingIpId-BGrOAmPT.mjs.map +1 -0
- package/dist/client/_imageId-CvfD832b.mjs +534 -0
- package/dist/client/{_imageId-n3RcnhAR.mjs.map → _imageId-CvfD832b.mjs.map} +1 -1
- package/dist/client/_pcaId-BxBt5DXi.mjs +459 -0
- package/dist/client/_pcaId-BxBt5DXi.mjs.map +1 -0
- package/dist/client/{_pcaId-ChnM_t-9.mjs → _pcaId-DOHycvCf.mjs} +2 -2
- package/dist/client/{_pcaId-ChnM_t-9.mjs.map → _pcaId-DOHycvCf.mjs.map} +1 -1
- package/dist/client/{_projectId-26bw-_rm.mjs → _projectId-BDSWnMGj.mjs} +3 -3
- package/dist/client/{_projectId-26bw-_rm.mjs.map → _projectId-BDSWnMGj.mjs.map} +1 -1
- package/dist/client/{_projectId-Dhb4AyBD.mjs → _projectId-DOgwFiqD.mjs} +2 -2
- package/dist/client/{_projectId-Dhb4AyBD.mjs.map → _projectId-DOgwFiqD.mjs.map} +1 -1
- package/dist/client/_projectId-DS4nR59B.mjs +299 -0
- package/dist/client/_projectId-DS4nR59B.mjs.map +1 -0
- package/dist/client/{_projectId-BK9UqeYw.mjs → _projectId-MxcHrXW4.mjs} +12 -12
- package/dist/client/_projectId-MxcHrXW4.mjs.map +1 -0
- package/dist/client/{_securityGroupId-CR1mKICQ.mjs → _securityGroupId-CJJanWiY.mjs} +2 -2
- package/dist/client/{_securityGroupId-CR1mKICQ.mjs.map → _securityGroupId-CJJanWiY.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-DroYG6cA.mjs → _securityGroupId-KKw4RPdH.mjs} +328 -328
- package/dist/client/{_securityGroupId-DroYG6cA.mjs.map → _securityGroupId-KKw4RPdH.mjs.map} +1 -1
- package/dist/client/{containers-DGY2hoWw.mjs → _storageType-4wSxI__0.mjs} +18 -15
- package/dist/client/_storageType-4wSxI__0.mjs.map +1 -0
- package/dist/client/{containers-ZMFTRaQL.mjs → _storageType-DYjo-6ej.mjs} +1054 -1088
- package/dist/client/_storageType-DYjo-6ej.mjs.map +1 -0
- package/dist/client/{containers-xfsYgRyf.mjs → _storageType-zeSZe--V.mjs} +2 -2
- package/dist/client/_storageType-zeSZe--V.mjs.map +1 -0
- package/dist/client/{about-969pIiZ9.mjs → about-Bo9vxGHy.mjs} +8 -8
- package/dist/client/{about-969pIiZ9.mjs.map → about-Bo9vxGHy.mjs.map} +1 -1
- package/dist/client/{build-DracvfrJ.mjs → build-DeJcDjPi.mjs} +3798 -3372
- package/dist/client/build-DeJcDjPi.mjs.map +1 -0
- package/dist/client/constants-BmcGYeR-.mjs +153 -0
- package/dist/client/constants-BmcGYeR-.mjs.map +1 -0
- package/dist/client/{flavors-C4GtoybP.mjs → flavors-BxFVqgnb.mjs} +2 -2
- package/dist/client/{flavors-C4GtoybP.mjs.map → flavors-BxFVqgnb.mjs.map} +1 -1
- package/dist/client/{flavors-CpirO_nr.mjs → flavors-CfdgjsZY.mjs} +192 -192
- package/dist/client/{flavors-CpirO_nr.mjs.map → flavors-CfdgjsZY.mjs.map} +1 -1
- package/dist/client/{floatingips-BUf_oLRl.mjs → floatingips-ByRb82wS.mjs} +123 -123
- package/dist/client/{floatingips-BUf_oLRl.mjs.map → floatingips-ByRb82wS.mjs.map} +1 -1
- package/dist/client/{images-Da1t5KPh.mjs → images-CKqIXUq52.mjs} +613 -613
- package/dist/client/images-CKqIXUq52.mjs.map +1 -0
- package/dist/client/{images-CsonlmFx.mjs → images-C_dX7nY6.mjs} +2 -2
- package/dist/client/{images-CsonlmFx.mjs.map → images-C_dX7nY6.mjs.map} +1 -1
- package/dist/client/{images-QnWf63uj.mjs → images-CenluYV8.mjs} +2 -2
- package/dist/client/{images-QnWf63uj.mjs.map → images-CenluYV8.mjs.map} +1 -1
- package/dist/client/index.js +391 -431
- package/dist/client/index.js.map +1 -1
- package/dist/client/{md-sBiSNVSQ.mjs → md-CYTrL5dq.mjs} +52 -16
- package/dist/client/{md-sBiSNVSQ.mjs.map → md-CYTrL5dq.mjs.map} +1 -1
- package/dist/client/{objects-H0NN_Sja.mjs → objects-BJM6YeuF.mjs} +2131 -1883
- package/dist/client/objects-BJM6YeuF.mjs.map +1 -0
- package/dist/client/{objects-B89dYCBq.mjs → objects-gxSjvbvF.mjs} +36 -21
- package/dist/client/objects-gxSjvbvF.mjs.map +1 -0
- package/dist/client/{objects-CuFLUOe1.mjs → objects-o2Cj_ndZ.mjs} +2 -2
- package/dist/client/objects-o2Cj_ndZ.mjs.map +1 -0
- package/dist/client/{pca-CtU6REww.mjs → pca-Bl8NmoVZ.mjs} +2 -2
- package/dist/client/{pca-CtU6REww.mjs.map → pca-Bl8NmoVZ.mjs.map} +1 -1
- package/dist/client/pca-RSiWpJs9.mjs +182 -0
- package/dist/client/pca-RSiWpJs9.mjs.map +1 -0
- package/dist/client/{projects-DNXsDnJM.mjs → projects-CgclWI16.mjs} +33 -27
- package/dist/client/{projects-DNXsDnJM.mjs.map → projects-CgclWI16.mjs.map} +1 -1
- package/dist/client/{projects-dhnQkuvV.mjs → projects-D2iewAzu.mjs} +2 -2
- package/dist/client/{projects-dhnQkuvV.mjs.map → projects-D2iewAzu.mjs.map} +1 -1
- package/dist/client/{projects-C-sjd9T5.mjs → projects-pe2_dCnV.mjs} +2 -2
- package/dist/client/{projects-C-sjd9T5.mjs.map → projects-pe2_dCnV.mjs.map} +1 -1
- package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
- package/dist/client/{securitygroups-wHdrxZXd.mjs → securitygroups-DahZkVYQ.mjs} +111 -111
- package/dist/client/{securitygroups-wHdrxZXd.mjs.map → securitygroups-DahZkVYQ.mjs.map} +1 -1
- package/dist/client/{useListWithFiltering-DrgUwXef.mjs → useListWithFiltering-DaYcu5AB.mjs} +12 -12
- package/dist/client/{useListWithFiltering-DrgUwXef.mjs.map → useListWithFiltering-DaYcu5AB.mjs.map} +1 -1
- package/dist/server/index.d.ts +571 -2
- package/dist/server/index.js +29 -211
- package/package.json +4 -5
- package/dist/client/ImageToastNotifications-BWimIzu_.mjs.map +0 -1
- package/dist/client/_floatingIpId-COK_TBrz2.mjs.map +0 -1
- package/dist/client/_imageId-n3RcnhAR.mjs +0 -534
- package/dist/client/_pcaId-B-f_6kqs.mjs +0 -466
- package/dist/client/_pcaId-B-f_6kqs.mjs.map +0 -1
- package/dist/client/_projectId-BK9UqeYw.mjs.map +0 -1
- package/dist/client/_projectId-CCtpAQ8m.mjs +0 -299
- package/dist/client/_projectId-CCtpAQ8m.mjs.map +0 -1
- package/dist/client/build-DracvfrJ.mjs.map +0 -1
- package/dist/client/constants-4lVQXort.mjs +0 -128
- package/dist/client/constants-4lVQXort.mjs.map +0 -1
- package/dist/client/containers-DGY2hoWw.mjs.map +0 -1
- package/dist/client/containers-ZMFTRaQL.mjs.map +0 -1
- package/dist/client/containers-xfsYgRyf.mjs.map +0 -1
- package/dist/client/images-Da1t5KPh.mjs.map +0 -1
- package/dist/client/objects-B89dYCBq.mjs.map +0 -1
- package/dist/client/objects-CuFLUOe1.mjs.map +0 -1
- package/dist/client/objects-H0NN_Sja.mjs.map +0 -1
- package/dist/client/pca-C-UFjicP.mjs +0 -167
- package/dist/client/pca-C-UFjicP.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -52,19 +52,65 @@ export function App() {
|
|
|
52
52
|
|
|
53
53
|
### `createServer(config)`
|
|
54
54
|
|
|
55
|
-
| Option | Type
|
|
56
|
-
| --------------------------------- |
|
|
57
|
-
| `identityEndpoint` | `string`
|
|
58
|
-
| `policyDir` | `string`
|
|
59
|
-
| `bffEndpoint` | `string`
|
|
60
|
-
| `viteRoot` | `string`
|
|
61
|
-
| `defaultEndpointInterface` | `string`
|
|
62
|
-
| `proxyUrl` | `string`
|
|
63
|
-
| `cephRegion` | `string`
|
|
64
|
-
| `imageMetadataExcludedProperties` | `string`
|
|
65
|
-
| `cookieName` | `string`
|
|
66
|
-
| `crossDomainCookie` | `boolean`
|
|
67
|
-
| `insecureCookies` | `boolean`
|
|
55
|
+
| Option | Type | Required | Default | Description |
|
|
56
|
+
| --------------------------------- | ------------- | -------- | -------------------------- | ---------------------------------------------------------------- |
|
|
57
|
+
| `identityEndpoint` | `string` | yes | — | OpenStack Keystone v3 URL |
|
|
58
|
+
| `policyDir` | `string` | yes | — | Absolute path to a directory of OpenStack policy YAML files |
|
|
59
|
+
| `bffEndpoint` | `string` | no | `"/polaris-bff"` | URL prefix for all tRPC routes |
|
|
60
|
+
| `viteRoot` | `string` | no | — | Directory that contains `dist/client/` in production |
|
|
61
|
+
| `defaultEndpointInterface` | `string` | no | `"public"` | OpenStack service catalog interface |
|
|
62
|
+
| `proxyUrl` | `string` | no | — | HTTP proxy for OpenStack calls (dev only, ignored in production) |
|
|
63
|
+
| `cephRegion` | `string` | no | — | Ceph RGW region for S3 operations |
|
|
64
|
+
| `imageMetadataExcludedProperties` | `string` | no | — | Comma-separated image metadata keys to hide in the UI |
|
|
65
|
+
| `cookieName` | `string` | no | `"dashboard-session-auth"` | Override the session cookie name |
|
|
66
|
+
| `crossDomainCookie` | `boolean` | no | `true` | Share cookie across subdomains |
|
|
67
|
+
| `insecureCookies` | `boolean` | no | `false` | Disable `Secure` flag — only for HTTP-only local dev |
|
|
68
|
+
| `routers` | `AnyRouter[]` | no | `[]` | Additional tRPC routers — see [Custom routers](#custom-routers) |
|
|
69
|
+
|
|
70
|
+
## Custom routers
|
|
71
|
+
|
|
72
|
+
`createServer` accepts a `routers` option so consumers can add their own tRPC procedures that run alongside the built-in Aurora routes, sharing the same Fastify request context (session, cookies, OpenStack client).
|
|
73
|
+
|
|
74
|
+
### Requirements
|
|
75
|
+
|
|
76
|
+
Routers passed via `routers` **must** be created with the `auroraRouter` function exported from `@cobaltcore-dev/aurora/server`. Using a different `initTRPC` instance produces an incompatible context type and will cause runtime failures when procedures access `ctx.openstack`, `ctx.validateSession`, etc.
|
|
77
|
+
|
|
78
|
+
For the full list of exported procedure builders and router utilities, see [`src/server/index.ts`](./src/server/index.ts).
|
|
79
|
+
|
|
80
|
+
### Example
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { z } from "zod"
|
|
84
|
+
import { auroraRouter, protectedProcedure, createServer } from "@cobaltcore-dev/aurora/server"
|
|
85
|
+
|
|
86
|
+
const customRouter = auroraRouter({
|
|
87
|
+
feedback: protectedProcedure.input(z.object({ message: z.string() })).mutation(async ({ input }) => {
|
|
88
|
+
// ctx.validateSession(), ctx.openstack — all available here
|
|
89
|
+
return { status: "received" }
|
|
90
|
+
}),
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const server = await createServer({
|
|
94
|
+
identityEndpoint: "https://keystone.example.com/v3/",
|
|
95
|
+
policyDir: path.resolve(__dirname, "../policies"),
|
|
96
|
+
routers: [customRouter],
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The procedure above is reachable at `POST <bffEndpoint>/feedback` via the tRPC client.
|
|
101
|
+
|
|
102
|
+
### Registering additional Fastify plugins
|
|
103
|
+
|
|
104
|
+
`createServer` returns the `FastifyInstance` before `.listen()` is called. You can register any Fastify plugin — metrics, tracing, custom middleware — on the returned instance before starting the server:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const server = await createServer({ ... })
|
|
108
|
+
|
|
109
|
+
server.register(MyPlugin, { ... })
|
|
110
|
+
server.get("/healthz", async () => ({ ok: true }))
|
|
111
|
+
|
|
112
|
+
await server.listen({ host: "0.0.0.0", port: 4000 })
|
|
113
|
+
```
|
|
68
114
|
|
|
69
115
|
### `<AuroraApp />`
|
|
70
116
|
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as e, Q as t, _ as n, l as r, nt as i, q as a, st as o } from "./build-DeJcDjPi.mjs";
|
|
2
2
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
3
3
|
import { useState as l } from "react";
|
|
4
4
|
import { Trans as u, useLingui as d } from "@lingui/react";
|
|
5
5
|
//#region src/client/components/ClipboardText.tsx
|
|
6
|
-
var f = ({ text:
|
|
7
|
-
let { i18n: h, _: g } = d(), [_, v] = l(!1), [y, b] = l(!1), x = `copyableTooltip inline-flex items-center ${u || ""}`, S = async (
|
|
8
|
-
|
|
6
|
+
var f = ({ text: e, tooltipContent: a, className: u, truncateAt: f, showTooltip: p = !0, ...m }) => {
|
|
7
|
+
let { i18n: h, _: g } = d(), [_, v] = l(!1), [y, b] = l(!1), x = `copyableTooltip inline-flex items-center ${u || ""}`, S = async (t) => {
|
|
8
|
+
t.preventDefault(), t.stopPropagation();
|
|
9
9
|
try {
|
|
10
|
-
await navigator.clipboard.writeText(
|
|
10
|
+
await navigator.clipboard.writeText(e), v(!0), b(!1), setTimeout(() => v(!1), 2e3);
|
|
11
11
|
} catch (e) {
|
|
12
12
|
console.error("Failed to copy text:", e);
|
|
13
13
|
}
|
|
14
|
-
}, C = f &&
|
|
14
|
+
}, C = f && e.length > f ? `${e.slice(0, f)}...` : e, w = () => _ ? a || h._({ id: "u+VWhB" }) : h._({ id: "he3ygx" }), T = _ && p || y && p;
|
|
15
15
|
return /*#__PURE__*/ s("div", {
|
|
16
16
|
...m,
|
|
17
17
|
className: x,
|
|
18
|
-
children: /*#__PURE__*/ c(
|
|
18
|
+
children: /*#__PURE__*/ c(o, {
|
|
19
19
|
open: T,
|
|
20
|
-
children: [/*#__PURE__*/ s(
|
|
20
|
+
children: [/*#__PURE__*/ s(n, {
|
|
21
21
|
onClick: S,
|
|
22
22
|
onMouseEnter: () => !_ && b(!0),
|
|
23
23
|
onMouseLeave: () => b(!1),
|
|
24
24
|
"aria-label": h._({
|
|
25
25
|
id: "Wbg1jv",
|
|
26
|
-
values: { text:
|
|
26
|
+
values: { text: e }
|
|
27
27
|
}),
|
|
28
28
|
className: "cursor-pointer",
|
|
29
29
|
asChild: !0,
|
|
30
30
|
"data-testid": "clipboard-copy-trigger",
|
|
31
31
|
children: /*#__PURE__*/ s("div", {
|
|
32
32
|
className: "group",
|
|
33
|
-
children: /*#__PURE__*/ c(
|
|
33
|
+
children: /*#__PURE__*/ c(t, {
|
|
34
34
|
direction: "horizontal",
|
|
35
35
|
gap: "1",
|
|
36
36
|
className: "items-center hover:underline",
|
|
@@ -43,17 +43,17 @@ var f = ({ text: i, tooltipContent: o, className: u, truncateAt: f, showTooltip:
|
|
|
43
43
|
})]
|
|
44
44
|
})
|
|
45
45
|
})
|
|
46
|
-
}), /*#__PURE__*/ s(
|
|
46
|
+
}), /*#__PURE__*/ s(i, { children: w() })]
|
|
47
47
|
})
|
|
48
48
|
});
|
|
49
49
|
};
|
|
50
50
|
//#endregion
|
|
51
51
|
//#region src/client/components/ContentHeader/ContentHeader.tsx
|
|
52
|
-
function p({ title:
|
|
52
|
+
function p({ title: t, projectId: n, actions: r }) {
|
|
53
53
|
return /*#__PURE__*/ c("header", { children: [
|
|
54
54
|
/*#__PURE__*/ c("div", {
|
|
55
55
|
className: "flex flex-col sm:flex-row sm:items-center sm:justify-between",
|
|
56
|
-
children: [/*#__PURE__*/ s(
|
|
56
|
+
children: [/*#__PURE__*/ s(a, { children: t }), /*#__PURE__*/ c("div", {
|
|
57
57
|
className: "text-theme-light flex items-center gap-1 text-sm",
|
|
58
58
|
children: [/*#__PURE__*/ c("span", {
|
|
59
59
|
className: "font-semibold",
|
|
@@ -63,19 +63,19 @@ function p({ title: e, projectId: t, actions: n }) {
|
|
|
63
63
|
" "
|
|
64
64
|
]
|
|
65
65
|
}), /*#__PURE__*/ s(f, {
|
|
66
|
-
text:
|
|
66
|
+
text: n,
|
|
67
67
|
truncateAt: 15
|
|
68
68
|
})]
|
|
69
69
|
})]
|
|
70
70
|
}),
|
|
71
|
-
/*#__PURE__*/ s(
|
|
72
|
-
|
|
71
|
+
/*#__PURE__*/ s(e, { className: "mt-4" }),
|
|
72
|
+
r && /*#__PURE__*/ s("div", {
|
|
73
73
|
className: "mt-3 flex justify-end",
|
|
74
|
-
children:
|
|
74
|
+
children: r
|
|
75
75
|
})
|
|
76
76
|
] });
|
|
77
77
|
}
|
|
78
78
|
//#endregion
|
|
79
79
|
export { f as n, p as t };
|
|
80
80
|
|
|
81
|
-
//# sourceMappingURL=ContentHeader-
|
|
81
|
+
//# sourceMappingURL=ContentHeader-kx1Th5Sq.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentHeader-
|
|
1
|
+
{"version":3,"file":"ContentHeader-kx1Th5Sq.mjs","names":["React","useState","Tooltip","TooltipTrigger","TooltipContent","Icon","Stack","ClipboardText","text","tooltipContent","className","truncateAt","showTooltip","props","useLingui","copied","setCopied","isHovering","setIsHovering","combinedClassName","handleCopy","e","preventDefault","stopPropagation","navigator","clipboard","writeText","setTimeout","err","console","error","displayText","length","slice","getTooltipContent","t","tooltipIsOpen","div","open","onClick","onMouseEnter","onMouseLeave","aria-label","asChild","data-testid","direction","gap","span","icon","size","Divider","ContentHeading","ClipboardText","ContentHeader","title","projectId","actions","header","div","className","span","text","truncateAt"],"sources":["../../src/client/components/ClipboardText.tsx","../../src/client/components/ContentHeader/ContentHeader.tsx"],"sourcesContent":["import React, { useState } from \"react\"\nimport { Tooltip, TooltipTrigger, TooltipContent, Icon, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\n\nexport interface ClipboardTextProps extends React.HTMLAttributes<HTMLDivElement> {\n tooltipContent?: string\n text: string\n className?: string\n truncateAt?: number\n showTooltip?: boolean\n}\n\nconst ClipboardText: React.FC<ClipboardTextProps> = ({\n text,\n tooltipContent,\n className,\n truncateAt,\n showTooltip = true,\n ...props\n}) => {\n const { t } = useLingui()\n const [copied, setCopied] = useState(false)\n const [isHovering, setIsHovering] = useState(false)\n\n const combinedClassName = `copyableTooltip inline-flex items-center ${className || \"\"}`\n\n const handleCopy = async (e: React.MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setIsHovering(false)\n setTimeout(() => setCopied(false), 2000)\n } catch (err) {\n console.error(\"Failed to copy text:\", err)\n }\n }\n\n const displayText = truncateAt && text.length > truncateAt ? `${text.slice(0, truncateAt)}...` : text\n\n // Determine tooltip content based on state\n const getTooltipContent = () => {\n if (copied) {\n return tooltipContent || t`Copied to clipboard!`\n }\n return t`Copy`\n }\n\n const tooltipIsOpen = (copied && showTooltip) || (isHovering && showTooltip)\n\n return (\n <div {...props} className={combinedClassName}>\n <Tooltip open={tooltipIsOpen}>\n <TooltipTrigger\n onClick={handleCopy}\n onMouseEnter={() => !copied && setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n aria-label={t`Copy ${text} to clipboard`}\n className=\"cursor-pointer\"\n asChild\n data-testid=\"clipboard-copy-trigger\"\n >\n <div className=\"group\">\n <Stack direction=\"horizontal\" gap=\"1\" className=\"items-center hover:underline\">\n <span className=\"select-none\">{displayText}</span>\n <Icon icon={copied ? \"check\" : \"contentCopy\"} size=\"18\" />\n </Stack>\n </div>\n </TooltipTrigger>\n <TooltipContent>{getTooltipContent()}</TooltipContent>\n </Tooltip>\n </div>\n )\n}\n\nexport default ClipboardText\n","import type { ReactNode } from \"react\"\nimport { Divider, ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\nimport ClipboardText from \"../ClipboardText\"\n\ninterface ContentHeaderProps {\n title: string\n projectId: string\n actions?: ReactNode\n}\n\nexport function ContentHeader({ title, projectId, actions }: ContentHeaderProps) {\n return (\n <header>\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n <ContentHeading>{title}</ContentHeading>\n <div className=\"text-theme-light flex items-center gap-1 text-sm\">\n <span className=\"font-semibold\">\n <Trans>Project ID</Trans>:{\" \"}\n </span>\n <ClipboardText text={projectId} truncateAt={15} />\n </div>\n </div>\n <Divider className=\"mt-4\" />\n {actions && <div className=\"mt-3 flex justify-end\">{actions}</div>}\n </header>\n )\n}\n"],"mappings":";;;;;AAYA,IAAMO,KAA+C,EACnDC,SACAC,mBACAC,cACAC,eACAC,iBAAc,IACd,GAAGC,QACJ;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GACR,CAACC,GAAQC,KAAaf,EAAS,EAAA,GAC/B,CAACgB,GAAYC,KAAiBjB,EAAS,EAAA,GAEvCkB,IAAoB,6CAA6CT,KAAa,MAE9EU,IAAa,OAAOC,MAAAA;EAExBA,AADAA,EAAEC,eAAc,GAChBD,EAAEE,gBAAe;EAEjB,IAAI;GAIFI,AAHA,MAAMH,UAAUC,UAAUC,UAAUlB,CAAAA,GACpCQ,EAAU,EAAA,GACVE,EAAc,EAAA,GACdS,iBAAiBX,EAAU,EAAA,GAAQ,GAAA;EACrC,SAASY,GAAK;GACZC,QAAQC,MAAM,wBAAwBF,CAAAA;EACxC;CACF,GAEMG,IAAcpB,KAAcH,EAAKwB,SAASrB,IAAa,GAAGH,EAAKyB,MAAM,GAAGtB,CAAAA,EAAY,OAAOH,GAG3F0B,UACAnB,IACKN,KAAkB0B,EAAAA,EAAC,EAAA,IAAA,SAAqB,CAAA,IAE1CA,EAAAA,EAAC,EAAA,IAAA,SAAK,CAAA,GAGTC,IAAgB,KAAWxB,KAAiBK,KAAcL;CAEhE,OACE,gBAACyB,OAAAA;EAAK,GAAGxB;EAAOH,WAAWS;YACzB,gBAACjB,GAAAA;GAAQoC,MAAMF;cACb,gBAACjC,GAAAA;IACCoC,SAASnB;IACToB,oBAAoB,CAACzB,KAAUG,EAAc,EAAA;IAC7CuB,oBAAoBvB,EAAc,EAAA;IAClCwB,cAAYP,EAAAA,EAAC;;eAAQ3B,QAAAA;IAAkB,CAAA;IACvCE,WAAU;IACViC,SAAO;IACPC,eAAY;cAEZ,gBAACP,OAAAA;KAAI3B,WAAU;eACb,gBAACJ,GAAAA;MAAMuC,WAAU;MAAaC,KAAI;MAAIpC,WAAU;iBAC9C,gBAACqC,QAAAA;OAAKrC,WAAU;iBAAeqB;UAC/B,gBAAC1B,GAAAA;OAAK2C,MAAMjC,IAAS,UAAU;OAAekC,MAAK;;;;OAIzD,gBAAC7C,GAAAA,EAAAA,UAAgB8B,EAAAA,EAAAA,CAAAA,CAAAA;;;AAIzB;;;AChEA,SAAgBmB,EAAc,EAAEC,UAAOC,cAAWC,cAA6B;CAC7E,OACE,gBAACC,UAAAA,EAAAA,UAAAA;EACC,gBAACC,OAAAA;GAAIC,WAAU;cACb,gBAACR,GAAAA,EAAAA,UAAgBG,EAAAA,CAAAA,GACjB,gBAACI,OAAAA;IAAIC,WAAU;eACb,gBAACC,QAAAA;KAAKD,WAAU;;MACd,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;MAAyB;MAAE;;QAE7B,gBAACP,GAAAA;KAAcS,MAAMN;KAAWO,YAAY;;;;EAGhD,gBAACZ,GAAAA,EAAQS,WAAU,OAAA,CAAA;EAClBH,KAAW,gBAACE,OAAAA;GAAIC,WAAU;aAAyBH;;;AAG1D"}
|