@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.
Files changed (45) hide show
  1. package/dist/esm/components/ui/AppHeader/AppHeader.js +3 -3
  2. package/dist/esm/components/ui/Image/Image.styl.js +1 -1
  3. package/dist/esm/components/ui/NavUserHeader/NavUserHeader.js +28 -0
  4. package/dist/esm/components/ui/NavUserHeader/NavUserHeader.styl.js +7 -0
  5. package/dist/esm/components/ui/Page/AppShell/AppShell.styl.js +1 -1
  6. package/dist/esm/components/ui/Page/PageScroll/PageScroll.js +4 -4
  7. package/dist/esm/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.js +9 -9
  8. package/dist/esm/index.js +2 -1
  9. package/dist/esm/sybilion-auth/SybilionAuthProvider.js +30 -7
  10. package/dist/esm/sybilion-auth/exchangeSybilionToken.js +6 -2
  11. package/dist/esm/types/src/components/ui/AppHeader/AppHeader.d.ts +2 -1
  12. package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.d.ts +2 -0
  13. package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.types.d.ts +25 -0
  14. package/dist/esm/types/src/components/ui/NavUserHeader/index.d.ts +2 -0
  15. package/dist/esm/types/src/components/ui/Page/PageScroll/PageScroll.d.ts +2 -1
  16. package/dist/esm/types/src/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.d.ts +3 -1
  17. package/dist/esm/types/src/docs/pages/NavUserHeaderPage.d.ts +1 -0
  18. package/dist/esm/types/src/docs/pages/StandaloneAppLayoutPage.d.ts +1 -0
  19. package/dist/esm/types/src/index.d.ts +1 -0
  20. package/dist/esm/types/src/sybilion-auth/SybilionAuthProvider.d.ts +5 -2
  21. package/dist/esm/types/src/sybilion-auth/exchangeSybilionToken.d.ts +3 -1
  22. package/dist/esm/types/src/sybilion-auth/index.d.ts +1 -1
  23. package/docs/standalone-apps.md +266 -27
  24. package/package.json +6 -1
  25. package/src/components/ui/AppHeader/AppHeader.tsx +7 -3
  26. package/src/components/ui/Image/Image.styl +1 -0
  27. package/src/components/ui/NavUserHeader/NavUserHeader.styl +125 -0
  28. package/src/components/ui/NavUserHeader/NavUserHeader.styl.d.ts +28 -0
  29. package/src/components/ui/NavUserHeader/NavUserHeader.tsx +148 -0
  30. package/src/components/ui/NavUserHeader/NavUserHeader.types.ts +27 -0
  31. package/src/components/ui/NavUserHeader/avatar.svg +4 -0
  32. package/src/components/ui/NavUserHeader/index.ts +5 -0
  33. package/src/components/ui/Page/AppShell/AppShell.styl +1 -0
  34. package/src/components/ui/Page/PageScroll/PageScroll.tsx +9 -2
  35. package/src/components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.tsx +9 -0
  36. package/src/docs/pages/NavUserHeaderPage.tsx +89 -0
  37. package/src/docs/pages/StandaloneAppLayoutPage.styl +46 -0
  38. package/src/docs/pages/StandaloneAppLayoutPage.styl.d.ts +8 -0
  39. package/src/docs/pages/StandaloneAppLayoutPage.tsx +242 -0
  40. package/src/docs/pages/SybilionAuthProviderPage.tsx +5 -2
  41. package/src/docs/registry.ts +12 -0
  42. package/src/index.ts +1 -0
  43. package/src/sybilion-auth/SybilionAuthProvider.tsx +33 -11
  44. package/src/sybilion-auth/exchangeSybilionToken.ts +5 -1
  45. package/src/sybilion-auth/index.ts +1 -0
@@ -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
- apiBaseUrl: string;
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
- apiBaseUrl,
144
+ sdk,
123
145
  storageKey,
124
146
  logoutReturnTo,
125
147
  }: {
126
148
  children: ReactNode;
127
- apiBaseUrl: string;
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 jwt = await exchangeAuth0AccessTokenForSybilionJwt(
178
- apiBaseUrl,
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
- apiBaseUrl,
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
- apiBaseUrl,
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
- apiBaseUrl={apiBaseUrl}
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',
@@ -4,6 +4,7 @@ export type {
4
4
  } from '#uilib/sybilion-auth/SybilionAuthProvider';
5
5
  export {
6
6
  SybilionAuthProvider,
7
+ getSybilionApiOriginFromSdk,
7
8
  useSybilionAuth,
8
9
  sybilionApiFetch,
9
10
  createSybilionApiFetch,