@sybilion/uilib 1.2.0 → 1.2.3
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/esm/components/ui/AppHeader/AppHeader.js +3 -3
- package/dist/esm/components/ui/Image/Image.styl.js +1 -1
- package/dist/esm/components/ui/NavUserHeader/NavUserHeader.js +28 -0
- package/dist/esm/components/ui/NavUserHeader/NavUserHeader.styl.js +7 -0
- package/dist/esm/components/ui/Page/AppShell/AppShell.styl.js +1 -1
- package/dist/esm/components/ui/Page/PageScroll/PageScroll.js +4 -4
- package/dist/esm/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.js +9 -9
- package/dist/esm/index.js +2 -1
- package/dist/esm/sybilion-auth/SybilionAuthProvider.js +30 -7
- package/dist/esm/sybilion-auth/exchangeSybilionToken.js +6 -2
- package/dist/esm/types/src/components/ui/AppHeader/AppHeader.d.ts +2 -1
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.d.ts +2 -0
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.types.d.ts +25 -0
- package/dist/esm/types/src/components/ui/NavUserHeader/index.d.ts +2 -0
- package/dist/esm/types/src/components/ui/Page/PageScroll/PageScroll.d.ts +2 -1
- package/dist/esm/types/src/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.d.ts +3 -1
- package/dist/esm/types/src/docs/pages/NavUserHeaderPage.d.ts +1 -0
- package/dist/esm/types/src/docs/pages/StandaloneAppLayoutPage.d.ts +1 -0
- package/dist/esm/types/src/index.d.ts +1 -0
- package/dist/esm/types/src/sybilion-auth/SybilionAuthProvider.d.ts +5 -2
- package/dist/esm/types/src/sybilion-auth/exchangeSybilionToken.d.ts +3 -1
- package/dist/esm/types/src/sybilion-auth/index.d.ts +1 -1
- package/docs/standalone-apps.md +266 -27
- package/package.json +6 -1
- package/src/components/ui/AppHeader/AppHeader.tsx +7 -3
- package/src/components/ui/Image/Image.styl +1 -0
- package/src/components/ui/NavUserHeader/NavUserHeader.styl +125 -0
- package/src/components/ui/NavUserHeader/NavUserHeader.styl.d.ts +28 -0
- package/src/components/ui/NavUserHeader/NavUserHeader.tsx +148 -0
- package/src/components/ui/NavUserHeader/NavUserHeader.types.ts +27 -0
- package/src/components/ui/NavUserHeader/avatar.svg +4 -0
- package/src/components/ui/NavUserHeader/index.ts +5 -0
- package/src/components/ui/Page/AppShell/AppShell.styl +1 -0
- package/src/components/ui/Page/PageScroll/PageScroll.tsx +9 -2
- package/src/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.tsx +9 -0
- package/src/docs/pages/NavUserHeaderPage.tsx +89 -0
- package/src/docs/pages/StandaloneAppLayoutPage.styl +46 -0
- package/src/docs/pages/StandaloneAppLayoutPage.styl.d.ts +8 -0
- package/src/docs/pages/StandaloneAppLayoutPage.tsx +242 -0
- package/src/docs/pages/SybilionAuthProviderPage.tsx +5 -2
- package/src/docs/registry.ts +12 -0
- package/src/index.ts +1 -0
- package/src/sybilion-auth/SybilionAuthProvider.tsx +33 -11
- package/src/sybilion-auth/exchangeSybilionToken.ts +5 -1
- package/src/sybilion-auth/index.ts +1 -0
package/src/docs/registry.ts
CHANGED
|
@@ -66,6 +66,12 @@ export const DOC_REGISTRY: DocEntry[] = [
|
|
|
66
66
|
section: 'Navigation',
|
|
67
67
|
load: () => import('./pages/BreadcrumbPage'),
|
|
68
68
|
},
|
|
69
|
+
{
|
|
70
|
+
slug: 'nav-user-header',
|
|
71
|
+
title: 'NavUserHeader',
|
|
72
|
+
section: 'Navigation',
|
|
73
|
+
load: () => import('./pages/NavUserHeaderPage'),
|
|
74
|
+
},
|
|
69
75
|
{
|
|
70
76
|
slug: 'card',
|
|
71
77
|
title: 'Card',
|
|
@@ -210,6 +216,12 @@ export const DOC_REGISTRY: DocEntry[] = [
|
|
|
210
216
|
section: 'Layout',
|
|
211
217
|
load: () => import('./pages/PagePage'),
|
|
212
218
|
},
|
|
219
|
+
{
|
|
220
|
+
slug: 'standalone-app-layout',
|
|
221
|
+
title: 'Standalone app layout',
|
|
222
|
+
section: 'Layout',
|
|
223
|
+
load: () => import('./pages/StandaloneAppLayoutPage'),
|
|
224
|
+
},
|
|
213
225
|
{
|
|
214
226
|
slug: 'progress',
|
|
215
227
|
title: 'Progress',
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ export * from './components/ui/LabelWithId';
|
|
|
31
31
|
export * from './components/ui/LegacyPlatformLink';
|
|
32
32
|
export * from './components/ui/Logo';
|
|
33
33
|
export * from './components/ui/MobileAdaptiveSelector';
|
|
34
|
+
export * from './components/ui/NavUserHeader';
|
|
34
35
|
export * from './components/ui/NumberControl';
|
|
35
36
|
export * from './components/ui/Page';
|
|
36
37
|
export * from './components/ui/Progress';
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type RedirectLoginOptions,
|
|
4
4
|
useAuth0,
|
|
5
5
|
} from '@auth0/auth0-react';
|
|
6
|
+
import type { LoginTokenResponse, SybilionSDK } from '@sybilion/sdk';
|
|
6
7
|
import type { JSX, ReactNode } from 'react';
|
|
7
8
|
import {
|
|
8
9
|
createContext,
|
|
@@ -15,13 +16,34 @@ import {
|
|
|
15
16
|
} from 'react';
|
|
16
17
|
|
|
17
18
|
import { normalizeApiBaseUrl } from '#uilib/sybilion-auth/authPaths';
|
|
18
|
-
import { exchangeAuth0AccessTokenForSybilionJwt } from '#uilib/sybilion-auth/exchangeSybilionToken';
|
|
19
19
|
|
|
20
20
|
const DEFAULT_TOKEN_KEY = 'sybilion.standalone.jwt';
|
|
21
21
|
|
|
22
|
+
function sybilionJwtFromLoginResponse(body: LoginTokenResponse): string {
|
|
23
|
+
const t = body.data?.token ?? body.token;
|
|
24
|
+
if (!t) throw new Error('Sybilion auth: missing token in login response');
|
|
25
|
+
return t;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Origin (`scheme://host:port`) for paths like `/api/v1/...`; derived from SDK URL layout. */
|
|
29
|
+
export function getSybilionApiOriginFromSdk(sdk: SybilionSDK): string {
|
|
30
|
+
const loginUrl = sdk.http.buildUrl('/v1/auth/login');
|
|
31
|
+
try {
|
|
32
|
+
const baseHref =
|
|
33
|
+
typeof window !== 'undefined' && window.location?.href
|
|
34
|
+
? window.location.href
|
|
35
|
+
: 'http://localhost/';
|
|
36
|
+
const u = new URL(loginUrl, baseHref);
|
|
37
|
+
if (!u.pathname.endsWith('/v1/auth/login')) return '';
|
|
38
|
+
return u.origin;
|
|
39
|
+
} catch {
|
|
40
|
+
return '';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
22
44
|
export type SybilionAuthProviderProps = {
|
|
23
45
|
children: ReactNode;
|
|
24
|
-
|
|
46
|
+
sdk: SybilionSDK;
|
|
25
47
|
auth0Domain: string;
|
|
26
48
|
auth0ClientId: string;
|
|
27
49
|
redirectUri: string;
|
|
@@ -119,12 +141,12 @@ function writeLs(key: string, value: string | null): void {
|
|
|
119
141
|
|
|
120
142
|
function InnerSybilionSession({
|
|
121
143
|
children,
|
|
122
|
-
|
|
144
|
+
sdk,
|
|
123
145
|
storageKey,
|
|
124
146
|
logoutReturnTo,
|
|
125
147
|
}: {
|
|
126
148
|
children: ReactNode;
|
|
127
|
-
|
|
149
|
+
sdk: SybilionSDK;
|
|
128
150
|
storageKey: string;
|
|
129
151
|
logoutReturnTo?: string;
|
|
130
152
|
}): JSX.Element {
|
|
@@ -155,6 +177,8 @@ function InnerSybilionSession({
|
|
|
155
177
|
});
|
|
156
178
|
}, [persistToken, logoutReturnTo]);
|
|
157
179
|
|
|
180
|
+
const apiBaseUrl = useMemo(() => getSybilionApiOriginFromSdk(sdk), [sdk]);
|
|
181
|
+
|
|
158
182
|
useEffect(() => {
|
|
159
183
|
if (!auth0.isAuthenticated || !auth0.user?.sub) {
|
|
160
184
|
persistToken(null);
|
|
@@ -174,10 +198,8 @@ function InnerSybilionSession({
|
|
|
174
198
|
setExchangeError(null);
|
|
175
199
|
try {
|
|
176
200
|
const access = await auth0Ref.current.getAccessTokenSilently();
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
access,
|
|
180
|
-
);
|
|
201
|
+
const loginBody = await sdk.auth.loginWithAuth0Identity(access);
|
|
202
|
+
const jwt = sybilionJwtFromLoginResponse(loginBody);
|
|
181
203
|
if (cancelled) return;
|
|
182
204
|
persistToken(jwt);
|
|
183
205
|
} catch (e) {
|
|
@@ -198,7 +220,7 @@ function InnerSybilionSession({
|
|
|
198
220
|
cancelled = true;
|
|
199
221
|
};
|
|
200
222
|
}, [
|
|
201
|
-
|
|
223
|
+
sdk,
|
|
202
224
|
auth0.isAuthenticated,
|
|
203
225
|
auth0.user?.sub,
|
|
204
226
|
persistToken,
|
|
@@ -270,7 +292,7 @@ function InnerSybilionSession({
|
|
|
270
292
|
|
|
271
293
|
export function SybilionAuthProvider({
|
|
272
294
|
children,
|
|
273
|
-
|
|
295
|
+
sdk,
|
|
274
296
|
auth0Domain,
|
|
275
297
|
auth0ClientId,
|
|
276
298
|
redirectUri,
|
|
@@ -311,7 +333,7 @@ export function SybilionAuthProvider({
|
|
|
311
333
|
{...cookieOpts}
|
|
312
334
|
>
|
|
313
335
|
<InnerSybilionSession
|
|
314
|
-
|
|
336
|
+
sdk={sdk}
|
|
315
337
|
storageKey={sybilionTokenStorageKey}
|
|
316
338
|
logoutReturnTo={logoutReturnTo}
|
|
317
339
|
>
|
|
@@ -3,13 +3,17 @@ import {
|
|
|
3
3
|
normalizeApiBaseUrl,
|
|
4
4
|
} from '#uilib/sybilion-auth/authPaths';
|
|
5
5
|
|
|
6
|
+
/** Default API segment before `/v1/...`; matches {@link createSybilionSDK} default `apiPrefix`. */
|
|
7
|
+
const SYBILION_AUTH_API_PREFIX = '/api';
|
|
8
|
+
|
|
6
9
|
/** POST `{ identity: auth0AccessToken, type: 'auth0' }` → Sybilion API JWT string. */
|
|
7
10
|
export async function exchangeAuth0AccessTokenForSybilionJwt(
|
|
11
|
+
/** API origin only (no trailing slash), same as SDK `baseUrl`. */
|
|
8
12
|
apiBaseUrl: string,
|
|
9
13
|
auth0AccessToken: string,
|
|
10
14
|
): Promise<string> {
|
|
11
15
|
const base = normalizeApiBaseUrl(apiBaseUrl);
|
|
12
|
-
const res = await fetch(`${base}${SYBILION_AUTH_LOGIN_PATH}`, {
|
|
16
|
+
const res = await fetch(`${base}${SYBILION_AUTH_API_PREFIX}${SYBILION_AUTH_LOGIN_PATH}`, {
|
|
13
17
|
method: 'POST',
|
|
14
18
|
headers: {
|
|
15
19
|
Accept: 'application/json',
|