@cobaltcore-dev/aurora 0.4.0 → 0.6.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.
Files changed (178) hide show
  1. package/README.md +73 -77
  2. package/dist/client/AuroraApp.d.ts +15 -0
  3. package/dist/client/{AuthProvider-D-5Jpa6F.mjs → AuthProvider-Co4d0WzB.mjs} +3 -3
  4. package/dist/client/{AuthProvider-D-5Jpa6F.mjs.map → AuthProvider-Co4d0WzB.mjs.map} +1 -1
  5. package/dist/client/{ContentHeader-BXZoN3B9.mjs → ContentHeader-kx1Th5Sq.mjs} +29 -29
  6. package/dist/client/{ContentHeader-BXZoN3B9.mjs.map → ContentHeader-kx1Th5Sq.mjs.map} +1 -1
  7. package/dist/client/DeleteFlavorModal-C3cb7YiJ.mjs +638 -0
  8. package/dist/client/DeleteFlavorModal-C3cb7YiJ.mjs.map +1 -0
  9. package/dist/client/{EditSecurityGroupModal-DK3WYikA.mjs → EditSecurityGroupModal-CpP54WIK.mjs} +22 -22
  10. package/dist/client/{EditSecurityGroupModal-DK3WYikA.mjs.map → EditSecurityGroupModal-CpP54WIK.mjs.map} +1 -1
  11. package/dist/client/{FiltersInput-OVeIJzIo.mjs → FiltersInput-DxcyR6Bp.mjs} +18 -18
  12. package/dist/client/{FiltersInput-OVeIJzIo.mjs.map → FiltersInput-DxcyR6Bp.mjs.map} +1 -1
  13. package/dist/client/{FloatingIpActionModals-Dok7fJss.mjs → FloatingIpActionModals-BP8RWHbu.mjs} +77 -77
  14. package/dist/client/{FloatingIpActionModals-Dok7fJss.mjs.map → FloatingIpActionModals-BP8RWHbu.mjs.map} +1 -1
  15. package/dist/client/ImageToastNotifications-TZ3EfQg-.mjs +1219 -0
  16. package/dist/client/ImageToastNotifications-TZ3EfQg-.mjs.map +1 -0
  17. package/dist/client/{RouteError-pDEWC_k7.mjs → RouteError-QSV7qOoJ.mjs} +6 -6
  18. package/dist/client/{RouteError-pDEWC_k7.mjs.map → RouteError-QSV7qOoJ.mjs.map} +1 -1
  19. package/dist/client/{SortInput-DXWSqSny.mjs → SortInput-CYv2_Pur.mjs} +6 -6
  20. package/dist/client/{SortInput-DXWSqSny.mjs.map → SortInput-CYv2_Pur.mjs.map} +1 -1
  21. package/dist/client/{_auth-CJj1Cnbm.mjs → _auth-DXJkv9QO.mjs} +3 -3
  22. package/dist/client/{_auth-CJj1Cnbm.mjs.map → _auth-DXJkv9QO.mjs.map} +1 -1
  23. package/dist/client/{_flavorId-BoNcxYmF.mjs → _flavorId-C2x43-6S.mjs} +15 -15
  24. package/dist/client/_flavorId-C2x43-6S.mjs.map +1 -0
  25. package/dist/client/_flavorId-CR8ZUI-P.mjs +194 -0
  26. package/dist/client/_flavorId-CR8ZUI-P.mjs.map +1 -0
  27. package/dist/client/{_floatingIpId-D33bOEmH.mjs → _floatingIpId-BCk41_Lb.mjs} +3 -3
  28. package/dist/client/{_floatingIpId-D33bOEmH.mjs.map → _floatingIpId-BCk41_Lb.mjs.map} +1 -1
  29. package/dist/client/{_floatingIpId-DF_BSJN6.mjs → _floatingIpId-BGrOAmPT.mjs} +48 -48
  30. package/dist/client/{_floatingIpId-DF_BSJN6.mjs.map → _floatingIpId-BGrOAmPT.mjs.map} +1 -1
  31. package/dist/client/_imageId-CvfD832b.mjs +534 -0
  32. package/dist/client/_imageId-CvfD832b.mjs.map +1 -0
  33. package/dist/client/_pcaId-BxBt5DXi.mjs +459 -0
  34. package/dist/client/_pcaId-BxBt5DXi.mjs.map +1 -0
  35. package/dist/client/{_pcaId-BYCoeK6_.mjs → _pcaId-DOHycvCf.mjs} +3 -3
  36. package/dist/client/{_pcaId-BYCoeK6_.mjs.map → _pcaId-DOHycvCf.mjs.map} +1 -1
  37. package/dist/client/_projectId-BDSWnMGj.mjs +46 -0
  38. package/dist/client/_projectId-BDSWnMGj.mjs.map +1 -0
  39. package/dist/client/{_projectId-OW2xkK43.mjs → _projectId-DOgwFiqD.mjs} +3 -3
  40. package/dist/client/{_projectId-OW2xkK43.mjs.map → _projectId-DOgwFiqD.mjs.map} +1 -1
  41. package/dist/client/_projectId-DS4nR59B.mjs +299 -0
  42. package/dist/client/_projectId-DS4nR59B.mjs.map +1 -0
  43. package/dist/client/{_projectId-BwLMEMGC.mjs → _projectId-MxcHrXW4.mjs} +21 -21
  44. package/dist/client/_projectId-MxcHrXW4.mjs.map +1 -0
  45. package/dist/client/{_securityGroupId-B-Z-CzLp.mjs → _securityGroupId-CJJanWiY.mjs} +3 -3
  46. package/dist/client/{_securityGroupId-B-Z-CzLp.mjs.map → _securityGroupId-CJJanWiY.mjs.map} +1 -1
  47. package/dist/client/{_securityGroupId-B1bOYRbX.mjs → _securityGroupId-KKw4RPdH.mjs} +445 -446
  48. package/dist/client/{_securityGroupId-B1bOYRbX.mjs.map → _securityGroupId-KKw4RPdH.mjs.map} +1 -1
  49. package/dist/client/{containers-BjWqjNOx.mjs → _storageType-4wSxI__0.mjs} +19 -16
  50. package/dist/client/_storageType-4wSxI__0.mjs.map +1 -0
  51. package/dist/client/_storageType-DYjo-6ej.mjs +3243 -0
  52. package/dist/client/_storageType-DYjo-6ej.mjs.map +1 -0
  53. package/dist/client/_storageType-zeSZe--V.mjs +7 -0
  54. package/dist/client/_storageType-zeSZe--V.mjs.map +1 -0
  55. package/dist/client/about-Bo9vxGHy.mjs +92 -0
  56. package/dist/client/{about-DLn1ShhF.mjs.map → about-Bo9vxGHy.mjs.map} +1 -1
  57. package/dist/client/aurora-DDzsst74.mjs +19 -0
  58. package/dist/client/{aurora-CRcxVUCo.mjs.map → aurora-DDzsst74.mjs.map} +1 -1
  59. package/dist/client/{build-BJDfnAyi.mjs → build-DeJcDjPi.mjs} +3802 -3376
  60. package/dist/client/build-DeJcDjPi.mjs.map +1 -0
  61. package/dist/client/{buildFilterParams-TeyosGyK.mjs → buildFilterParams-DoZzMKX9.mjs} +1 -1
  62. package/dist/client/{buildFilterParams-TeyosGyK.mjs.map → buildFilterParams-DoZzMKX9.mjs.map} +1 -1
  63. package/dist/client/{cn-C3laVXMm.mjs → cn-DM4Cy3jv.mjs} +1 -1
  64. package/dist/client/{cn-C3laVXMm.mjs.map → cn-DM4Cy3jv.mjs.map} +1 -1
  65. package/dist/client/constants-BmcGYeR-.mjs +153 -0
  66. package/dist/client/constants-BmcGYeR-.mjs.map +1 -0
  67. package/dist/client/{flavors-D8oElC2K.mjs → flavors-BxFVqgnb.mjs} +2 -2
  68. package/dist/client/{flavors-D8oElC2K.mjs.map → flavors-BxFVqgnb.mjs.map} +1 -1
  69. package/dist/client/flavors-CfdgjsZY.mjs +632 -0
  70. package/dist/client/flavors-CfdgjsZY.mjs.map +1 -0
  71. package/dist/client/{flavors-BXPYAFyQ.mjs → flavors-DWMZ6TuJ.mjs} +2 -2
  72. package/dist/client/{flavors-BXPYAFyQ.mjs.map → flavors-DWMZ6TuJ.mjs.map} +1 -1
  73. package/dist/client/{floatingips-Fa6ocNUu.mjs → floatingips-ByRb82wS.mjs} +138 -139
  74. package/dist/client/{floatingips-Fa6ocNUu.mjs.map → floatingips-ByRb82wS.mjs.map} +1 -1
  75. package/dist/client/{formatBytes-tQBEnPoL.mjs → formatBytes-CZv_XyCY.mjs} +1 -1
  76. package/dist/client/{formatBytes-tQBEnPoL.mjs.map → formatBytes-CZv_XyCY.mjs.map} +1 -1
  77. package/dist/client/{helpers--JWXi40U.mjs → helpers-1PpYf-fC.mjs} +1 -1
  78. package/dist/client/{helpers--JWXi40U.mjs.map → helpers-1PpYf-fC.mjs.map} +1 -1
  79. package/dist/client/hooks-dSArr2Ca.mjs +2 -0
  80. package/dist/client/images-CKqIXUq52.mjs +1873 -0
  81. package/dist/client/images-CKqIXUq52.mjs.map +1 -0
  82. package/dist/client/{images-tYfyOkX8.mjs → images-C_dX7nY6.mjs} +3 -3
  83. package/dist/client/{images-tYfyOkX8.mjs.map → images-C_dX7nY6.mjs.map} +1 -1
  84. package/dist/client/{images-CTLCY-yY.mjs → images-CenluYV8.mjs} +2 -2
  85. package/dist/client/{images-CTLCY-yY.mjs.map → images-CenluYV8.mjs.map} +1 -1
  86. package/dist/client/{images-DM9I8G0p.mjs → images-NBf2bV43.mjs} +2 -2
  87. package/dist/client/{images-DM9I8G0p.mjs.map → images-NBf2bV43.mjs.map} +1 -1
  88. package/dist/client/index.js +428 -477
  89. package/dist/client/index.js.map +1 -1
  90. package/dist/client/{md-BivyCkGC.mjs → md-CYTrL5dq.mjs} +58 -22
  91. package/dist/client/{md-BivyCkGC.mjs.map → md-CYTrL5dq.mjs.map} +1 -1
  92. package/dist/client/{network-rYLHyf15.mjs → network-DuZm76BZ.mjs} +2 -2
  93. package/dist/client/{network-rYLHyf15.mjs.map → network-DuZm76BZ.mjs.map} +1 -1
  94. package/dist/client/objects-BJM6YeuF.mjs +5708 -0
  95. package/dist/client/objects-BJM6YeuF.mjs.map +1 -0
  96. package/dist/client/objects-gxSjvbvF.mjs +101 -0
  97. package/dist/client/objects-gxSjvbvF.mjs.map +1 -0
  98. package/dist/client/objects-o2Cj_ndZ.mjs +8 -0
  99. package/dist/client/objects-o2Cj_ndZ.mjs.map +1 -0
  100. package/dist/client/{pca-COmKvp3J.mjs → pca-Bl8NmoVZ.mjs} +2 -2
  101. package/dist/client/{pca-COmKvp3J.mjs.map → pca-Bl8NmoVZ.mjs.map} +1 -1
  102. package/dist/client/pca-RSiWpJs9.mjs +182 -0
  103. package/dist/client/pca-RSiWpJs9.mjs.map +1 -0
  104. package/dist/client/projects-CgclWI16.mjs +105 -0
  105. package/dist/client/projects-CgclWI16.mjs.map +1 -0
  106. package/dist/client/{projects-DI_L4oDw.mjs → projects-D2iewAzu.mjs} +2 -2
  107. package/dist/client/{projects-DI_L4oDw.mjs.map → projects-D2iewAzu.mjs.map} +1 -1
  108. package/dist/client/{projects-Dl5XkXUP.mjs → projects-pe2_dCnV.mjs} +3 -3
  109. package/dist/client/{projects-Dl5XkXUP.mjs.map → projects-pe2_dCnV.mjs.map} +1 -1
  110. package/dist/client/{projects-HoQ0gE5Y.mjs → projects-yiK0HGSA.mjs} +2 -2
  111. package/dist/client/{projects-HoQ0gE5Y.mjs.map → projects-yiK0HGSA.mjs.map} +1 -1
  112. package/dist/client/{securitygroups-BjkmHk2J.mjs → securitygroups-DahZkVYQ.mjs} +139 -140
  113. package/dist/client/{securitygroups-BjkmHk2J.mjs.map → securitygroups-DahZkVYQ.mjs.map} +1 -1
  114. package/dist/client/{trpcClient-BxguzNYF.mjs → trpcClient-BzPUgiM2.mjs} +1 -1
  115. package/dist/client/{trpcClient-BxguzNYF.mjs.map → trpcClient-BzPUgiM2.mjs.map} +1 -1
  116. package/dist/client/{useErrorTranslation-TZVwIAzq.mjs → useErrorTranslation-Dc0eE8Zt.mjs} +1 -1
  117. package/dist/client/{useErrorTranslation-TZVwIAzq.mjs.map → useErrorTranslation-Dc0eE8Zt.mjs.map} +1 -1
  118. package/dist/client/useListWithFiltering-DaYcu5AB.mjs +157 -0
  119. package/dist/client/useListWithFiltering-DaYcu5AB.mjs.map +1 -0
  120. package/dist/client/{useModal-DxxlilRm.mjs → useModal-DCs1OJh7.mjs} +1 -1
  121. package/dist/client/{useModal-DxxlilRm.mjs.map → useModal-DCs1OJh7.mjs.map} +1 -1
  122. package/dist/client/{useProjectId-OQv2KBbG.mjs → useProjectId-DBc5lpoU.mjs} +1 -1
  123. package/dist/client/{useProjectId-OQv2KBbG.mjs.map → useProjectId-DBc5lpoU.mjs.map} +1 -1
  124. package/dist/server/index.js +1285 -435
  125. package/package.json +5 -4
  126. package/dist/client/DeleteFlavorModal-BusYn32r.mjs +0 -629
  127. package/dist/client/DeleteFlavorModal-BusYn32r.mjs.map +0 -1
  128. package/dist/client/ImageToastNotifications-BG9LPnXf.mjs +0 -1267
  129. package/dist/client/ImageToastNotifications-BG9LPnXf.mjs.map +0 -1
  130. package/dist/client/ListToolbar-BojRTNbo.mjs +0 -129
  131. package/dist/client/ListToolbar-BojRTNbo.mjs.map +0 -1
  132. package/dist/client/_flavorId-BRonXvCo.mjs +0 -188
  133. package/dist/client/_flavorId-BRonXvCo.mjs.map +0 -1
  134. package/dist/client/_flavorId-BoNcxYmF.mjs.map +0 -1
  135. package/dist/client/_imageId-BL0I5_pv.mjs +0 -527
  136. package/dist/client/_imageId-BL0I5_pv.mjs.map +0 -1
  137. package/dist/client/_pcaId-CbBhBrX1.mjs +0 -466
  138. package/dist/client/_pcaId-CbBhBrX1.mjs.map +0 -1
  139. package/dist/client/_projectId-5NiasyXm.mjs +0 -26
  140. package/dist/client/_projectId-5NiasyXm.mjs.map +0 -1
  141. package/dist/client/_projectId-BwLMEMGC.mjs.map +0 -1
  142. package/dist/client/_projectId-D35MN1kY.mjs +0 -316
  143. package/dist/client/_projectId-D35MN1kY.mjs.map +0 -1
  144. package/dist/client/about-DLn1ShhF.mjs +0 -92
  145. package/dist/client/aurora-CRcxVUCo.mjs +0 -19
  146. package/dist/client/build-BJDfnAyi.mjs.map +0 -1
  147. package/dist/client/constants-B-P2r5F1.mjs +0 -128
  148. package/dist/client/constants-B-P2r5F1.mjs.map +0 -1
  149. package/dist/client/containers-BjWqjNOx.mjs.map +0 -1
  150. package/dist/client/containers-DsRWc1L5.mjs +0 -7
  151. package/dist/client/containers-DsRWc1L5.mjs.map +0 -1
  152. package/dist/client/containers-J7WFA18U.mjs +0 -3120
  153. package/dist/client/containers-J7WFA18U.mjs.map +0 -1
  154. package/dist/client/flavors-qvgPSI7J.mjs +0 -613
  155. package/dist/client/flavors-qvgPSI7J.mjs.map +0 -1
  156. package/dist/client/hooks-DEjb9d1F.mjs +0 -2
  157. package/dist/client/images-CSFfefAu.mjs +0 -1901
  158. package/dist/client/images-CSFfefAu.mjs.map +0 -1
  159. package/dist/client/objects-BciXwZ00.mjs +0 -86
  160. package/dist/client/objects-BciXwZ00.mjs.map +0 -1
  161. package/dist/client/objects-Cdew99tK.mjs +0 -8
  162. package/dist/client/objects-Cdew99tK.mjs.map +0 -1
  163. package/dist/client/objects-DaElrban.mjs +0 -5340
  164. package/dist/client/objects-DaElrban.mjs.map +0 -1
  165. package/dist/client/overview-BMhjFMIV.mjs +0 -15
  166. package/dist/client/overview-BMhjFMIV.mjs.map +0 -1
  167. package/dist/client/overview-BYIRj7_X.mjs +0 -15
  168. package/dist/client/overview-BYIRj7_X.mjs.map +0 -1
  169. package/dist/client/overview-DRCKNBH2.mjs +0 -15
  170. package/dist/client/overview-DRCKNBH2.mjs.map +0 -1
  171. package/dist/client/overview-urYLOVQE.mjs +0 -173
  172. package/dist/client/overview-urYLOVQE.mjs.map +0 -1
  173. package/dist/client/pca-oc7J0_Xd.mjs +0 -167
  174. package/dist/client/pca-oc7J0_Xd.mjs.map +0 -1
  175. package/dist/client/projects-BUabCzvw.mjs +0 -95
  176. package/dist/client/projects-BUabCzvw.mjs.map +0 -1
  177. package/dist/client/useListWithFiltering-CbhHJO4V.mjs +0 -32
  178. package/dist/client/useListWithFiltering-CbhHJO4V.mjs.map +0 -1
