@cobaltcore-dev/aurora 0.7.0 → 0.8.1
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 +101 -7
- package/dist/client/AuroraApp.d.ts +38 -0
- package/dist/client/{ContentHeader-kx1Th5Sq.mjs → ContentHeader-C51H95X8.mjs} +24 -20
- package/dist/client/ContentHeader-C51H95X8.mjs.map +1 -0
- package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs → DeleteFlavorModal-C3m7bQJu.mjs} +163 -163
- package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs.map → DeleteFlavorModal-C3m7bQJu.mjs.map} +1 -1
- package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs → EditSecurityGroupModal-DKusxfta.mjs} +18 -18
- package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs.map → EditSecurityGroupModal-DKusxfta.mjs.map} +1 -1
- package/dist/client/{FiltersInput-DxcyR6Bp.mjs → FiltersInput-GzR4D0q6.mjs} +21 -21
- package/dist/client/{FiltersInput-DxcyR6Bp.mjs.map → FiltersInput-GzR4D0q6.mjs.map} +1 -1
- package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs → FloatingIpActionModals-CRvROJ3H.mjs} +51 -51
- package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs.map → FloatingIpActionModals-CRvROJ3H.mjs.map} +1 -1
- package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs → ImageToastNotifications-BuDXpTkl.mjs} +344 -344
- package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs.map → ImageToastNotifications-BuDXpTkl.mjs.map} +1 -1
- package/dist/client/{RouteError-QSV7qOoJ.mjs → RouteError-DVAiT0mT.mjs} +2 -2
- package/dist/client/{RouteError-QSV7qOoJ.mjs.map → RouteError-DVAiT0mT.mjs.map} +1 -1
- package/dist/client/{SortInput-CYv2_Pur.mjs → SortInput-VK7IYqQv.mjs} +6 -6
- package/dist/client/{SortInput-CYv2_Pur.mjs.map → SortInput-VK7IYqQv.mjs.map} +1 -1
- package/dist/client/{_flavorId-C2x43-6S.mjs → _flavorId-DU4gcFna.mjs} +8 -8
- package/dist/client/{_flavorId-C2x43-6S.mjs.map → _flavorId-DU4gcFna.mjs.map} +1 -1
- package/dist/client/{_flavorId-CR8ZUI-P.mjs → _flavorId-iZE2j210.mjs} +62 -62
- package/dist/client/{_flavorId-CR8ZUI-P.mjs.map → _flavorId-iZE2j210.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-BCk41_Lb.mjs → _floatingIpId-B5GMSLeQ.mjs} +2 -2
- package/dist/client/{_floatingIpId-BCk41_Lb.mjs.map → _floatingIpId-B5GMSLeQ.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-BGrOAmPT.mjs → _floatingIpId-C2-BeRmF.mjs} +27 -27
- package/dist/client/{_floatingIpId-BGrOAmPT.mjs.map → _floatingIpId-C2-BeRmF.mjs.map} +1 -1
- package/dist/client/_imageId-zmaSymWe.mjs +534 -0
- package/dist/client/{_imageId-CvfD832b.mjs.map → _imageId-zmaSymWe.mjs.map} +1 -1
- package/dist/client/_pcaId-BwTvJJgh.mjs +479 -0
- package/dist/client/_pcaId-BwTvJJgh.mjs.map +1 -0
- package/dist/client/{_pcaId-DOHycvCf.mjs → _pcaId-DUHQd0rB.mjs} +2 -2
- package/dist/client/{_pcaId-DOHycvCf.mjs.map → _pcaId-DUHQd0rB.mjs.map} +1 -1
- package/dist/client/{_projectId-DOgwFiqD.mjs → _projectId-B_2sZKk-.mjs} +2 -2
- package/dist/client/_projectId-B_2sZKk-.mjs.map +1 -0
- package/dist/client/_projectId-C8BaEHUj.mjs +273 -0
- package/dist/client/_projectId-C8BaEHUj.mjs.map +1 -0
- package/dist/client/_projectId-COt93OEF.mjs +84 -0
- package/dist/client/_projectId-COt93OEF.mjs.map +1 -0
- package/dist/client/{_securityGroupId-KKw4RPdH.mjs → _securityGroupId-DYxmXUOP.mjs} +319 -319
- package/dist/client/{_securityGroupId-KKw4RPdH.mjs.map → _securityGroupId-DYxmXUOP.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-CJJanWiY.mjs → _securityGroupId-fhK1CuZh.mjs} +2 -2
- package/dist/client/{_securityGroupId-CJJanWiY.mjs.map → _securityGroupId-fhK1CuZh.mjs.map} +1 -1
- package/dist/client/{_storageType-DYjo-6ej.mjs → _storageType-B-qGcGUQ.mjs} +699 -698
- package/dist/client/_storageType-B-qGcGUQ.mjs.map +1 -0
- package/dist/client/{_storageType-4wSxI__0.mjs → _storageType-CepuevDG.mjs} +2 -2
- package/dist/client/{_storageType-4wSxI__0.mjs.map → _storageType-CepuevDG.mjs.map} +1 -1
- package/dist/client/{about-Bo9vxGHy.mjs → about-Nsxkyh9U.mjs} +2 -2
- package/dist/client/{about-Bo9vxGHy.mjs.map → about-Nsxkyh9U.mjs.map} +1 -1
- package/dist/client/{build-DeJcDjPi.mjs → build-BdRRmNf5.mjs} +3290 -3274
- package/dist/client/{build-DeJcDjPi.mjs.map → build-BdRRmNf5.mjs.map} +1 -1
- package/dist/client/{constants-BmcGYeR-.mjs → constants-J5nm9hbP.mjs} +15 -15
- package/dist/client/{constants-BmcGYeR-.mjs.map → constants-J5nm9hbP.mjs.map} +1 -1
- package/dist/client/{flavors-BxFVqgnb.mjs → flavors-8bZVlzzb.mjs} +2 -2
- package/dist/client/{flavors-BxFVqgnb.mjs.map → flavors-8bZVlzzb.mjs.map} +1 -1
- package/dist/client/{flavors-CfdgjsZY.mjs → flavors-BfsEBUE-.mjs} +238 -221
- package/dist/client/flavors-BfsEBUE-.mjs.map +1 -0
- package/dist/client/{floatingips-ByRb82wS.mjs → floatingips-Dq4DXQYb.mjs} +90 -90
- package/dist/client/{floatingips-ByRb82wS.mjs.map → floatingips-Dq4DXQYb.mjs.map} +1 -1
- package/dist/client/{images-CenluYV8.mjs → images-8FOgju2f.mjs} +2 -2
- package/dist/client/{images-CenluYV8.mjs.map → images-8FOgju2f.mjs.map} +1 -1
- package/dist/client/images-BPnTuKFO2.mjs +1890 -0
- package/dist/client/images-BPnTuKFO2.mjs.map +1 -0
- package/dist/client/{images-C_dX7nY6.mjs → images-Dbjo4yKn.mjs} +2 -2
- package/dist/client/{images-C_dX7nY6.mjs.map → images-Dbjo4yKn.mjs.map} +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +382 -351
- package/dist/client/index.js.map +1 -1
- package/dist/client/{objects-gxSjvbvF.mjs → objects-DKWp9RtR.mjs} +2 -2
- package/dist/client/{objects-gxSjvbvF.mjs.map → objects-DKWp9RtR.mjs.map} +1 -1
- package/dist/client/{objects-BJM6YeuF.mjs → objects-DaCuy_CB.mjs} +1156 -1156
- package/dist/client/{objects-BJM6YeuF.mjs.map → objects-DaCuy_CB.mjs.map} +1 -1
- package/dist/client/pca-5wOBf_KI.mjs +202 -0
- package/dist/client/pca-5wOBf_KI.mjs.map +1 -0
- package/dist/client/{pca-Bl8NmoVZ.mjs → pca-dhrOFfrE.mjs} +2 -2
- package/dist/client/{pca-Bl8NmoVZ.mjs.map → pca-dhrOFfrE.mjs.map} +1 -1
- package/dist/client/{projects-D2iewAzu.mjs → projects-B_PPyZD1.mjs} +2 -2
- package/dist/client/{projects-D2iewAzu.mjs.map → projects-B_PPyZD1.mjs.map} +1 -1
- package/dist/client/{projects-pe2_dCnV.mjs → projects-CHYn7L5e.mjs} +2 -2
- package/dist/client/{projects-pe2_dCnV.mjs.map → projects-CHYn7L5e.mjs.map} +1 -1
- package/dist/client/{projects-CgclWI16.mjs → projects-Dmewygrp.mjs} +12 -12
- package/dist/client/projects-Dmewygrp.mjs.map +1 -0
- package/dist/client/routeInfo-CHiJfum5.mjs +73 -0
- package/dist/client/routeInfo-CHiJfum5.mjs.map +1 -0
- package/dist/client/{securitygroups-DahZkVYQ.mjs → securitygroups-CNFLu9zS.mjs} +112 -112
- package/dist/client/{securitygroups-DahZkVYQ.mjs.map → securitygroups-CNFLu9zS.mjs.map} +1 -1
- package/dist/client/{useListWithFiltering-DaYcu5AB.mjs → useListWithFiltering-v2A0-SZb.mjs} +9 -9
- package/dist/client/{useListWithFiltering-DaYcu5AB.mjs.map → useListWithFiltering-v2A0-SZb.mjs.map} +1 -1
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js +37 -52
- package/package.json +4 -4
- package/dist/client/ContentHeader-kx1Th5Sq.mjs.map +0 -1
- package/dist/client/_imageId-CvfD832b.mjs +0 -534
- package/dist/client/_pcaId-BxBt5DXi.mjs +0 -459
- package/dist/client/_pcaId-BxBt5DXi.mjs.map +0 -1
- package/dist/client/_projectId-BDSWnMGj.mjs +0 -46
- package/dist/client/_projectId-BDSWnMGj.mjs.map +0 -1
- package/dist/client/_projectId-DOgwFiqD.mjs.map +0 -1
- package/dist/client/_projectId-DS4nR59B.mjs +0 -299
- package/dist/client/_projectId-DS4nR59B.mjs.map +0 -1
- package/dist/client/_projectId-MxcHrXW4.mjs +0 -84
- package/dist/client/_projectId-MxcHrXW4.mjs.map +0 -1
- package/dist/client/_storageType-DYjo-6ej.mjs.map +0 -1
- package/dist/client/flavors-CfdgjsZY.mjs.map +0 -1
- package/dist/client/images-CKqIXUq52.mjs +0 -1873
- package/dist/client/images-CKqIXUq52.mjs.map +0 -1
- package/dist/client/pca-RSiWpJs9.mjs +0 -182
- package/dist/client/pca-RSiWpJs9.mjs.map +0 -1
- package/dist/client/projects-CgclWI16.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -114,13 +114,14 @@ await server.listen({ host: "0.0.0.0", port: 4000 })
|
|
|
114
114
|
|
|
115
115
|
### `<AuroraApp />`
|
|
116
116
|
|
|
117
|
-
| Prop | Type | Default | Description
|
|
118
|
-
| --------------- | ------------------------------- | ---------------- |
|
|
119
|
-
| `bffEndpoint` | `string` | `"/polaris-bff"` | Must match the server's `bffEndpoint`
|
|
120
|
-
| `theme` | `"theme-light" \| "theme-dark"` | `"theme-light"` | Initial theme
|
|
121
|
-
| `onThemeChange` | `(theme) => void` | — | Called when the user toggles the theme
|
|
122
|
-
| `appName` | `string` | `"Aurora"` | App name shown in the header breadcrumb and logo
|
|
123
|
-
| `slots` | `Slots` | — | Optional UI extension points — see [Slots](#slots)
|
|
117
|
+
| Prop | Type | Default | Description |
|
|
118
|
+
| --------------- | ------------------------------- | ---------------- | ----------------------------------------------------------------------- |
|
|
119
|
+
| `bffEndpoint` | `string` | `"/polaris-bff"` | Must match the server's `bffEndpoint` |
|
|
120
|
+
| `theme` | `"theme-light" \| "theme-dark"` | `"theme-light"` | Initial theme |
|
|
121
|
+
| `onThemeChange` | `(theme) => void` | — | Called when the user toggles the theme |
|
|
122
|
+
| `appName` | `string` | `"Aurora"` | App name shown in the header breadcrumb and logo |
|
|
123
|
+
| `slots` | `Slots` | — | Optional UI extension points — see [Slots](#slots) |
|
|
124
|
+
| `onTrackEvent` | `OnTrackEventCallback` | — | Called on user interactions for analytics — see [Analytics](#analytics) |
|
|
124
125
|
|
|
125
126
|
## Slots
|
|
126
127
|
|
|
@@ -178,6 +179,99 @@ function MyBanner(_props: SlotProps) {
|
|
|
178
179
|
}
|
|
179
180
|
```
|
|
180
181
|
|
|
182
|
+
## Analytics
|
|
183
|
+
|
|
184
|
+
Aurora provides an optional `onTrackEvent` callback to track user interactions and feature usage. The API is source-agnostic, supporting various event types like navigation, link clicks, modals, and more.
|
|
185
|
+
|
|
186
|
+
### Basic usage
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { AuroraApp, type TrackEventPayload } from "@cobaltcore-dev/aurora/client"
|
|
190
|
+
|
|
191
|
+
function trackEvent(payload: TrackEventPayload) {
|
|
192
|
+
// Router navigation example:
|
|
193
|
+
// payload.source = "router"
|
|
194
|
+
// payload.action = "/_auth/projects/$projectId/compute/images"
|
|
195
|
+
// payload.metadata = { pathname: "/projects/abc/compute/images", search: "?tab=details", section: "compute", service: "images" }
|
|
196
|
+
|
|
197
|
+
sendAnalytics("user-interaction", {
|
|
198
|
+
source: payload.source,
|
|
199
|
+
action: payload.action,
|
|
200
|
+
...payload.metadata,
|
|
201
|
+
timestamp: Date.now(),
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
;<AuroraApp bffEndpoint="/polaris-bff" onTrackEvent={trackEvent} />
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### TrackEventPayload
|
|
209
|
+
|
|
210
|
+
The callback receives a `TrackEventPayload` object with the following fields:
|
|
211
|
+
|
|
212
|
+
| Field | Type | Description |
|
|
213
|
+
| ---------- | ---------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
214
|
+
| `source` | `string` | Event source (e.g., "router", "external-link", "modal") |
|
|
215
|
+
| `action` | `string` | Action identifier (e.g., route ID, button name, link URL) |
|
|
216
|
+
| `metadata` | `Record<string, string \| number \| boolean \| undefined>` | Source-specific context (pathname, section, service, href, target, etc.) |
|
|
217
|
+
|
|
218
|
+
### Built-in tracking sources
|
|
219
|
+
|
|
220
|
+
#### Router navigation (`source: "router"`)
|
|
221
|
+
|
|
222
|
+
Automatically tracked when users navigate between routes. Fires on every route change via TanStack Router's `onResolved` event.
|
|
223
|
+
|
|
224
|
+
- **`action`**: Route ID (e.g., `"/_auth/projects/$projectId/compute/images"`)
|
|
225
|
+
- **`metadata`**: Always includes `pathname`; includes `search` (query string) when present; optionally includes `section` and `service` if the route defines them in `staticData`
|
|
226
|
+
|
|
227
|
+
**Example event:**
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
{
|
|
231
|
+
source: "router",
|
|
232
|
+
action: "/_auth/projects/$projectId/compute/images",
|
|
233
|
+
metadata: {
|
|
234
|
+
pathname: "/projects/my-project/compute/images",
|
|
235
|
+
search: "?memberStatus=accepted", // Query string, undefined if empty
|
|
236
|
+
section: "compute", // Optional: from route staticData
|
|
237
|
+
service: "images" // Optional: from route staticData
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Extending with custom tracking
|
|
243
|
+
|
|
244
|
+
The `onTrackEvent` callback is available in the router context, allowing any component to track custom interactions:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { useRouteContext } from "@tanstack/react-router"
|
|
248
|
+
|
|
249
|
+
function MyComponent() {
|
|
250
|
+
const { onTrackEvent } = useRouteContext()
|
|
251
|
+
|
|
252
|
+
const handleExternalLinkClick = (href: string) => {
|
|
253
|
+
onTrackEvent?.({
|
|
254
|
+
source: "external-link",
|
|
255
|
+
action: href,
|
|
256
|
+
metadata: { target: "_blank" },
|
|
257
|
+
})
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<a href="https://docs.example.com" onClick={() => handleExternalLinkClick("https://docs.example.com")}>
|
|
262
|
+
Docs
|
|
263
|
+
</a>
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Implementation notes
|
|
269
|
+
|
|
270
|
+
- Router events are tracked via subscription to TanStack Router's `onResolved` event
|
|
271
|
+
- Automatic deduplication - fires once per navigation
|
|
272
|
+
- Errors in your callback are caught and logged to prevent breaking the app
|
|
273
|
+
- The callback executes **after** navigation completes
|
|
274
|
+
|
|
181
275
|
## License
|
|
182
276
|
|
|
183
277
|
Apache-2.0
|
|
@@ -16,6 +16,23 @@ export type Slots = {
|
|
|
16
16
|
/** Replaces the default page footer. Renders outside shadow DOM — inherits page styles. */
|
|
17
17
|
pageFooter?: FC<SlotProps>;
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Payload for analytics tracking events.
|
|
21
|
+
* Generic structure that supports multiple event sources (router, links, modals, etc.)
|
|
22
|
+
*/
|
|
23
|
+
export type TrackEventPayload = {
|
|
24
|
+
/** Source of the event (e.g., "router", "external-link", "modal", "button") */
|
|
25
|
+
source: string;
|
|
26
|
+
/** Action identifier describing what happened (e.g., route ID, button name, link URL) */
|
|
27
|
+
action: string;
|
|
28
|
+
/** Additional context specific to the source. For router: pathname, section, service. For links: href, target. */
|
|
29
|
+
metadata?: Record<string, string | number | boolean | undefined>;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Callback invoked when users interact with trackable features.
|
|
33
|
+
* Use this to send analytics data about feature usage patterns.
|
|
34
|
+
*/
|
|
35
|
+
export type OnTrackEventCallback = (payload: TrackEventPayload) => void;
|
|
19
36
|
/** Props for the top-level `<AuroraApp />` component. */
|
|
20
37
|
export type AuroraAppProps = {
|
|
21
38
|
/** Initial theme. Defaults to `"theme-light"`. */
|
|
@@ -28,5 +45,26 @@ export type AuroraAppProps = {
|
|
|
28
45
|
slots?: Slots;
|
|
29
46
|
/** App name shown in the header breadcrumb and as the default logo title. Defaults to `"Aurora"`. */
|
|
30
47
|
appName?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Analytics callback for tracking user interactions and feature usage.
|
|
50
|
+
* Called for various user actions like navigation, external link clicks, etc.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* function trackEvent(payload: TrackEventPayload) {
|
|
55
|
+
* // Router navigation: payload.action = "/_auth/projects/$projectId/compute/images"
|
|
56
|
+
* // External link: payload.action = "https://docs.example.com"
|
|
57
|
+
* sendAnalytics('user-interaction', {
|
|
58
|
+
* action: payload.action,
|
|
59
|
+
* source: payload.source,
|
|
60
|
+
* ...payload.metadata,
|
|
61
|
+
* timestamp: Date.now()
|
|
62
|
+
* })
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* <AuroraApp onTrackEvent={trackEvent} />
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
onTrackEvent?: OnTrackEventCallback;
|
|
31
69
|
};
|
|
32
70
|
export declare const AuroraApp: FC<AuroraAppProps>;
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as e, C as t, Q as n, Y as r, c as i, o as a, st as o } from "./build-BdRRmNf5.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: n, tooltipContent: o, 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 (e) => {
|
|
8
|
+
e.preventDefault(), e.stopPropagation();
|
|
9
9
|
try {
|
|
10
|
-
await navigator.clipboard.writeText(
|
|
10
|
+
await navigator.clipboard.writeText(n), 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 && n.length > f ? `${n.slice(0, f)}...` : n, w = () => _ ? o || 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(e, {
|
|
19
19
|
open: T,
|
|
20
|
-
children: [/*#__PURE__*/ s(
|
|
20
|
+
children: [/*#__PURE__*/ s(a, {
|
|
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: n }
|
|
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(r, {
|
|
34
34
|
direction: "horizontal",
|
|
35
35
|
gap: "1",
|
|
36
36
|
className: "items-center hover:underline",
|
|
37
37
|
children: [/*#__PURE__*/ s("span", {
|
|
38
38
|
className: "select-none",
|
|
39
39
|
children: C
|
|
40
|
-
}), /*#__PURE__*/ s(
|
|
40
|
+
}), /*#__PURE__*/ s(i, {
|
|
41
41
|
icon: _ ? "check" : "contentCopy",
|
|
42
42
|
size: "18"
|
|
43
43
|
})]
|
|
44
44
|
})
|
|
45
45
|
})
|
|
46
|
-
}), /*#__PURE__*/ s(
|
|
46
|
+
}), /*#__PURE__*/ s(t, { 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: e, projectId: t, description: r, actions: i }) {
|
|
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(
|
|
57
|
-
className: "text-theme-light flex items-center gap-1 text-sm",
|
|
56
|
+
children: [/*#__PURE__*/ s(n, { children: e }), /*#__PURE__*/ c("div", {
|
|
57
|
+
className: "text-theme-light flex shrink-0 items-center gap-1 text-sm",
|
|
58
58
|
children: [/*#__PURE__*/ c("span", {
|
|
59
59
|
className: "font-semibold",
|
|
60
60
|
children: [
|
|
@@ -63,19 +63,23 @@ function p({ title: t, projectId: n, actions: r }) {
|
|
|
63
63
|
" "
|
|
64
64
|
]
|
|
65
65
|
}), /*#__PURE__*/ s(f, {
|
|
66
|
-
text:
|
|
66
|
+
text: t,
|
|
67
67
|
truncateAt: 15
|
|
68
68
|
})]
|
|
69
69
|
})]
|
|
70
70
|
}),
|
|
71
|
-
/*#__PURE__*/ s(
|
|
72
|
-
|
|
73
|
-
className: "mt-3 flex justify-end",
|
|
71
|
+
r && /*#__PURE__*/ s("p", {
|
|
72
|
+
className: "text-sm font-normal",
|
|
74
73
|
children: r
|
|
74
|
+
}),
|
|
75
|
+
/*#__PURE__*/ s(o, { className: "mt-4" }),
|
|
76
|
+
i && /*#__PURE__*/ s("div", {
|
|
77
|
+
className: "mt-3 flex justify-end",
|
|
78
|
+
children: i
|
|
75
79
|
})
|
|
76
80
|
] });
|
|
77
81
|
}
|
|
78
82
|
//#endregion
|
|
79
83
|
export { f as n, p as t };
|
|
80
84
|
|
|
81
|
-
//# sourceMappingURL=ContentHeader-
|
|
85
|
+
//# sourceMappingURL=ContentHeader-C51H95X8.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentHeader-C51H95X8.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","description","actions","header","div","className","span","text","truncateAt","p"],"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 description?: string | null\n actions?: ReactNode\n}\n\nexport function ContentHeader({ title, projectId, description, 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 shrink-0 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 {description && <p className=\"text-sm font-normal\">{description}</p>}\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;;;AC/DA,SAAgBmB,EAAc,EAAEC,UAAOC,cAAWC,gBAAaC,cAA6B;CAC1F,OACE,gBAACC,UAAAA,EAAAA,UAAAA;EACC,gBAACC,OAAAA;GAAIC,WAAU;cACb,gBAACT,GAAAA,EAAAA,UAAgBG,EAAAA,CAAAA,GACjB,gBAACK,OAAAA;IAAIC,WAAU;eACb,gBAACC,QAAAA;KAAKD,WAAU;;MACd,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;MAAyB;MAAE;;QAE7B,gBAACR,GAAAA;KAAcU,MAAMP;KAAWQ,YAAY;;;;EAG/CP,KAAe,gBAACQ,KAAAA;GAAEJ,WAAU;aAAuBJ;;EACpD,gBAACN,GAAAA,EAAQU,WAAU,OAAA,CAAA;EAClBH,KAAW,gBAACE,OAAAA;GAAIC,WAAU;aAAyBH;;;AAG1D"}
|