@shellui/core 0.2.0 → 0.3.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -4
- package/src/app.tsx +12 -9
- package/src/components/ui/badge.tsx +35 -0
- package/src/components/ui/dropdown-menu.tsx +94 -0
- package/src/components/ui/sidebar.tsx +1 -1
- package/src/constants/urls.ts +8 -0
- package/src/features/admin/AdminView.tsx +154 -0
- package/src/features/admin/components/AdminForbiddenAccess.tsx +10 -0
- package/src/features/auth/AuthProvider.tsx +464 -0
- package/src/features/auth/backends/index.ts +41 -0
- package/src/features/auth/backends/shellui.ts +278 -0
- package/src/features/auth/backends/supabase.ts +300 -0
- package/src/features/auth/backends/types.ts +30 -0
- package/src/features/auth/components/LoginButton.tsx +360 -0
- package/src/features/auth/components/LoginButtonIcons.tsx +48 -0
- package/src/features/auth/components/LoginView.tsx +721 -0
- package/src/features/auth/components/OAuthCallbackView.tsx +119 -0
- package/src/features/auth/hooks/useAuth.tsx +37 -0
- package/src/features/auth/types.ts +51 -0
- package/src/features/auth/utils/buildSessionFromParams.spec.ts +61 -0
- package/src/features/auth/utils/buildSessionFromParams.ts +79 -0
- package/src/features/auth/utils/clearStoredAuthSession.spec.ts +23 -0
- package/src/features/auth/utils/clearStoredAuthSession.ts +10 -0
- package/src/features/auth/utils/clientLoginContext.spec.ts +83 -0
- package/src/features/auth/utils/clientLoginContext.ts +89 -0
- package/src/features/auth/utils/decodeJwtPayload.spec.ts +17 -0
- package/src/features/auth/utils/decodeJwtPayload.ts +24 -0
- package/src/features/auth/utils/formatProviderLabel.spec.ts +19 -0
- package/src/features/auth/utils/formatProviderLabel.ts +11 -0
- package/src/features/auth/utils/getOAuthProviderCandidates.spec.ts +16 -0
- package/src/features/auth/utils/getOAuthProviderCandidates.ts +15 -0
- package/src/features/auth/utils/getPreferredBackendProvider.spec.ts +15 -0
- package/src/features/auth/utils/getPreferredBackendProvider.ts +10 -0
- package/src/features/auth/utils/getProviderVisual.spec.ts +30 -0
- package/src/features/auth/utils/getProviderVisual.ts +83 -0
- package/src/features/auth/utils/getUserFromSdkSettings.spec.ts +32 -0
- package/src/features/auth/utils/getUserFromSdkSettings.ts +13 -0
- package/src/features/auth/utils/index.ts +21 -0
- package/src/features/auth/utils/isLoginMethod.spec.ts +18 -0
- package/src/features/auth/utils/isLoginMethod.ts +5 -0
- package/src/features/auth/utils/isSessionExpired.spec.ts +23 -0
- package/src/features/auth/utils/isSessionExpired.ts +5 -0
- package/src/features/auth/utils/normalizeAuthSettings.spec.ts +60 -0
- package/src/features/auth/utils/normalizeAuthSettings.ts +71 -0
- package/src/features/auth/utils/normalizeNextPath.spec.ts +21 -0
- package/src/features/auth/utils/normalizeNextPath.ts +12 -0
- package/src/features/auth/utils/normalizeRedirectPath.spec.ts +12 -0
- package/src/features/auth/utils/normalizeRedirectPath.ts +3 -0
- package/src/features/auth/utils/persistAuthSession.spec.ts +35 -0
- package/src/features/auth/utils/persistAuthSession.ts +12 -0
- package/src/features/auth/utils/readStoredAuthSession.spec.ts +34 -0
- package/src/features/auth/utils/readStoredAuthSession.ts +14 -0
- package/src/features/auth/utils/toAuthSessionFromSettingsUser.spec.ts +76 -0
- package/src/features/auth/utils/toAuthSessionFromSettingsUser.ts +36 -0
- package/src/features/config/types.ts +55 -0
- package/src/features/layouts/AppLayout.tsx +8 -6
- package/src/features/layouts/appbar/AppBarLayout.tsx +42 -23
- package/src/features/layouts/fullscreen/FullscreenLayout.tsx +3 -2
- package/src/features/layouts/sidebar/SidebarInner.tsx +7 -5
- package/src/features/layouts/sidebar/SidebarLayout.tsx +16 -3
- package/src/features/layouts/utils.ts +54 -0
- package/src/features/layouts/windows/WindowsLayout.tsx +22 -4
- package/src/features/legal/LegalDocumentContent.tsx +102 -0
- package/src/features/legal/LegalDocumentView.tsx +42 -0
- package/src/features/legal/LegalDocumentsIndexView.tsx +51 -0
- package/src/features/legal/LegalDocumentsLinks.tsx +29 -0
- package/src/features/legal/legalDocuments.ts +62 -0
- package/src/features/settings/SettingsIcons.tsx +20 -0
- package/src/features/settings/SettingsProvider.tsx +347 -245
- package/src/features/settings/SettingsRoutes.tsx +8 -0
- package/src/features/settings/SettingsView.tsx +43 -8
- package/src/features/settings/components/Develop.tsx +2 -2
- package/src/features/settings/components/LegalDocumentsPanel.tsx +46 -0
- package/src/features/settings/components/UserIcon.tsx +20 -0
- package/src/features/settings/components/UserSettingsPanel.tsx +438 -0
- package/src/features/settings/components/createUserSettingsRoute.tsx +43 -0
- package/src/features/settings/utils/buildSettingsForPropagation.spec.ts +167 -0
- package/src/features/settings/utils/buildSettingsForPropagation.ts +61 -0
- package/src/features/settings/utils/flattenNavigationItems.spec.ts +17 -0
- package/src/features/settings/utils/flattenNavigationItems.ts +12 -0
- package/src/features/settings/utils/getAvailableThemesForSettings.spec.ts +15 -0
- package/src/features/settings/utils/getAvailableThemesForSettings.ts +16 -0
- package/src/features/settings/utils/getBrowserTimezone.spec.ts +11 -0
- package/src/features/settings/utils/getBrowserTimezone.ts +7 -0
- package/src/features/settings/utils/getPreferenceSnapshot.spec.ts +35 -0
- package/src/features/settings/utils/getPreferenceSnapshot.ts +10 -0
- package/src/features/settings/utils/getResolvedAppearanceForSettings.spec.ts +97 -0
- package/src/features/settings/utils/getResolvedAppearanceForSettings.ts +48 -0
- package/src/features/settings/utils/index.ts +12 -0
- package/src/features/settings/utils/isSameUser.spec.ts +35 -0
- package/src/features/settings/utils/isSameUser.ts +17 -0
- package/src/features/settings/utils/mergePreferencesIntoSettings.spec.ts +108 -0
- package/src/features/settings/utils/mergePreferencesIntoSettings.ts +47 -0
- package/src/features/settings/utils/resolveColorMode.spec.ts +29 -0
- package/src/features/settings/utils/resolveColorMode.ts +6 -0
- package/src/features/settings/utils/resolveLabel.spec.ts +17 -0
- package/src/features/settings/utils/resolveLabel.ts +7 -0
- package/src/features/settings/utils/toAbsoluteFontUrls.spec.ts +26 -0
- package/src/features/settings/utils/toAbsoluteFontUrls.ts +15 -0
- package/src/features/settings/utils/toSettingsUser.spec.ts +49 -0
- package/src/features/settings/utils/toSettingsUser.ts +15 -0
- package/src/i18n/translations/en/common.json +14 -0
- package/src/i18n/translations/en/settings.json +45 -0
- package/src/i18n/translations/fr/common.json +14 -0
- package/src/i18n/translations/fr/settings.json +45 -0
- package/src/index.css +37 -0
- package/src/index.ts +6 -0
- package/src/routes/components/NavigationItemRoute.tsx +32 -1
- package/src/routes/components/NotFoundView.tsx +13 -3
- package/src/routes/hooks/useNavigationItems.ts +19 -4
- package/src/routes/routes.tsx +87 -0
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { useConfig } from '../../features/config/useConfig';
|
|
3
|
+
import { useAuth } from '../../features/auth/hooks/useAuth';
|
|
3
4
|
import {
|
|
5
|
+
filterNavigationForAuthState,
|
|
4
6
|
flattenNavigationItems,
|
|
5
7
|
getBaseUrlWithoutHash,
|
|
6
8
|
getHashPathFromUrl,
|
|
7
9
|
getNavPathPrefix,
|
|
8
10
|
isHashRouterNavItem,
|
|
9
11
|
} from '../../features/layouts/utils';
|
|
12
|
+
import { useSettings } from '../../features/settings/hooks/useSettings';
|
|
10
13
|
import { useLocation } from 'react-router';
|
|
11
14
|
|
|
12
15
|
export function useNavigationItems() {
|
|
13
16
|
const { config } = useConfig();
|
|
17
|
+
const { isAuthenticated } = useAuth();
|
|
18
|
+
const { settings } = useSettings();
|
|
14
19
|
const location = useLocation();
|
|
15
20
|
|
|
16
21
|
const navigationItems = useMemo(() => {
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
const authAndDevFilteredNavigation = filterNavigationForAuthState(
|
|
23
|
+
config?.navigation ?? [],
|
|
24
|
+
isAuthenticated,
|
|
25
|
+
settings.developerFeatures.enabled,
|
|
26
|
+
);
|
|
27
|
+
return flattenNavigationItems(authAndDevFilteredNavigation);
|
|
28
|
+
}, [config?.navigation, isAuthenticated, settings.developerFeatures.enabled]);
|
|
19
29
|
|
|
20
30
|
const navigationItem = useMemo(() => {
|
|
21
31
|
return navigationItems.find((item) => {
|
|
@@ -29,6 +39,10 @@ export function useNavigationItems() {
|
|
|
29
39
|
() => navigationItems.find((item) => item.path === '' || item.path === '/'),
|
|
30
40
|
[navigationItems],
|
|
31
41
|
);
|
|
42
|
+
const isRootFallback = useMemo(
|
|
43
|
+
() => !navigationItem && Boolean(rootItem) && location.pathname !== '/',
|
|
44
|
+
[navigationItem, rootItem, location.pathname],
|
|
45
|
+
);
|
|
32
46
|
|
|
33
47
|
/**
|
|
34
48
|
* Constructs the final URL for the iframe based on the navigation item and the pathname.
|
|
@@ -39,7 +53,7 @@ export function useNavigationItems() {
|
|
|
39
53
|
const url = useMemo(() => {
|
|
40
54
|
const pathname = location.pathname;
|
|
41
55
|
|
|
42
|
-
const useRootFallback =
|
|
56
|
+
const useRootFallback = isRootFallback;
|
|
43
57
|
const actualNavItem = navigationItem ?? (useRootFallback ? rootItem : null);
|
|
44
58
|
|
|
45
59
|
if (!actualNavItem) {
|
|
@@ -72,7 +86,7 @@ export function useNavigationItems() {
|
|
|
72
86
|
}
|
|
73
87
|
}
|
|
74
88
|
return finalUrl;
|
|
75
|
-
}, [navigationItem, rootItem, location.pathname]);
|
|
89
|
+
}, [navigationItem, rootItem, location.pathname, isRootFallback]);
|
|
76
90
|
|
|
77
91
|
return {
|
|
78
92
|
url: url,
|
|
@@ -80,5 +94,6 @@ export function useNavigationItems() {
|
|
|
80
94
|
currentItem: navigationItem || rootItem,
|
|
81
95
|
navigationItem: navigationItem || rootItem,
|
|
82
96
|
navigationItems: navigationItems,
|
|
97
|
+
isRootFallback,
|
|
83
98
|
};
|
|
84
99
|
}
|
package/src/routes/routes.tsx
CHANGED
|
@@ -16,6 +16,25 @@ const CookiePreferencesView = lazy(() =>
|
|
|
16
16
|
default: m.CookiePreferencesView,
|
|
17
17
|
})),
|
|
18
18
|
);
|
|
19
|
+
const LoginView = lazy(() =>
|
|
20
|
+
import('../features/auth/components/LoginView').then((m) => ({ default: m.LoginView })),
|
|
21
|
+
);
|
|
22
|
+
const OAuthCallbackView = lazy(() =>
|
|
23
|
+
import('../features/auth/components/OAuthCallbackView').then((m) => ({
|
|
24
|
+
default: m.OAuthCallbackView,
|
|
25
|
+
})),
|
|
26
|
+
);
|
|
27
|
+
const AdminView = lazy(() =>
|
|
28
|
+
import('../features/admin/AdminView').then((m) => ({ default: m.AdminView })),
|
|
29
|
+
);
|
|
30
|
+
const LegalDocumentView = lazy(() =>
|
|
31
|
+
import('../features/legal/LegalDocumentView').then((m) => ({ default: m.LegalDocumentView })),
|
|
32
|
+
);
|
|
33
|
+
const LegalDocumentsIndexView = lazy(() =>
|
|
34
|
+
import('../features/legal/LegalDocumentsIndexView').then((m) => ({
|
|
35
|
+
default: m.LegalDocumentsIndexView,
|
|
36
|
+
})),
|
|
37
|
+
);
|
|
19
38
|
const NavigationItemRoute = lazy(() =>
|
|
20
39
|
import('./components/NavigationItemRoute').then((m) => ({ default: m.NavigationItemRoute })),
|
|
21
40
|
);
|
|
@@ -27,6 +46,11 @@ const NotFoundView = lazy(() =>
|
|
|
27
46
|
);
|
|
28
47
|
|
|
29
48
|
export const createRoutes = (config: ShellUIConfig): RouteObject[] => {
|
|
49
|
+
const configuredAdminPathname = config.backend?.adminPathname?.trim();
|
|
50
|
+
const adminPath =
|
|
51
|
+
configuredAdminPathname && configuredAdminPathname.startsWith('/')
|
|
52
|
+
? configuredAdminPathname
|
|
53
|
+
: urls.admin;
|
|
30
54
|
const routes: RouteObject[] = [
|
|
31
55
|
{
|
|
32
56
|
path: '/',
|
|
@@ -51,6 +75,69 @@ export const createRoutes = (config: ShellUIConfig): RouteObject[] => {
|
|
|
51
75
|
</Suspense>
|
|
52
76
|
),
|
|
53
77
|
},
|
|
78
|
+
{
|
|
79
|
+
// Login route
|
|
80
|
+
path: urls.login.replace(/^\//, ''),
|
|
81
|
+
element: (
|
|
82
|
+
<Suspense fallback={<RouteFallback />}>
|
|
83
|
+
<LoginView />
|
|
84
|
+
</Suspense>
|
|
85
|
+
),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
// OAuth callback route (frontend receives code, then exchanges via backend).
|
|
89
|
+
path: urls.loginCallback.replace(/^\//, ''),
|
|
90
|
+
element: (
|
|
91
|
+
<Suspense fallback={<RouteFallback />}>
|
|
92
|
+
<OAuthCallbackView />
|
|
93
|
+
</Suspense>
|
|
94
|
+
),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
path: urls.legalDocuments.replace(/^\//, ''),
|
|
98
|
+
element: (
|
|
99
|
+
<Suspense fallback={<RouteFallback />}>
|
|
100
|
+
<LegalDocumentsIndexView />
|
|
101
|
+
</Suspense>
|
|
102
|
+
),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
path: urls.legalPrivacyPolicy.replace(/^\//, ''),
|
|
106
|
+
element: (
|
|
107
|
+
<Suspense fallback={<RouteFallback />}>
|
|
108
|
+
<LegalDocumentView />
|
|
109
|
+
</Suspense>
|
|
110
|
+
),
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
path: urls.legalTermsOfService.replace(/^\//, ''),
|
|
114
|
+
element: (
|
|
115
|
+
<Suspense fallback={<RouteFallback />}>
|
|
116
|
+
<LegalDocumentView />
|
|
117
|
+
</Suspense>
|
|
118
|
+
),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
path: urls.legalNotice.replace(/^\//, ''),
|
|
122
|
+
element: (
|
|
123
|
+
<Suspense fallback={<RouteFallback />}>
|
|
124
|
+
<LegalDocumentView />
|
|
125
|
+
</Suspense>
|
|
126
|
+
),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
path: urls.legalDataProcessingAgreement.replace(/^\//, ''),
|
|
130
|
+
element: (
|
|
131
|
+
<Suspense fallback={<RouteFallback />}>
|
|
132
|
+
<LegalDocumentView />
|
|
133
|
+
</Suspense>
|
|
134
|
+
),
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
// Admin route
|
|
138
|
+
path: `${adminPath.replace(/^\//, '')}/*`,
|
|
139
|
+
element: <AdminView />,
|
|
140
|
+
},
|
|
54
141
|
{
|
|
55
142
|
// Catch-all route
|
|
56
143
|
path: '*',
|