package/README.md CHANGED
@@ -18,39 +18,31 @@ npm install react react-dom fastify
18
18
 
19
19
  Aurora has two entry points: `server` and `client`.
20
20
 
21
- ### Server (`src/server/server.ts`)
21
+ ### Server
22
22
 
23
23
  ```ts
24
24
  import path from "path"
25
25
  import { createServer } from "@cobaltcore-dev/aurora/server"
26
26
 
27
- createServer({
28
- viteRoot: path.resolve(__dirname, "../.."), // root of your app (where dist/client lives)
29
- identityEndpoint: process.env.IDENTITY_ENDPOINT, // OpenStack Keystone URL
30
- bffEndpoint: process.env.BFF_ENDPOINT, // tRPC prefix, default "/polaris-bff"
31
- defaultEndpointInterface: process.env.DEFAULT_ENDPOINT_INTERFACE, // "public" | "internal"
32
- proxyUrl: process.env.GLOBAL_AGENT_HTTP_PROXY, // optional HTTP proxy (dev only)
33
- cephRegion: process.env.CEPH_REGION, // Ceph/S3 region for object storage
34
- imageMetadataExcludedProperties: process.env.IMAGE_METADATA_EXCLUDED_PROPERTIES, // comma-separated
35
- insecureCookies: process.env.INSECURE_COOKIES === "true", // disable Secure flag locally
36
- }).then((server) => server.listen({ host: "0.0.0.0", port: 4000 }))
27
+ const server = await createServer({
28
+ identityEndpoint: "https://keystone.example.com/v3/",
29
+ policyDir: path.resolve(__dirname, "../policies"),
30
+ })
31
+
32
+ server.listen({ host: "0.0.0.0", port: 4000 })
37
33
  ```
