@cobaltcore-dev/aurora 1.0.0 → 1.1.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/dist/client/App.d.ts +2 -1
- package/dist/client/AuroraApp.d.ts +25 -0
- package/dist/client/{AuthProvider-5TyZKZkx.mjs → AuthProvider-BS5OVv8n.mjs} +2 -2
- package/dist/client/AuthProvider-BS5OVv8n.mjs.map +1 -0
- package/dist/client/{ContentHeader-D64NtKvo.mjs → ContentHeader-BHMUzd9H.mjs} +16 -16
- package/dist/client/{ContentHeader-D64NtKvo.mjs.map → ContentHeader-BHMUzd9H.mjs.map} +1 -1
- package/dist/client/{DeleteFlavorModal-C2K43ABZ.mjs → DeleteFlavorModal-BP83t9zX.mjs} +283 -294
- package/dist/client/DeleteFlavorModal-BP83t9zX.mjs.map +1 -0
- package/dist/client/{FiltersInput-Bw8TFfwb.mjs → FiltersInput-B8CNBg1L.mjs} +23 -23
- package/dist/client/{FiltersInput-Bw8TFfwb.mjs.map → FiltersInput-B8CNBg1L.mjs.map} +1 -1
- package/dist/client/{FloatingIpActionModals-BfEDfYg9.mjs → FloatingIpActionModals-BraiJWBi.mjs} +48 -48
- package/dist/client/{FloatingIpActionModals-BfEDfYg9.mjs.map → FloatingIpActionModals-BraiJWBi.mjs.map} +1 -1
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs +1131 -0
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs.map +1 -0
- package/dist/client/{RouteError-B-NPGIv7.mjs → RouteError-hAF8_jbe.mjs} +2 -2
- package/dist/client/{RouteError-B-NPGIv7.mjs.map → RouteError-hAF8_jbe.mjs.map} +1 -1
- package/dist/client/{SortInput-DysAXpB3.mjs → SortInput-Cqs2poV3.mjs} +7 -7
- package/dist/client/{SortInput-DysAXpB3.mjs.map → SortInput-Cqs2poV3.mjs.map} +1 -1
- package/dist/client/{StatusError-DX-GvLjq.mjs → StatusError-C5KodQOq.mjs} +4 -4
- package/dist/client/{StatusError-DX-GvLjq.mjs.map → StatusError-C5KodQOq.mjs.map} +1 -1
- package/dist/client/{TwoColumnDescriptionList-B3xunXmz.mjs → TwoColumnDescriptionList-DiDx3PnH.mjs} +6 -6
- package/dist/client/{TwoColumnDescriptionList-B3xunXmz.mjs.map → TwoColumnDescriptionList-DiDx3PnH.mjs.map} +1 -1
- package/dist/client/{_auth-R5H2yKFf.mjs → _auth-DJ9wHZaj.mjs} +2 -2
- package/dist/client/{_auth-R5H2yKFf.mjs.map → _auth-DJ9wHZaj.mjs.map} +1 -1
- package/dist/client/{_flavorId-Zj7LNL-R.mjs → _flavorId-BN_qessZ.mjs} +2 -2
- package/dist/client/{_flavorId-Zj7LNL-R.mjs.map → _flavorId-BN_qessZ.mjs.map} +1 -1
- package/dist/client/{_flavorId-Dit5mM8I.mjs → _flavorId-CJjEB_Ao.mjs} +34 -34
- package/dist/client/{_flavorId-Dit5mM8I.mjs.map → _flavorId-CJjEB_Ao.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-DCQQpNO-.mjs → _floatingIpId-CwDGHkWm.mjs} +2 -2
- package/dist/client/{_floatingIpId-DCQQpNO-.mjs.map → _floatingIpId-CwDGHkWm.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-B0MCoqE3.mjs → _floatingIpId-foMIwbE4.mjs} +23 -23
- package/dist/client/{_floatingIpId-B0MCoqE3.mjs.map → _floatingIpId-foMIwbE4.mjs.map} +1 -1
- package/dist/client/_imageId-BtJ7GmYB.mjs +558 -0
- package/dist/client/{_imageId-CZYzBAVx.mjs.map → _imageId-BtJ7GmYB.mjs.map} +1 -1
- package/dist/client/{_projectId-DhSWowQo.mjs → _projectId-BmtCuzJu.mjs} +4 -4
- package/dist/client/{_projectId-DhSWowQo.mjs.map → _projectId-BmtCuzJu.mjs.map} +1 -1
- package/dist/client/_projectId-Byt3GQDW.mjs +99 -0
- package/dist/client/_projectId-Byt3GQDW.mjs.map +1 -0
- package/dist/client/_projectId-NYk1IN_a.mjs +291 -0
- package/dist/client/_projectId-NYk1IN_a.mjs.map +1 -0
- package/dist/client/{_projectId-D2pFfYIs.mjs → _projectId-QueiFczy.mjs} +3 -3
- package/dist/client/{_projectId-D2pFfYIs.mjs.map → _projectId-QueiFczy.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-Mj8NJT2-.mjs → _securityGroupId-BcbkRhsN.mjs} +2 -2
- package/dist/client/{_securityGroupId-Mj8NJT2-.mjs.map → _securityGroupId-BcbkRhsN.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-DZ4D4WwB.mjs → _securityGroupId-pPtJsCoe.mjs} +438 -442
- package/dist/client/{_securityGroupId-DZ4D4WwB.mjs.map → _securityGroupId-pPtJsCoe.mjs.map} +1 -1
- package/dist/client/_storageType-BmqrU06i.mjs +2202 -0
- package/dist/client/_storageType-BmqrU06i.mjs.map +1 -0
- package/dist/client/{about-WLyShNgE.mjs → about-_73VmpTB.mjs} +2 -2
- package/dist/client/{about-WLyShNgE.mjs.map → about-_73VmpTB.mjs.map} +1 -1
- package/dist/client/assets/{objectDownload.worker-BXFQIIU_.js.map → objectDownload.worker-CWWLPDyb.js.map} +1 -1
- package/dist/client/assets/{objectDownload.worker-ECvFtmOF.js.map → objectDownload.worker-kZlQuo3F.js.map} +1 -1
- package/dist/client/{aurora-IMO9HhqJ.mjs → aurora-EbwGRLLf.mjs} +2 -2
- package/dist/client/{aurora-IMO9HhqJ.mjs.map → aurora-EbwGRLLf.mjs.map} +1 -1
- package/dist/client/{build-DnD-T35u.mjs → build-C_4vRMCq.mjs} +2233 -2662
- package/dist/client/{build-DnD-T35u.mjs.map → build-C_4vRMCq.mjs.map} +1 -1
- package/dist/client/{flavors-Cp0LEGOH.mjs → flavors-CiHCYrtZ.mjs} +2 -2
- package/dist/client/{flavors-Cp0LEGOH.mjs.map → flavors-CiHCYrtZ.mjs.map} +1 -1
- package/dist/client/{flavors-CwMbDRHm2.mjs → flavors-DY-bDc8l.mjs} +164 -164
- package/dist/client/flavors-DY-bDc8l.mjs.map +1 -0
- package/dist/client/{floatingips-ICwo-rV_.mjs → floatingips-Ci4jHkaG.mjs} +177 -177
- package/dist/client/{floatingips-ICwo-rV_.mjs.map → floatingips-Ci4jHkaG.mjs.map} +1 -1
- package/dist/client/{hooks-CrriowRk.mjs → hooks-LutR2Yg3.mjs} +2 -2
- package/dist/client/{hooks-CrriowRk.mjs.map → hooks-LutR2Yg3.mjs.map} +1 -1
- package/dist/client/images-91U7tr9Y2.mjs +1976 -0
- package/dist/client/images-91U7tr9Y2.mjs.map +1 -0
- package/dist/client/{images-DWiM_72I.mjs → images-CS4kZQyu.mjs} +2 -2
- package/dist/client/{images-DWiM_72I.mjs.map → images-CS4kZQyu.mjs.map} +1 -1
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.js +444 -586
- package/dist/client/index.js.map +1 -1
- package/dist/client/{md-DNzcRhmz.mjs → md-kvaGCNAK.mjs} +4 -22
- package/dist/client/{md-DNzcRhmz.mjs.map → md-kvaGCNAK.mjs.map} +1 -1
- package/dist/client/{objects-DeK2WD5K.mjs → objects-C3azvW8m.mjs} +2019 -2023
- package/dist/client/{objects-DeK2WD5K.mjs.map → objects-C3azvW8m.mjs.map} +1 -1
- package/dist/client/{objects-DI1-tnKr.mjs → objects-CM265S6b.mjs} +2 -2
- package/dist/client/{objects-DI1-tnKr.mjs.map → objects-CM265S6b.mjs.map} +1 -1
- package/dist/client/{objects-D2MKUCxc.mjs → objects-EE9Cd1wI.mjs} +2 -2
- package/dist/client/{objects-D2MKUCxc.mjs.map → objects-EE9Cd1wI.mjs.map} +1 -1
- package/dist/client/{routeInfo-CdTRlSxv.mjs → routeInfo-DXqB2HCf.mjs} +3 -3
- package/dist/client/routeInfo-DXqB2HCf.mjs.map +1 -0
- package/dist/client/router.d.ts +2 -1
- package/dist/client/{routes-DOJr5onJ.mjs → routes-CBd8CCuM.mjs} +13 -13
- package/dist/client/{routes-DOJr5onJ.mjs.map → routes-CBd8CCuM.mjs.map} +1 -1
- package/dist/client/{routes-B05u5bk4.mjs → routes-CdDm-hhO.mjs} +2 -2
- package/dist/client/{routes-B05u5bk4.mjs.map → routes-CdDm-hhO.mjs.map} +1 -1
- package/dist/client/{securitygroups-Be2Qgmew.mjs → securitygroups-Bd_uV4S9.mjs} +198 -198
- package/dist/client/{securitygroups-Be2Qgmew.mjs.map → securitygroups-Bd_uV4S9.mjs.map} +1 -1
- package/dist/client/{securitygroups-_7SYN2jN.mjs → securitygroups-Byte-iSp.mjs} +2 -2
- package/dist/client/{securitygroups-_7SYN2jN.mjs.map → securitygroups-Byte-iSp.mjs.map} +1 -1
- package/dist/client/services-D1PbooD1.mjs +6 -0
- package/dist/client/services-D1PbooD1.mjs.map +1 -0
- package/dist/client/services-DEMVtFyn.mjs +9 -0
- package/dist/client/services-DEMVtFyn.mjs.map +1 -0
- package/dist/client/trpcClient.d.ts +18 -367
- package/dist/client/{useSecurityGroupPermissions-qPwm4mFt.mjs → useSecurityGroupPermissions-C29mzb3b.mjs} +15 -15
- package/dist/client/{useSecurityGroupPermissions-qPwm4mFt.mjs.map → useSecurityGroupPermissions-C29mzb3b.mjs.map} +1 -1
- package/dist/server/index.d.ts +43 -369
- package/dist/server/index.js +71 -276
- package/package.json +1 -3
- package/dist/client/AuthProvider-5TyZKZkx.mjs.map +0 -1
- package/dist/client/DeleteFlavorModal-C2K43ABZ.mjs.map +0 -1
- package/dist/client/DeletePcaModal-D9v8E0Ki.mjs +0 -92
- package/dist/client/DeletePcaModal-D9v8E0Ki.mjs.map +0 -1
- package/dist/client/DetailsInfo-h7rPJ4Jf.mjs +0 -61
- package/dist/client/DetailsInfo-h7rPJ4Jf.mjs.map +0 -1
- package/dist/client/ImageToastNotifications-C0Tluzq-.mjs +0 -1125
- package/dist/client/ImageToastNotifications-C0Tluzq-.mjs.map +0 -1
- package/dist/client/_imageId-CZYzBAVx.mjs +0 -558
- package/dist/client/_pcaId-CHRRsWmO.mjs +0 -605
- package/dist/client/_pcaId-CHRRsWmO.mjs.map +0 -1
- package/dist/client/_projectId-B8wWSxPu.mjs +0 -98
- package/dist/client/_projectId-B8wWSxPu.mjs.map +0 -1
- package/dist/client/_projectId-C5DUYIjt.mjs +0 -291
- package/dist/client/_projectId-C5DUYIjt.mjs.map +0 -1
- package/dist/client/_storageType-C-9bNkmZ.mjs +0 -2211
- package/dist/client/_storageType-C-9bNkmZ.mjs.map +0 -1
- package/dist/client/flavors-CwMbDRHm2.mjs.map +0 -1
- package/dist/client/images-DOGZmr3D.mjs +0 -1937
- package/dist/client/images-DOGZmr3D.mjs.map +0 -1
- package/dist/client/pca-BokFv4Gz.mjs +0 -239
- package/dist/client/pca-BokFv4Gz.mjs.map +0 -1
- package/dist/client/pca-D5jHAl0b.mjs +0 -26
- package/dist/client/pca-D5jHAl0b.mjs.map +0 -1
- package/dist/client/pcaAccess-Br4kVjLQ.mjs +0 -9
- package/dist/client/pcaAccess-Br4kVjLQ.mjs.map +0 -1
- package/dist/client/routeInfo-CdTRlSxv.mjs.map +0 -1
package/dist/client/App.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Slots, OnTrackEventCallback } from './AuroraApp';
|
|
1
|
+
import { Slots, OnTrackEventCallback, AdditionalProjectService } from './AuroraApp';
|
|
2
2
|
type AppProps = {
|
|
3
3
|
theme?: "theme-dark" | "theme-light";
|
|
4
4
|
bffEndpoint?: string;
|
|
@@ -7,6 +7,7 @@ type AppProps = {
|
|
|
7
7
|
appName?: string;
|
|
8
8
|
onTrackEvent?: OnTrackEventCallback;
|
|
9
9
|
enabledServices?: string[];
|
|
10
|
+
additionalProjectServices?: AdditionalProjectService[];
|
|
10
11
|
};
|
|
11
12
|
declare const App: (props: AppProps) => import("react").JSX.Element;
|
|
12
13
|
export default App;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
+
import { AnyRoute } from '@tanstack/react-router';
|
|
2
3
|
import { TrpcClient } from './trpcClient';
|
|
3
4
|
/** Context object passed to every slot component. */
|
|
4
5
|
export type SlotProps = {
|
|
@@ -47,6 +48,28 @@ export type TrackEventPayload = {
|
|
|
47
48
|
* Use this to send analytics data about feature usage patterns.
|
|
48
49
|
*/
|
|
49
50
|
export type OnTrackEventCallback = (payload: TrackEventPayload) => void;
|
|
51
|
+
/**
|
|
52
|
+
* An additional project-scoped service a consumer wants to register.
|
|
53
|
+
* Aurora checks `serviceIndex[serviceType][serviceName]` against the project's OpenStack catalog.
|
|
54
|
+
* When present, the service appears in the "Services" nav section and its routes are activated
|
|
55
|
+
* under the OSS-owned `/services` layout. Pass the service's entry route (list/overview) as
|
|
56
|
+
* `routes` — wire its full sub-tree via `addChildren` and set `getParentRoute: () => servicesRoute`.
|
|
57
|
+
*/
|
|
58
|
+
export type AdditionalProjectService = {
|
|
59
|
+
/** OpenStack catalog service type, e.g. `"pca"`. */
|
|
60
|
+
serviceType: string;
|
|
61
|
+
/** OpenStack catalog service name, e.g. `"clavis"`. */
|
|
62
|
+
serviceName: string;
|
|
63
|
+
/** Nav item and service card label. */
|
|
64
|
+
label: string;
|
|
65
|
+
/**
|
|
66
|
+
* The pre-assembled entry route for this service (list/overview).
|
|
67
|
+
* Set `getParentRoute: () => servicesRoute` (from `@cobaltcore-dev/aurora/client`) and wire
|
|
68
|
+
* the full sub-tree via `addChildren` before passing here.
|
|
69
|
+
* `routes.fullPath` is used as the nav item navigation target automatically.
|
|
70
|
+
*/
|
|
71
|
+
routes: AnyRoute;
|
|
72
|
+
};
|
|
50
73
|
/** Props for the top-level `<AuroraApp />` component. */
|
|
51
74
|
export type AuroraAppProps = {
|
|
52
75
|
/** Initial theme. Defaults to `"theme-light"`. */
|
|
@@ -82,5 +105,7 @@ export type AuroraAppProps = {
|
|
|
82
105
|
onTrackEvent?: OnTrackEventCallback;
|
|
83
106
|
/** Whitelist of service keys to show in the side nav and project home page. When omitted, all available services are shown. */
|
|
84
107
|
enabledServices?: string[];
|
|
108
|
+
/** Additional project-scoped services to register. Each is activated when its OpenStack service appears in the project catalog. */
|
|
109
|
+
additionalProjectServices?: AdditionalProjectService[];
|
|
85
110
|
};
|
|
86
111
|
export declare const AuroraApp: FC<AuroraAppProps>;
|
|
@@ -14,7 +14,7 @@ function o({ children: n }) {
|
|
|
14
14
|
};
|
|
15
15
|
return r(() => {
|
|
16
16
|
e.auth.getCurrentUserSession.query().then((e) => {
|
|
17
|
-
e && (s(e.user), p(e.expires_at));
|
|
17
|
+
e && (s(e.user), p(e.expires_at ?? null));
|
|
18
18
|
}).catch((e) => {
|
|
19
19
|
d(e instanceof Error ? e.message : "Could not load session");
|
|
20
20
|
}).finally(() => l(!1));
|
|
@@ -66,4 +66,4 @@ function s() {
|
|
|
66
66
|
//#endregion
|
|
67
67
|
export { s as n, o as t };
|
|
68
68
|
|
|
69
|
-
//# sourceMappingURL=AuthProvider-
|
|
69
|
+
//# sourceMappingURL=AuthProvider-BS5OVv8n.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider-BS5OVv8n.mjs","names":["React","useEffect","useState","trpcClient","AuthContext","createContext","AuthProvider","children","user","setUser","isLoading","setIsLoading","error","setError","expiresAt","setExpiresAt","redirectToLogin","saveReturnUrl","window","location","pathname","returnUrl","encodeURIComponent","search","replace","clearLocalSession","auth","getCurrentUserSession","query","then","session","expires_at","catch","err","Error","message","finally","timeUntilExpiry","Date","getTime","now","handleExpiry","timer","setTimeout","clearTimeout","login","domain","password","createUserSession","mutate","domainName","success","logout","terminateUserSession","Provider","value","isAuthenticated","undefined","useAuth","context","useContext"],"sources":["../../src/client/store/AuthProvider.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\"\nimport { TokenData } from \"../../server/Authentication/types/models\"\nimport { trpcClient } from \"../trpcClient\"\n\nexport type User = TokenData[\"user\"] | null\n\nexport interface AuthContext {\n isAuthenticated: boolean\n isLoading: boolean\n error: string | null\n login: (credentials: { domain: string; user: string; password: string }) => Promise<{ success: boolean }>\n logout: () => Promise<void>\n user?: User\n expiresAt?: Date\n}\n\nconst AuthContext = React.createContext<AuthContext | null>(null)\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [expiresAt, setExpiresAt] = useState<string | null>(null)\n\n // Redirect to login, optionally with return URL\n const redirectToLogin = (saveReturnUrl: boolean = false) => {\n if (window.location.pathname !== \"/\") {\n const returnUrl = saveReturnUrl\n ? `/?redirect=${encodeURIComponent(window.location.pathname + window.location.search)}`\n : \"/\"\n window.location.replace(returnUrl)\n }\n }\n\n // Clear local session state\n const clearLocalSession = () => {\n setUser(null)\n setExpiresAt(null)\n }\n\n // Get current session on mount\n useEffect(() => {\n trpcClient.auth.getCurrentUserSession\n .query()\n .then((session) => {\n if (session) {\n setUser(session.user)\n setExpiresAt(session.expires_at ?? null)\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err.message : \"Could not load session\")\n })\n .finally(() => setIsLoading(false))\n }, [])\n\n // Auto-logout when session expires\n useEffect(() => {\n if (!user || !expiresAt) return\n\n const timeUntilExpiry = new Date(expiresAt).getTime() - Date.now()\n\n const handleExpiry = () => {\n clearLocalSession()\n redirectToLogin(true)\n }\n\n if (timeUntilExpiry <= 0) {\n handleExpiry()\n return\n }\n\n const timer = setTimeout(handleExpiry, timeUntilExpiry)\n return () => clearTimeout(timer)\n }, [user, expiresAt])\n\n const login = async ({ domain, user, password }: { domain: string; user: string; password: string }) => {\n setError(null)\n setIsLoading(true)\n try {\n const session = await trpcClient.auth.createUserSession.mutate({ domainName: domain, user, password })\n setUser(session.user)\n setExpiresAt(session.expires_at)\n return { success: true }\n } catch (err) {\n setError(err instanceof Error ? err.message : `Could not create session: ${err}`)\n return { success: false }\n } finally {\n setIsLoading(false)\n }\n }\n\n const logout = async () => {\n setIsLoading(true)\n await trpcClient.auth.terminateUserSession.mutate().catch(() => {})\n clearLocalSession()\n redirectToLogin(false) // Don't save return URL on manual logout\n // If already on login page, no redirect happens - reset loading state\n if (window.location.pathname === \"/\") {\n setIsLoading(false)\n }\n }\n\n return (\n <AuthContext.Provider\n value={{\n user,\n isAuthenticated: !!user,\n isLoading,\n error,\n login,\n logout,\n expiresAt: expiresAt ? new Date(expiresAt) : undefined,\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":";;;;AAgBA,IAAMI,IAAcJ,gBAAMK,cAAkC,IAAA;AAE5D,SAAgBC,EAAa,EAAEC,eAAyC;CACtE,IAAM,CAACC,GAAMC,KAAWP,EAAsB,IAAA,GACxC,CAACQ,GAAWC,KAAgBT,EAAS,EAAA,GACrC,CAACU,GAAOC,KAAYX,EAAwB,IAAA,GAC5C,CAACY,GAAWC,KAAgBb,EAAwB,IAAA,GAGpDc,KAAmBC,IAAyB,OAAK;EACrD,IAAIC,OAAOC,SAASC,aAAa,KAAK;GACpC,IAAMC,IAAYJ,IACd,cAAcK,mBAAmBJ,OAAOC,SAASC,WAAWF,OAAOC,SAASI,MAAM,MAClF;GACJL,OAAOC,SAASK,QAAQH,CAAAA;EAC1B;CACF,GAGMI,UAAoB;EAExBV,AADAN,EAAQ,IAAA,GACRM,EAAa,IAAA;CACf;CAiEA,OA9DAd,QAAU;EACRE,EAAWuB,KAAKC,sBACbC,MAAK,CAAA,CACLC,MAAMC,MAAAA;GACL,AAAIA,MACFrB,EAAQqB,EAAQtB,IAAI,GACpBO,EAAae,EAAQC,cAAc,IAAA;EAEvC,CAAA,CAAA,CACCC,OAAOC,MAAAA;GACNpB,EAASoB,aAAeC,QAAQD,EAAIE,UAAU,wBAAA;EAChD,CAAA,CAAA,CACCC,cAAczB,EAAa,EAAA,CAAA;CAChC,GAAG,CAAA,CAAE,GAGLV,QAAU;EACR,IAAI,CAACO,KAAQ,CAACM,GAAW;EAEzB,IAAMuB,IAAkB,IAAIC,KAAKxB,CAAAA,CAAAA,CAAWyB,QAAO,IAAKD,KAAKE,IAAG,GAE1DC,UAAe;GAEnBzB,AADAS,EAAAA,GACAT,EAAgB,EAAA;EAClB;EAEA,IAAIqB,KAAmB,GAAG;GACxBI,EAAAA;GACA;EACF;EAEA,IAAMC,IAAQC,WAAWF,GAAcJ,CAAAA;EACvC,aAAaO,aAAaF,CAAAA;CAC5B,GAAG,CAAClC,GAAMM,CAAU,CAAA,GA8BlB,gBAACV,EAAYkD,UAAQ;EACnBC,OAAO;GACL/C;GACAgD,iBAAiB,CAAC,CAAChD;GACnBE;GACAE;GACAiC,cAlCe,EAAEC,WAAQtC,SAAMuC,kBAA8D;IAEjGpC,AADAE,EAAS,IAAA,GACTF,EAAa,EAAA;IACb,IAAI;KACF,IAAMmB,IAAU,MAAM3B,EAAWuB,KAAKsB,kBAAkBC,OAAO;MAAEC,YAAYJ;MAAQtC;MAAMuC;KAAS,CAAA;KAGpG,OAFAtC,EAAQqB,EAAQtB,IAAI,GACpBO,EAAae,EAAQC,UAAU,GACxB,EAAEoB,SAAS,GAAK;IACzB,SAASlB,GAAK;KAEZ,OADApB,EAASoB,aAAeC,QAAQD,EAAIE,UAAU,6BAA6BF,GAAK,GACzE,EAAEkB,SAAS,GAAM;IAC1B,UAAU;KACRxC,EAAa,EAAA;IACf;GACF;GAqBMyC,oBAnBS;IAMb,AALAzC,EAAa,EAAA,GACb,MAAMR,EAAWuB,KAAK2B,qBAAqBJ,OAAM,CAAA,CAAGjB,YAAM,CAAO,CAAA,GACjEP,EAAAA,GACAT,EAAgB,EAAA,GAEZE,OAAOC,SAASC,aAAa,OAC/BT,EAAa,EAAA;GAEjB;GAWMG,WAAWA,IAAY,IAAIwB,KAAKxB,CAAAA,IAAa2C,KAAAA;EAC/C;EAEClD;;AAGP;AAEA,SAAgBmD,IAAAA;CACd,IAAMC,IAAU3D,EAAM4D,WAAWxD,CAAAA;CACjC,IAAI,CAACuD,GACH,MAAUzB,MAAM,6CAAA;CAElB,OAAOyB;AACT"}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as e, B as t, X as n, Y as r, _ as i, d as a, nt as o } from "./build-C_4vRMCq.mjs";
|
|
2
2
|
import { t as s } from "./Slot-CWb612-_.mjs";
|
|
3
|
-
import { t as c } from "./routeInfo-
|
|
3
|
+
import { t as c } from "./routeInfo-DXqB2HCf.mjs";
|
|
4
4
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
5
|
import { useState as d } from "react";
|
|
6
6
|
import { useMatches as f, useParams as p, useRouteContext as m } from "@tanstack/react-router";
|
|
7
7
|
import { Trans as h, useLingui as g } from "@lingui/react";
|
|
8
8
|
//#region src/client/components/ClipboardText.tsx
|
|
9
|
-
var _ = ({ text:
|
|
9
|
+
var _ = ({ text: i, tooltipContent: o, className: s, truncateAt: c, showTooltip: f = !0, ...p }) => {
|
|
10
10
|
let { i18n: m, _: h } = g(), [_, v] = d(!1), [y, b] = d(!1), x = `copyableTooltip inline-flex items-center ${s || ""}`, S = async (e) => {
|
|
11
11
|
e.preventDefault(), e.stopPropagation();
|
|
12
12
|
try {
|
|
13
|
-
await navigator.clipboard.writeText(
|
|
13
|
+
await navigator.clipboard.writeText(i), v(!0), b(!1), setTimeout(() => v(!1), 2e3);
|
|
14
14
|
} catch (e) {
|
|
15
15
|
console.error("Failed to copy text:", e);
|
|
16
16
|
}
|
|
17
|
-
}, C = c &&
|
|
17
|
+
}, C = c && i.length > c ? `${i.slice(0, c)}...` : i, w = () => _ ? o || m._({ id: "u+VWhB" }) : m._({ id: "he3ygx" }), T = _ && f || y && f;
|
|
18
18
|
return /*#__PURE__*/ l("div", {
|
|
19
19
|
...p,
|
|
20
20
|
className: x,
|
|
21
|
-
children: /*#__PURE__*/ u(
|
|
21
|
+
children: /*#__PURE__*/ u(r, {
|
|
22
22
|
open: T,
|
|
23
|
-
children: [/*#__PURE__*/ l(
|
|
23
|
+
children: [/*#__PURE__*/ l(e, {
|
|
24
24
|
onClick: S,
|
|
25
25
|
onMouseEnter: () => !_ && b(!0),
|
|
26
26
|
onMouseLeave: () => b(!1),
|
|
27
27
|
"aria-label": m._({
|
|
28
28
|
id: "Wbg1jv",
|
|
29
|
-
values: { text:
|
|
29
|
+
values: { text: i }
|
|
30
30
|
}),
|
|
31
31
|
className: "cursor-pointer",
|
|
32
32
|
asChild: !0,
|
|
@@ -41,19 +41,19 @@ var _ = ({ text: a, tooltipContent: o, className: s, truncateAt: c, showTooltip:
|
|
|
41
41
|
children: [/*#__PURE__*/ l("span", {
|
|
42
42
|
className: "select-none",
|
|
43
43
|
children: C
|
|
44
|
-
}), /*#__PURE__*/ l(
|
|
44
|
+
}), /*#__PURE__*/ l(a, {
|
|
45
45
|
icon: _ ? "check" : "contentCopy",
|
|
46
46
|
size: "18"
|
|
47
47
|
})]
|
|
48
48
|
})
|
|
49
49
|
})
|
|
50
|
-
}), /*#__PURE__*/ l(
|
|
50
|
+
}), /*#__PURE__*/ l(t, { children: w() })]
|
|
51
51
|
})
|
|
52
52
|
});
|
|
53
53
|
};
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/client/components/ContentHeader/ContentHeader.tsx
|
|
56
|
-
function v({ title: e, projectId: t, description: n, actions: r, badges:
|
|
56
|
+
function v({ title: e, projectId: t, description: n, actions: r, badges: a }) {
|
|
57
57
|
let { slots: d } = m({ strict: !1 }), g = f(), { provider: v } = p({ strict: !1 }), y = [...g].reverse().find((e) => c(e.staticData)), b = y && c(y.staticData) ? y.staticData.service : void 0, x = b === "containers" && v === "ceph" ? "ceph-containers" : b, S = d?.servicePageActions && x ? /*#__PURE__*/ l(s, {
|
|
58
58
|
component: d.servicePageActions,
|
|
59
59
|
useShadowDOM: !1,
|
|
@@ -73,7 +73,7 @@ function v({ title: e, projectId: t, description: n, actions: r, badges: i }) {
|
|
|
73
73
|
className: "flex flex-col sm:flex-row sm:items-center sm:justify-between",
|
|
74
74
|
children: [/*#__PURE__*/ u("div", {
|
|
75
75
|
className: "flex items-center gap-3",
|
|
76
|
-
children: [/*#__PURE__*/ l(
|
|
76
|
+
children: [/*#__PURE__*/ l(o, { children: e }), S]
|
|
77
77
|
}), /*#__PURE__*/ u("div", {
|
|
78
78
|
className: "text-theme-light flex shrink-0 items-center gap-1 text-sm",
|
|
79
79
|
children: [/*#__PURE__*/ u("span", {
|
|
@@ -95,12 +95,12 @@ function v({ title: e, projectId: t, description: n, actions: r, badges: i }) {
|
|
|
95
95
|
}),
|
|
96
96
|
C,
|
|
97
97
|
w,
|
|
98
|
-
/*#__PURE__*/ l(
|
|
99
|
-
(
|
|
98
|
+
/*#__PURE__*/ l(i, { className: "mt-4" }),
|
|
99
|
+
(a || r) && /*#__PURE__*/ u("div", {
|
|
100
100
|
className: "mt-3 flex items-start justify-between",
|
|
101
101
|
children: [/*#__PURE__*/ u("div", {
|
|
102
102
|
className: "flex items-center gap-2",
|
|
103
|
-
children: [
|
|
103
|
+
children: [a, " "]
|
|
104
104
|
}), r && /*#__PURE__*/ l("div", {
|
|
105
105
|
className: "flex gap-2",
|
|
106
106
|
children: r
|
|
@@ -112,4 +112,4 @@ function v({ title: e, projectId: t, description: n, actions: r, badges: i }) {
|
|
|
112
112
|
//#endregion
|
|
113
113
|
export { _ as n, v as t };
|
|
114
114
|
|
|
115
|
-
//# sourceMappingURL=ContentHeader-
|
|
115
|
+
//# sourceMappingURL=ContentHeader-BHMUzd9H.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentHeader-
|
|
1
|
+
{"version":3,"file":"ContentHeader-BHMUzd9H.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","button","type","direction","gap","span","icon","size","Divider","ContentHeading","useRouteContext","useMatches","useParams","ClipboardText","Slot","isRouteInfo","ContentHeader","title","projectId","description","actions","badges","slots","strict","matches","provider","activeMatch","reverse","find","m","staticData","routeService","service","undefined","currentService","slotActions","servicePageActions","component","useShadowDOM","serviceBanner","projectOverviewBanner","header","className","div","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 <button type=\"button\" className=\"group border-none bg-transparent p-0 text-inherit\">\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 </button>\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 { useRouteContext, useMatches, useParams } from \"@tanstack/react-router\"\nimport ClipboardText from \"../ClipboardText\"\nimport { Slot } from \"../Slot\"\nimport { isRouteInfo } from \"@/client/routes/routeInfo\"\n\ninterface ContentHeaderProps {\n title: string\n projectId: string\n description?: string | null\n actions?: ReactNode\n badges?: ReactNode\n}\n\nexport function ContentHeader({ title, projectId, description, actions, badges }: ContentHeaderProps) {\n const { slots } = useRouteContext({ strict: false })\n const matches = useMatches()\n const { provider } = useParams({ strict: false }) as { provider?: string }\n\n const activeMatch = [...matches].reverse().find((m) => isRouteInfo(m.staticData))\n const routeService = activeMatch && isRouteInfo(activeMatch.staticData) ? activeMatch.staticData.service : undefined\n\n // Storage routes share service: \"containers\" for both Swift and Ceph.\n // Distinguish them by the $provider param.\n const currentService = routeService === \"containers\" && provider === \"ceph\" ? \"ceph-containers\" : routeService\n\n const slotActions =\n slots?.servicePageActions && currentService ? (\n <Slot component={slots.servicePageActions} useShadowDOM={false} currentService={currentService} />\n ) : null\n\n const serviceBanner =\n slots?.serviceBanner && currentService ? (\n <Slot component={slots.serviceBanner} useShadowDOM={false} currentService={currentService} />\n ) : null\n\n const projectOverviewBanner =\n slots?.projectOverviewBanner && !currentService ? (\n <Slot component={slots.projectOverviewBanner} useShadowDOM={false} />\n ) : null\n\n return (\n <header className=\"mb-8\">\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3\">\n <ContentHeading>{title}</ContentHeading>\n {slotActions}\n </div>\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 {serviceBanner}\n {projectOverviewBanner}\n <Divider className=\"mt-4\" />\n {(badges || actions) && (\n <div className=\"mt-3 flex items-start justify-between\">\n <div className=\"flex items-center gap-2\">{badges} </div>\n {actions && <div className=\"flex gap-2\">{actions}</div>}\n </div>\n )}\n </header>\n )\n}\n"],"mappings":"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"}
|