@micha.bigler/ui-core-micha 1.4.40 → 2.1.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/dist/index.js +1 -0
- package/dist/pages/AccountPage.js +19 -15
- package/package.json +1 -1
- package/src/index.js +2 -0
- package/src/pages/AccountPage.jsx +24 -16
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// index.js (Entry Point deiner Library)
|
|
2
2
|
// --- 1. Auth Context (Essentiell für den Wrapper) ---
|
|
3
3
|
export { AuthContext, AuthProvider } from './auth/AuthContext';
|
|
4
|
+
export { default as apiClient, ensureCsrfToken } from "./auth/apiClient";
|
|
4
5
|
// --- 2. API & Services (Neue Struktur) ---
|
|
5
6
|
// Statt dem 'authApi'-Objekt exportieren wir die Funktionen direkt.
|
|
6
7
|
// Konsumenten können dann machen: import { loginWithPassword } from 'django-core-micha';
|
|
@@ -5,6 +5,13 @@ import { useSearchParams } from 'react-router-dom';
|
|
|
5
5
|
import { Tabs, Tab, Box, Typography, Alert, CircularProgress } from '@mui/material';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
// Internal Library Components
|
|
8
|
+
// Stellen Sie sicher, dass diese Pfade korrekt auf Ihre Library zeigen!
|
|
9
|
+
// Da Sie '@micha.bigler/ui-core-micha' nutzen, sollten die Imports ggf. so aussehen:
|
|
10
|
+
import { AuthContext,
|
|
11
|
+
// ... andere Komponenten aus der Lib importieren, falls sie dort exportiert sind
|
|
12
|
+
// Wenn sie lokal sind, lassen Sie die relativen Pfade.
|
|
13
|
+
} from '@micha.bigler/ui-core-micha';
|
|
14
|
+
// Falls die Komponenten noch lokal sind:
|
|
8
15
|
import { WidePage } from '../layout/PageLayout';
|
|
9
16
|
import { ProfileComponent } from '../components/ProfileComponent';
|
|
10
17
|
import { SecurityComponent } from '../components/SecurityComponent';
|
|
@@ -12,14 +19,7 @@ import { UserListComponent } from '../components/UserListComponent';
|
|
|
12
19
|
import { UserInviteComponent } from '../components/UserInviteComponent';
|
|
13
20
|
import { AccessCodeManager } from '../components/AccessCodeManager';
|
|
14
21
|
import { SupportRecoveryRequestsTab } from '../components/SupportRecoveryRequestsTab';
|
|
15
|
-
import {
|
|
16
|
-
import { updateUserProfile } from '../auth/authApi';
|
|
17
|
-
/**
|
|
18
|
-
* Complete, self-configuring Account Page.
|
|
19
|
-
* Architecture:
|
|
20
|
-
* - Permissions: Read from user.ui_permissions (from Backend).
|
|
21
|
-
* - Roles: Read from user.available_roles (from Backend).
|
|
22
|
-
*/
|
|
22
|
+
import { updateUserProfile } from '../auth/authApi'; // Ggf. Pfad anpassen
|
|
23
23
|
export function AccountPage() {
|
|
24
24
|
const { t } = useTranslation();
|
|
25
25
|
const { user, login, loading } = useContext(AuthContext);
|
|
@@ -28,9 +28,11 @@ export function AccountPage() {
|
|
|
28
28
|
const currentTab = searchParams.get('tab') || 'profile';
|
|
29
29
|
const fromRecovery = searchParams.get('from') === 'recovery';
|
|
30
30
|
const fromWeakLogin = searchParams.get('from') === 'weak_login';
|
|
31
|
-
// 2. Data & Permissions
|
|
31
|
+
// 2. Data & Permissions
|
|
32
32
|
const activeRoles = (user === null || user === void 0 ? void 0 : user.available_roles) || [];
|
|
33
33
|
const perms = (user === null || user === void 0 ? void 0 : user.ui_permissions) || {};
|
|
34
|
+
// NEU: Superuser-Flag prüfen
|
|
35
|
+
const isSuperUser = (user === null || user === void 0 ? void 0 : user.is_superuser) || false;
|
|
34
36
|
const handleTabChange = (_event, newValue) => {
|
|
35
37
|
setSearchParams({ tab: newValue });
|
|
36
38
|
};
|
|
@@ -38,7 +40,7 @@ export function AccountPage() {
|
|
|
38
40
|
const updatedUser = await updateUserProfile(payload);
|
|
39
41
|
login(updatedUser);
|
|
40
42
|
};
|
|
41
|
-
// 3. Dynamic Tabs
|
|
43
|
+
// 3. Dynamic Tabs (angepasst für Superuser)
|
|
42
44
|
const tabs = useMemo(() => {
|
|
43
45
|
if (!user)
|
|
44
46
|
return [];
|
|
@@ -46,20 +48,21 @@ export function AccountPage() {
|
|
|
46
48
|
{ value: 'profile', label: t('Account.TAB_PROFILE', 'Profile') },
|
|
47
49
|
{ value: 'security', label: t('Account.TAB_SECURITY', 'Security') },
|
|
48
50
|
];
|
|
49
|
-
|
|
51
|
+
// Logik: Superuser darf ALLES, sonst gelten die spezifischen Permissions
|
|
52
|
+
if (isSuperUser || perms.can_view_users) {
|
|
50
53
|
list.push({ value: 'users', label: t('Account.TAB_USERS', 'Users') });
|
|
51
54
|
}
|
|
52
|
-
if (perms.can_invite) {
|
|
55
|
+
if (isSuperUser || perms.can_invite) {
|
|
53
56
|
list.push({ value: 'invite', label: t('Account.TAB_INVITE', 'Invite') });
|
|
54
57
|
}
|
|
55
|
-
if (perms.can_manage_access_codes) {
|
|
58
|
+
if (isSuperUser || perms.can_manage_access_codes) {
|
|
56
59
|
list.push({ value: 'access', label: t('Account.TAB_ACCESS_CODES', 'Access Codes') });
|
|
57
60
|
}
|
|
58
|
-
if (perms.can_view_support) {
|
|
61
|
+
if (isSuperUser || perms.can_view_support) {
|
|
59
62
|
list.push({ value: 'support', label: t('Account.TAB_SUPPORT', 'Support') });
|
|
60
63
|
}
|
|
61
64
|
return list;
|
|
62
|
-
}, [user, perms, t]);
|
|
65
|
+
}, [user, perms, t, isSuperUser]);
|
|
63
66
|
// 4. Loading & Auth Checks
|
|
64
67
|
if (loading) {
|
|
65
68
|
return (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', mt: 10 }, children: _jsx(CircularProgress, {}) }));
|
|
@@ -69,6 +72,7 @@ export function AccountPage() {
|
|
|
69
72
|
}
|
|
70
73
|
// 5. Security Check: Is the active tab allowed?
|
|
71
74
|
const activeTabExists = tabs.some(t => t.value === currentTab);
|
|
75
|
+
// Falls der Tab nicht erlaubt ist (z.B. manuell in URL eingegeben), Fallback auf 'profile'
|
|
72
76
|
const safeTab = activeTabExists ? currentTab : 'profile';
|
|
73
77
|
return (_jsxs(WidePage, { title: t('Account.TITLE', 'Account & Administration'), children: [_jsx(Helmet, { children: _jsxs("title", { children: [t('Account.PAGE_TITLE', 'Account'), " \u2013 ", user.email] }) }), _jsx(Tabs, { value: safeTab, onChange: handleTabChange, variant: "scrollable", scrollButtons: "auto", sx: { mb: 3, borderBottom: 1, borderColor: 'divider' }, children: tabs.map((tab) => (_jsx(Tab, { label: tab.label, value: tab.value }, tab.value))) }), safeTab === 'profile' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(ProfileComponent, { onSubmit: handleProfileSubmit, showName: true, showPrivacy: true, showCookies: true }) })), safeTab === 'security' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(SecurityComponent, { fromRecovery: fromRecovery, fromWeakLogin: fromWeakLogin }) })), safeTab === 'users' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(UserListComponent, { roles: activeRoles, currentUser: user }) })), safeTab === 'invite' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(UserInviteComponent, {}) })), safeTab === 'access' && (_jsxs(Box, { sx: { mt: 2 }, children: [_jsx(Typography, { variant: "body2", sx: { mb: 2, color: 'text.secondary' }, children: t('Account.ACCESS_CODES_HINT', 'Manage access codes for self-registration.') }), _jsx(AccessCodeManager, {})] })), safeTab === 'support' && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(SupportRecoveryRequestsTab, {}) }))] }));
|
|
74
78
|
}
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// --- 1. Auth Context (Essentiell für den Wrapper) ---
|
|
4
4
|
export { AuthContext, AuthProvider } from './auth/AuthContext';
|
|
5
5
|
|
|
6
|
+
export { default as apiClient, ensureCsrfToken } from "./auth/apiClient";
|
|
7
|
+
|
|
6
8
|
// --- 2. API & Services (Neue Struktur) ---
|
|
7
9
|
// Statt dem 'authApi'-Objekt exportieren wir die Funktionen direkt.
|
|
8
10
|
// Konsumenten können dann machen: import { loginWithPassword } from 'django-core-micha';
|
|
@@ -12,6 +12,15 @@ import {
|
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
13
|
|
|
14
14
|
// Internal Library Components
|
|
15
|
+
// Stellen Sie sicher, dass diese Pfade korrekt auf Ihre Library zeigen!
|
|
16
|
+
// Da Sie '@micha.bigler/ui-core-micha' nutzen, sollten die Imports ggf. so aussehen:
|
|
17
|
+
import {
|
|
18
|
+
AuthContext,
|
|
19
|
+
// ... andere Komponenten aus der Lib importieren, falls sie dort exportiert sind
|
|
20
|
+
// Wenn sie lokal sind, lassen Sie die relativen Pfade.
|
|
21
|
+
} from '@micha.bigler/ui-core-micha';
|
|
22
|
+
|
|
23
|
+
// Falls die Komponenten noch lokal sind:
|
|
15
24
|
import { WidePage } from '../layout/PageLayout';
|
|
16
25
|
import { ProfileComponent } from '../components/ProfileComponent';
|
|
17
26
|
import { SecurityComponent } from '../components/SecurityComponent';
|
|
@@ -19,15 +28,8 @@ import { UserListComponent } from '../components/UserListComponent';
|
|
|
19
28
|
import { UserInviteComponent } from '../components/UserInviteComponent';
|
|
20
29
|
import { AccessCodeManager } from '../components/AccessCodeManager';
|
|
21
30
|
import { SupportRecoveryRequestsTab } from '../components/SupportRecoveryRequestsTab';
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Complete, self-configuring Account Page.
|
|
27
|
-
* Architecture:
|
|
28
|
-
* - Permissions: Read from user.ui_permissions (from Backend).
|
|
29
|
-
* - Roles: Read from user.available_roles (from Backend).
|
|
30
|
-
*/
|
|
31
|
+
import { updateUserProfile } from '../auth/authApi'; // Ggf. Pfad anpassen
|
|
32
|
+
|
|
31
33
|
export function AccountPage() {
|
|
32
34
|
const { t } = useTranslation();
|
|
33
35
|
const { user, login, loading } = useContext(AuthContext);
|
|
@@ -38,9 +40,12 @@ export function AccountPage() {
|
|
|
38
40
|
const fromRecovery = searchParams.get('from') === 'recovery';
|
|
39
41
|
const fromWeakLogin = searchParams.get('from') === 'weak_login';
|
|
40
42
|
|
|
41
|
-
// 2. Data & Permissions
|
|
43
|
+
// 2. Data & Permissions
|
|
42
44
|
const activeRoles = user?.available_roles || [];
|
|
43
45
|
const perms = user?.ui_permissions || {};
|
|
46
|
+
|
|
47
|
+
// NEU: Superuser-Flag prüfen
|
|
48
|
+
const isSuperUser = user?.is_superuser || false;
|
|
44
49
|
|
|
45
50
|
const handleTabChange = (_event, newValue) => {
|
|
46
51
|
setSearchParams({ tab: newValue });
|
|
@@ -51,7 +56,7 @@ export function AccountPage() {
|
|
|
51
56
|
login(updatedUser);
|
|
52
57
|
};
|
|
53
58
|
|
|
54
|
-
// 3. Dynamic Tabs
|
|
59
|
+
// 3. Dynamic Tabs (angepasst für Superuser)
|
|
55
60
|
const tabs = useMemo(() => {
|
|
56
61
|
if (!user) return [];
|
|
57
62
|
|
|
@@ -60,24 +65,26 @@ export function AccountPage() {
|
|
|
60
65
|
{ value: 'security', label: t('Account.TAB_SECURITY', 'Security') },
|
|
61
66
|
];
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
// Logik: Superuser darf ALLES, sonst gelten die spezifischen Permissions
|
|
69
|
+
|
|
70
|
+
if (isSuperUser || perms.can_view_users) {
|
|
64
71
|
list.push({ value: 'users', label: t('Account.TAB_USERS', 'Users') });
|
|
65
72
|
}
|
|
66
73
|
|
|
67
|
-
if (perms.can_invite) {
|
|
74
|
+
if (isSuperUser || perms.can_invite) {
|
|
68
75
|
list.push({ value: 'invite', label: t('Account.TAB_INVITE', 'Invite') });
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
if (perms.can_manage_access_codes) {
|
|
78
|
+
if (isSuperUser || perms.can_manage_access_codes) {
|
|
72
79
|
list.push({ value: 'access', label: t('Account.TAB_ACCESS_CODES', 'Access Codes') });
|
|
73
80
|
}
|
|
74
81
|
|
|
75
|
-
if (perms.can_view_support) {
|
|
82
|
+
if (isSuperUser || perms.can_view_support) {
|
|
76
83
|
list.push({ value: 'support', label: t('Account.TAB_SUPPORT', 'Support') });
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
return list;
|
|
80
|
-
}, [user, perms, t]);
|
|
87
|
+
}, [user, perms, t, isSuperUser]);
|
|
81
88
|
|
|
82
89
|
// 4. Loading & Auth Checks
|
|
83
90
|
if (loading) {
|
|
@@ -100,6 +107,7 @@ export function AccountPage() {
|
|
|
100
107
|
|
|
101
108
|
// 5. Security Check: Is the active tab allowed?
|
|
102
109
|
const activeTabExists = tabs.some(t => t.value === currentTab);
|
|
110
|
+
// Falls der Tab nicht erlaubt ist (z.B. manuell in URL eingegeben), Fallback auf 'profile'
|
|
103
111
|
const safeTab = activeTabExists ? currentTab : 'profile';
|
|
104
112
|
|
|
105
113
|
return (
|