38
34
 
39
- ### Client (`src/client/App.tsx`)
35
+ ### Client
40
36
 
41
37
  ```tsx
42
38
  import { AuroraApp } from "@cobaltcore-dev/aurora/client"
43
- import "@cobaltcore-dev/aurora/client/style.css" // include once at your app root
44
39
 
45
40
  export function App() {
46
41
  return (
47
42
  <AuroraApp
48
- bffEndpoint="/polaris-bff" // must match the server's bffEndpoint
49
- theme="theme-light" // "theme-light" | "theme-dark"
50
- onThemeChange={(theme) => {
51
- // called when user toggles — persist however you like
52
- localStorage.setItem("theme", theme)
53
- }}
43
+ bffEndpoint="/polaris-bff"
44
+ theme="theme-light"
45
+ onThemeChange={(theme) => localStorage.setItem("theme", theme)}
54
46
  />
55
47
  )
56
48
  }
@@ -60,80 +52,84 @@ export function App() {
60
52
 
61
53
  ### `createServer(config)`
62
54
 
63
- | Option | Type | Default | Description |
64
- | --------------------------------- | --------- | -------------------------- | ---------------------------------------------------------------- |
65
- | `identityEndpoint` | `string` | — | OpenStack Keystone v3 URL (required) |
66
- | `bffEndpoint` | `string` | `"/polaris-bff"` | URL prefix for all tRPC routes |
67
- | `viteRoot` | `string` | `__dirname/../../` | Directory that contains `dist/client/` in production |
68
- | `defaultEndpointInterface` | `string` | `"public"` | OpenStack service catalog interface |
69
- | `proxyUrl` | `string` | | HTTP proxy for OpenStack calls (dev only, ignored in production) |
70
- | `cephRegion` | `string` | — | Ceph RGW region for S3 operations |
71
- | `imageMetadataExcludedProperties` | `string` | — | Comma-separated image metadata keys to hide in the UI |
72
- | `cookieName` | `string` | `"dashboard-session-auth"` | Override the session cookie name |
73
- | `crossDomainCookie` | `boolean` | `true` | Share cookie across subdomains |
74
- | `insecureCookies` | `boolean` | `false` | Disable `Secure` flag only for HTTP-only local dev |
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 |
75
68
 
76
69
  ### `<AuroraApp />`
77
70
 
78
- | Prop | Type | Default | Description |
79
- | --------------- | ------------------------------- | ---------------- | -------------------------------------- |
80
- | `bffEndpoint` | `string` | `"/polaris-bff"` | Must match the server's `bffEndpoint` |
81
- | `theme` | `"theme-light" \| "theme-dark"` | `"theme-light"` | Initial theme |
82
- | `onThemeChange` | `(theme) => void` | — | Called when the user toggles the theme |
71
+ | Prop | Type | Default | Description |
72
+ | --------------- | ------------------------------- | ---------------- | -------------------------------------------------- |
73
+ | `bffEndpoint` | `string` | `"/polaris-bff"` | Must match the server's `bffEndpoint` |
74
+ | `theme` | `"theme-light" \| "theme-dark"` | `"theme-light"` | Initial theme |
75
+ | `onThemeChange` | `(theme) => void` | — | Called when the user toggles the theme |
76
+ | `appName` | `string` | `"Aurora"` | App name shown in the header breadcrumb and logo |
77
+ | `slots` | `Slots` | — | Optional UI extension points — see [Slots](#slots) |
83
78
 
84
- ## Environment variables
79
+ ## Slots
85
80
 
86
- Your app reads these from `.env` and passes them to `createServer()`. Aurora itself never reads environment variables.
81
+ Slots let you inject your own React components into specific locations inside `AuroraApp` without forking the package. Each slot receives an `auroraContext` object with a `client` (tRPC client) for making API calls.
87
82
 
88
- ```env
89
- IDENTITY_ENDPOINT="https://keystone.example.com/v3/"
90
- DEFAULT_ENDPOINT_INTERFACE="public"
91
- BFF_ENDPOINT="/polaris-bff"
92
- PORT="4000"
83
+ ```tsx
84
+ import type { SlotProps } from "@cobaltcore-dev/aurora/client"
93
85
 
94
- # Object storage (optional)
95
- CEPH_REGION="ceph-objectstore-st1-region-1"
86
+ function MyLogo(_props: SlotProps) {
87
+ return <img src="/my-logo.svg" alt="My App" style={{ height: "1.5rem" }} />
88
+ }
96
89
 
97
- # Local dev only
98
- INSECURE_COOKIES=true
99
- # GLOBAL_AGENT_HTTP_PROXY=http://localhost:8888
100
- ```
90
+ function MyBanner({ auroraContext }: SlotProps) {
91
+ // auroraContext.client gives you access to the tRPC API
92
+ return <div>Custom sidebar content</div>
93
+ }
101
94
 
102
- The `VITE_BFF_ENDPOINT` variable (prefixed with `VITE_`) is read by Vite and passed to the client:
95
+ function MyFooter(_props: SlotProps) {
96
+ return (
97
+ <footer>
98
+ <a href="/imprint">Imprint</a> · <a href="/privacy">Privacy</a>
99
+ </footer>
100
+ )
101
+ }
103
102
 
104
- ```env
105
- VITE_BFF_ENDPOINT="/polaris-bff"
103
+ ;<AuroraApp
104
+ slots={{
105
+ logo: MyLogo,
106
+ sideNavBanner: MyBanner,
107
+ pageFooter: MyFooter,
108
+ }}
109
+ />
106
110
  ```
107
111
 
108
- ```tsx
109
- <AuroraApp bffEndpoint={import.meta.env.VITE_BFF_ENDPOINT} />
110
- ```
112
+ ### Available slots
111
113
 
112
- ## Vite config
114
+ | Slot | Location | Renders in shadow DOM |
115
+ | --------------- | ----------------------------------------------- | --------------------- |
116
+ | `logo` | Page header, replacing the default Aurora logo | No |
117
+ | `sideNavBanner` | Bottom of the project side navigation | Yes |
118
+ | `pageFooter` | Page footer, replacing the default empty footer | No |
113
119
 
114
- In development, point Vite at your own server plugin. In production no extra plugins are needed aurora ships pre-built CSS and assets.
120
+ **Shadow DOM isolation:** Slots rendered in a shadow DOM cannot inherit styles from the host page. If your slot component uses a CSS framework, inject the styles inline:
115
121
 
116
- ```js
117
- // vite.config.mjs
118
- import { defineConfig } from "vite"
119
- import react from "@vitejs/plugin-react-swc"
120
- import viteFastify from "@fastify/vite/plugin"
121
-
122
- export default defineConfig(({ mode }) => ({
123
- root: "./src/client",
124
- build: { outDir: "../../dist/client" },
125
- plugins: [mode !== "production" && viteFastify(), react()],
126
- }))
127
- ```
128
-
129
- ## Running the app
130
-
131
- ```bash
132
- # Development (hot-reload)
133
- tsx watch --env-file=.env src/server/server.ts
122
+ ```tsx
123
+ import styles from "my-lib/styles.css?inline"
134
124
 
135
- # Production
136
- NODE_ENV=production tsx --env-file=.env src/server/server.ts
125
+ function MyBanner(_props: SlotProps) {
126
+ return (
127
+ <>
128
+ <style>{styles}</style>
129
+ <div>...</div>
130
+ </>
131
+ )
132
+ }
137
133
  ```
138
134
 
139
135
  ## License
@@ -1,17 +1,32 @@
1
1
  import { FC } from 'react';
2
2
  import { TrpcClient } from './trpcClient';
3
+ /** Context object passed to every slot component. */
3
4
  export type SlotProps = {
4
5
  auroraContext: {
6
+ /** tRPC client for making API calls to the Aurora BFF. */
5
7
  client: TrpcClient;
6
8
  };
7
9
  };
10
+ /** Named extension points where consumers can inject their own React components. */
8
11
  export type Slots = {
12
+ /** Replaces the default Aurora logo in the page header. Renders outside shadow DOM — inherits header styles. */
13
+ logo?: FC<SlotProps>;
14
+ /** Rendered at the bottom of the project side navigation. Renders inside a shadow DOM. */
9
15
  sideNavBanner?: FC<SlotProps>;
16
+ /** Replaces the default page footer. Renders outside shadow DOM — inherits page styles. */
17
+ pageFooter?: FC<SlotProps>;
10
18
  };
19
+ /** Props for the top-level `<AuroraApp />` component. */
11
20
  export type AuroraAppProps = {
21
+ /** Initial theme. Defaults to `"theme-light"`. */
12
22
  theme?: "theme-dark" | "theme-light";
23
+ /** URL prefix for all tRPC routes. Must match the server's `bffEndpoint`. Defaults to `"/polaris-bff"`. */
13
24
  bffEndpoint?: string;
25
+ /** Called when the user toggles the theme. Use this to persist the selection. */
14
26
  onThemeChange?: (theme: "theme-dark" | "theme-light") => void;
27
+ /** Optional UI extension points. */
15
28
  slots?: Slots;
29
+ /** App name shown in the header breadcrumb and as the default logo title. Defaults to `"Aurora"`. */
30
+ appName?: string;
16
31
  };
17
32
  export declare const AuroraApp: FC<AuroraAppProps>;
@@ -2,7 +2,7 @@ import { jsx as e } from "react/jsx-runtime";
2
2
  import t, { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
3
3
  import { useRouter as o } from "@tanstack/react-router";
4
4
  //#region src/client/store/AuthProvider.tsx
5
- var s = /* @__PURE__ */ t.createContext(null), c = 3600 * 1e3;
5
+ var s = /*#__PURE__*/ t.createContext(null), c = 3600 * 1e3;
6
6
  function l({ children: l }) {
7
7
  let u = o(), [d, f] = t.useState(null), [p, m] = t.useState(void 0), [h, g] = t.useState(void 0), [_, v] = a(!1), [y, b] = a(void 0), x = i(null), S = i(null), C = !!d, w = n(() => {
8
8
  x.current &&= (clearTimeout(x.current), null);
@@ -74,7 +74,7 @@ function l({ children: l }) {
74
74
  C,
75
75
  O,
76
76
  T
77
- ]), /* @__PURE__ */ e(s.Provider, {
77
+ ]), /*#__PURE__*/ e(s.Provider, {
78
78
  value: {
79
79
  isAuthenticated: C,
80
80
  user: d,
@@ -97,4 +97,4 @@ function u() {
97
97
  //#endregion
98
98
  export { u as n, l as t };
99
99
 
100
- //# sourceMappingURL=AuthProvider-D-5Jpa6F.mjs.map
100
+ //# sourceMappingURL=AuthProvider-Co4d0WzB.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthProvider-D-5Jpa6F.mjs","names":["React","useEffect","useRef","useCallback","useState","useRouter","AuthContext","createContext","INACTIVITY_TIMEOUT","AuthProvider","children","router","user","setUser","expiresAt","setExpiresAt","undefined","logoutReason","setLogoutReason","showInactivityModal","setShowInactivityModal","redirectAfterModal","setRedirectAfterModal","logoutTimerRef","inactivityTimerRef","isAuthenticated","clearLogoutTimer","current","clearTimeout","clearInactivityTimer","closeInactivityModal","navigate","to","search","redirect","logout","reason","currentPath","window","location","pathname","startsWith","invalidate","resetInactivityTimer","setTimeout","login","expires_at","expiration","Date","timeUntilExpiry","getTime","now","events","handleActivity","forEach","event","document","addEventListener","removeEventListener","Provider","value","useAuth","context","useContext","Error"],"sources":["../../src/client/store/AuthProvider.tsx"],"sourcesContent":["import React, { useEffect, useRef, useCallback, useState } from \"react\"\nimport { TokenData } from \"../../server/Authentication/types/models\"\nimport { useRouter } from \"@tanstack/react-router\"\n\nexport type User = TokenData[\"user\"] | null\n\nexport interface AuthContext {\n isAuthenticated: boolean\n login: (user: User, expires_at?: string) => Promise<void>\n logout: (reason?: \"inactive\" | \"expired\" | \"manual\") => Promise<void>\n user?: User\n expiresAt?: Date\n logoutReason?: \"inactive\" | \"expired\" | \"manual\"\n showInactivityModal: boolean\n closeInactivityModal: () => void\n redirectAfterModal?: string\n}\n\nconst AuthContext = React.createContext<AuthContext | null>(null)\n\nconst INACTIVITY_TIMEOUT = 60 * 60 * 1000 // 60 minutes\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const router = useRouter()\n const [user, setUser] = React.useState<User | null>(null)\n const [expiresAt, setExpiresAt] = React.useState<Date | undefined>(undefined)\n const [logoutReason, setLogoutReason] = React.useState<\"inactive\" | \"expired\" | \"manual\" | undefined>(undefined)\n const [showInactivityModal, setShowInactivityModal] = useState(false)\n const [redirectAfterModal, setRedirectAfterModal] = useState<string | undefined>(undefined)\n\n const logoutTimerRef = useRef<NodeJS.Timeout | null>(null)\n const inactivityTimerRef = useRef<NodeJS.Timeout | null>(null)\n\n const isAuthenticated = !!user\n\n const clearLogoutTimer = useCallback(() => {\n if (logoutTimerRef.current) {\n clearTimeout(logoutTimerRef.current)\n logoutTimerRef.current = null\n }\n }, [])\n\n const clearInactivityTimer = useCallback(() => {\n if (inactivityTimerRef.current) {\n clearTimeout(inactivityTimerRef.current)\n inactivityTimerRef.current = null\n }\n }, [])\n\n const closeInactivityModal = useCallback(() => {\n setShowInactivityModal(false)\n\n router.navigate({\n to: \"/\",\n search: redirectAfterModal ? { redirect: redirectAfterModal } : undefined,\n })\n }, [redirectAfterModal])\n\n const logout = useCallback(\n async (reason: \"inactive\" | \"expired\" | \"manual\" = \"manual\") => {\n clearLogoutTimer()\n clearInactivityTimer()\n\n setUser(null)\n setExpiresAt(undefined)\n setLogoutReason(reason)\n\n // For inactive/expired: Show modal instead of direct navigation\n if (reason === \"inactive\" || reason === \"expired\") {\n const currentPath = window.location.pathname + window.location.search\n if (currentPath && currentPath.startsWith(\"/\")) {\n setRedirectAfterModal(currentPath)\n }\n\n setShowInactivityModal(true)\n } else {\n // Manual logout: direct navigation\n router.invalidate()\n }\n },\n [clearLogoutTimer, clearInactivityTimer]\n )\n\n const resetInactivityTimer = useCallback(() => {\n if (!isAuthenticated) return\n\n clearInactivityTimer()\n\n inactivityTimerRef.current = setTimeout(() => {\n logout(\"inactive\")\n }, INACTIVITY_TIMEOUT)\n }, [isAuthenticated, clearInactivityTimer, logout])\n\n const login = useCallback(\n async (user: User, expires_at?: string) => {\n setUser(user)\n setLogoutReason(undefined)\n setShowInactivityModal(false)\n setRedirectAfterModal(undefined)\n\n if (expires_at) {\n const expiration = new Date(expires_at)\n setExpiresAt(expiration)\n } else {\n setExpiresAt(undefined)\n }\n\n resetInactivityTimer()\n },\n [resetInactivityTimer]\n )\n\n useEffect(() => {\n clearLogoutTimer()\n\n if (user && expiresAt) {\n const timeUntilExpiry = expiresAt.getTime() - Date.now()\n\n if (timeUntilExpiry <= 0) {\n logout(\"expired\")\n return\n }\n\n logoutTimerRef.current = setTimeout(() => {\n logout(\"expired\")\n }, timeUntilExpiry)\n }\n\n return () => {\n clearLogoutTimer()\n }\n }, [user, expiresAt, logout, clearLogoutTimer])\n\n useEffect(() => {\n if (!isAuthenticated) {\n clearInactivityTimer()\n return\n }\n\n const events = [\"mousedown\", \"mousemove\", \"keypress\", \"scroll\", \"touchstart\", \"click\"]\n\n const handleActivity = () => {\n resetInactivityTimer()\n }\n\n resetInactivityTimer()\n\n events.forEach((event) => {\n document.addEventListener(event, handleActivity, true)\n })\n\n return () => {\n clearInactivityTimer()\n events.forEach((event) => {\n document.removeEventListener(event, handleActivity, true)\n })\n }\n }, [isAuthenticated, resetInactivityTimer, clearInactivityTimer])\n\n return (\n <AuthContext.Provider\n value={{\n isAuthenticated,\n user,\n login,\n logout,\n expiresAt,\n logoutReason,\n showInactivityModal,\n closeInactivityModal,\n redirectAfterModal,\n }}\n >\n {children}\n </AuthContext.Provider>\n )\n}\n\nexport function useAuth() {\n const context = React.useContext(AuthContext)\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\")\n }\n return context\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuthProvider-Co4d0WzB.mjs","names":["React","useEffect","useRef","useCallback","useState","useRouter","AuthContext","createContext","INACTIVITY_TIMEOUT","AuthProvider","children","router","user","setUser","expiresAt","setExpiresAt","undefined","logoutReason","setLogoutReason","showInactivityModal","setShowInactivityModal","redirectAfterModal","setRedirectAfterModal","logoutTimerRef","inactivityTimerRef","isAuthenticated","clearLogoutTimer","current","clearTimeout","clearInactivityTimer","closeInactivityModal","navigate","to","search","redirect","logout","reason","currentPath","window","location","pathname","startsWith","invalidate","resetInactivityTimer","setTimeout","login","expires_at","expiration","Date","timeUntilExpiry","getTime","now","events","handleActivity","forEach","event","document","addEventListener","removeEventListener","Provider","value","useAuth","context","useContext","Error"],"sources":["../../src/client/store/AuthProvider.tsx"],"sourcesContent":["import React, { useEffect, useRef, useCallback, useState } from \"react\"\nimport { TokenData } from \"../../server/Authentication/types/models\"\nimport { useRouter } from \"@tanstack/react-router\"\n\nexport type User = TokenData[\"user\"] | null\n\nexport interface AuthContext {\n isAuthenticated: boolean\n login: (user: User, expires_at?: string) => Promise<void>\n logout: (reason?: \"inactive\" | \"expired\" | \"manual\") => Promise<void>\n user?: User\n expiresAt?: Date\n logoutReason?: \"inactive\" | \"expired\" | \"manual\"\n showInactivityModal: boolean\n closeInactivityModal: () => void\n redirectAfterModal?: string\n}\n\nconst AuthContext = React.createContext<AuthContext | null>(null)\n\nconst INACTIVITY_TIMEOUT = 60 * 60 * 1000 // 60 minutes\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const router = useRouter()\n const [user, setUser] = React.useState<User | null>(null)\n const [expiresAt, setExpiresAt] = React.useState<Date | undefined>(undefined)\n const [logoutReason, setLogoutReason] = React.useState<\"inactive\" | \"expired\" | \"manual\" | undefined>(undefined)\n const [showInactivityModal, setShowInactivityModal] = useState(false)\n const [redirectAfterModal, setRedirectAfterModal] = useState<string | undefined>(undefined)\n\n const logoutTimerRef = useRef<NodeJS.Timeout | null>(null)\n const inactivityTimerRef = useRef<NodeJS.Timeout | null>(null)\n\n const isAuthenticated = !!user\n\n const clearLogoutTimer = useCallback(() => {\n if (logoutTimerRef.current) {\n clearTimeout(logoutTimerRef.current)\n logoutTimerRef.current = null\n }\n }, [])\n\n const clearInactivityTimer = useCallback(() => {\n if (inactivityTimerRef.current) {\n clearTimeout(inactivityTimerRef.current)\n inactivityTimerRef.current = null\n }\n }, [])\n\n const closeInactivityModal = useCallback(() => {\n setShowInactivityModal(false)\n\n router.navigate({\n to: \"/\",\n search: redirectAfterModal ? { redirect: redirectAfterModal } : undefined,\n })\n }, [redirectAfterModal])\n\n const logout = useCallback(\n async (reason: \"inactive\" | \"expired\" | \"manual\" = \"manual\") => {\n clearLogoutTimer()\n clearInactivityTimer()\n\n setUser(null)\n setExpiresAt(undefined)\n setLogoutReason(reason)\n\n // For inactive/expired: Show modal instead of direct navigation\n if (reason === \"inactive\" || reason === \"expired\") {\n const currentPath = window.location.pathname + window.location.search\n if (currentPath && currentPath.startsWith(\"/\")) {\n setRedirectAfterModal(currentPath)\n }\n\n setShowInactivityModal(true)\n } else {\n // Manual logout: direct navigation\n router.invalidate()\n }\n },\n [clearLogoutTimer, clearInactivityTimer]\n )\n\n const resetInactivityTimer = useCallback(() => {\n if (!isAuthenticated) return\n\n clearInactivityTimer()\n\n inactivityTimerRef.current = setTimeout(() => {\n logout(\"inactive\")\n }, INACTIVITY_TIMEOUT)\n }, [isAuthenticated, clearInactivityTimer, logout])\n\n const login = useCallback(\n async (user: User, expires_at?: string) => {\n setUser(user)\n setLogoutReason(undefined)\n setShowInactivityModal(false)\n setRedirectAfterModal(undefined)\n\n if (expires_at) {\n const expiration = new Date(expires_at)\n setExpiresAt(expiration)\n } else {\n setExpiresAt(undefined)\n }\n\n resetInactivityTimer()\n },\n [resetInactivityTimer]\n )\n\n useEffect(() => {\n clearLogoutTimer()\n\n if (user && expiresAt) {\n const timeUntilExpiry = expiresAt.getTime() - Date.now()\n\n if (timeUntilExpiry <= 0) {\n logout(\"expired\")\n return\n }\n\n logoutTimerRef.current = setTimeout(() => {\n logout(\"expired\")\n }, timeUntilExpiry)\n }\n\n return () => {\n clearLogoutTimer()\n }\n }, [user, expiresAt, logout, clearLogoutTimer])\n\n useEffect(() => {\n if (!isAuthenticated) {\n clearInactivityTimer()\n return\n }\n\n const events = [\"mousedown\", \"mousemove\", \"keypress\", \"scroll\", \"touchstart\", \"click\"]\n\n const handleActivity = () => {\n resetInactivityTimer()\n }\n\n resetInactivityTimer()\n\n events.forEach((event) => {\n document.addEventListener(event, handleActivity, true)\n })\n\n return () => {\n clearInactivityTimer()\n events.forEach((event) => {\n document.removeEventListener(event, handleActivity, true)\n })\n }\n }, [isAuthenticated, resetInactivityTimer, clearInactivityTimer])\n\n return (\n <AuthContext.Provider\n value={{\n isAuthenticated,\n user,\n login,\n logout,\n expiresAt,\n logoutReason,\n showInactivityModal,\n closeInactivityModal,\n redirectAfterModal,\n }}\n >\n {children}\n </AuthContext.Provider>\n )\n}\n\nexport function useAuth() {\n const context = React.useContext(AuthContext)\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\")\n }\n return context\n}\n"],"mappings":"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"}
@@ -1,81 +1,81 @@
1
- import { A as e, P as t, Z as n, i as r, j as i, nt as a, rt as o } from "./build-BJDfnAyi.mjs";
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: i, 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();
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(i), v(!0), b(!1), setTimeout(() => v(!1), 2e3);
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 && i.length > f ? `${i.slice(0, f)}...` : i, w = () => _ ? o || h._({ id: "u+VWhB" }) : h._({ id: "he3ygx" }), T = _ && p || y && p;
15
- return /* @__PURE__ */ s("div", {
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
+ return /*#__PURE__*/ s("div", {
16
16
  ...m,
17
17
  className: x,
18
- children: /* @__PURE__ */ c(n, {
18
+ children: /*#__PURE__*/ c(o, {
19
19
  open: T,
20
- children: [/* @__PURE__ */ s(t, {
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: i }
26
+ values: { text: e }
27
27
  }),
28
28
  className: "cursor-pointer",
29
29
  asChild: !0,
30
30
  "data-testid": "clipboard-copy-trigger",
31
- children: /* @__PURE__ */ s("div", {
31
+ children: /*#__PURE__*/ s("div", {
32
32
  className: "group",
33
- children: /* @__PURE__ */ c(a, {
33
+ children: /*#__PURE__*/ c(t, {
34
34
  direction: "horizontal",
35
35
  gap: "1",
36
36
  className: "items-center hover:underline",
37
- children: [/* @__PURE__ */ s("span", {
37
+ children: [/*#__PURE__*/ s("span", {
38
38
  className: "select-none",
39
39
  children: C
40
- }), /* @__PURE__ */ s(r, {
40
+ }), /*#__PURE__*/ s(r, {
41
41
  icon: _ ? "check" : "contentCopy",
42
42
  size: "18"
43
43
  })]
44
44
  })
45
45
  })
46
- }), /* @__PURE__ */ s(e, { children: w() })]
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: e, projectId: t, actions: n }) {
53
- return /* @__PURE__ */ c("header", { children: [
54
- /* @__PURE__ */ c("div", {
52
+ function p({ title: t, projectId: n, actions: r }) {
53
+ return /*#__PURE__*/ c("header", { children: [
54
+ /*#__PURE__*/ c("div", {
55
55
  className: "flex flex-col sm:flex-row sm:items-center sm:justify-between",
56
- children: [/* @__PURE__ */ s(i, { children: e }), /* @__PURE__ */ c("div", {
56
+ children: [/*#__PURE__*/ s(a, { children: t }), /*#__PURE__*/ c("div", {
57
57
  className: "text-theme-light flex items-center gap-1 text-sm",
58
- children: [/* @__PURE__ */ c("span", {
58
+ children: [/*#__PURE__*/ c("span", {
59
59
  className: "font-semibold",
60
60
  children: [
61
- /* @__PURE__ */ s(u, { id: "mSfwLL" }),
61
+ /*#__PURE__*/ s(u, { id: "mSfwLL" }),
62
62
  ":",
63
63
  " "
64
64
  ]
65
- }), /* @__PURE__ */ s(f, {
66
- text: t,
65
+ }), /*#__PURE__*/ s(f, {
66
+ text: n,
67
67
  truncateAt: 15
68
68
  })]
69
69
  })]
70
70
  }),
71
- /* @__PURE__ */ s(o, { className: "mt-4" }),
72
- n && /* @__PURE__ */ s("div", {
73
- className: "mt-2 flex justify-end",
74
- children: n
71
+ /*#__PURE__*/ s(e, { className: "mt-4" }),
72
+ r && /*#__PURE__*/ s("div", {
73
+ className: "mt-3 flex justify-end",
74
+ children: r
75
75
  })
76
76
  ] });
77
77
  }
78
78
  //#endregion
79
- export { p as t };
79
+ export { f as n, p as t };
80
80
 
81
- //# sourceMappingURL=ContentHeader-BXZoN3B9.mjs.map
81
+ //# sourceMappingURL=ContentHeader-kx1Th5Sq.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContentHeader-BXZoN3B9.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-2 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,GAAAA,EACR,CAACC,GAAQC,KAAaf,EAAS,GAAA,EAC/B,CAACgB,GAAYC,KAAiBjB,EAAS,GAAA,EAEvCkB,IAAoB,6CAA6CT,KAAa,MAE9EU,IAAa,OAAOC,MAAAA;AAExBA,EADAA,EAAEC,gBAAc,EAChBD,EAAEE,iBAAe;AAEjB,MAAI;AAIFI,GAHA,MAAMH,UAAUC,UAAUC,UAAUlB,EAAAA,EACpCQ,EAAU,GAAA,EACVE,EAAc,GAAA,EACdS,iBAAiBX,EAAU,GAAA,EAAQ,IAAA;WAC5BY,GAAK;AACZC,WAAQC,MAAM,wBAAwBF,EAAAA;;IAIpCG,IAAcpB,KAAcH,EAAKwB,SAASrB,IAAa,GAAGH,EAAKyB,MAAM,GAAGtB,EAAAA,CAAY,OAAOH,GAG3F0B,UACAnB,IACKN,KAAkB0B,EAAAA,EAAC,EAAA,IAAA,UAAqB,CAAA,GAE1CA,EAAAA,EAAC,EAAA,IAAA,UAAK,CAAA,EAGTC,IAAgB,KAAWxB,KAAiBK,KAAcL;AAEhE,QACE,kBAACyB,OAAAA;EAAK,GAAGxB;EAAOH,WAAWS;YACzB,kBAACjB,GAAAA;GAAQoC,MAAMF;cACb,kBAACjC,GAAAA;IACCoC,SAASnB;IACToB,oBAAoB,CAACzB,KAAUG,EAAc,GAAA;IAC7CuB,oBAAoBvB,EAAc,GAAA;IAClCwB,cAAYP,EAAAA,EAAC;;eAAQ3B,SAAAA;KAAkB,CAAA;IACvCE,WAAU;IACViC,SAAO;IACPC,eAAY;cAEZ,kBAACP,OAAAA;KAAI3B,WAAU;eACb,kBAACJ,GAAAA;MAAMuC,WAAU;MAAaC,KAAI;MAAIpC,WAAU;iBAC9C,kBAACqC,QAAAA;OAAKrC,WAAU;iBAAeqB;UAC/B,kBAAC1B,GAAAA;OAAK2C,MAAMjC,IAAS,UAAU;OAAekC,MAAK;;;;OAIzD,kBAAC7C,GAAAA,EAAAA,UAAgB8B,GAAAA,EAAAA,CAAAA,CAAAA;;;;;;AC5DzB,SAAgBmB,EAAc,EAAEC,UAAOC,cAAWC,cAA6B;AAC7E,QACE,kBAACC,UAAAA,EAAAA,UAAAA;EACC,kBAACC,OAAAA;GAAIC,WAAU;cACb,kBAACR,GAAAA,EAAAA,UAAgBG,GAAAA,CAAAA,EACjB,kBAACI,OAAAA;IAAIC,WAAU;eACb,kBAACC,QAAAA;KAAKD,WAAU;;MACd,kBAAA,GAAA,EAAA,IAAA,UAAA,CAAA;MAAyB;MAAE;;QAE7B,kBAACP,GAAAA;KAAcS,MAAMN;KAAWO,YAAY;;;;EAGhD,kBAACZ,GAAAA,EAAQS,WAAU,QAAA,CAAA;EAClBH,KAAW,kBAACE,OAAAA;GAAIC,WAAU;aAAyBH"}
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"}