mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-01 20:10:35 +01:00
move to propietary for settings
This commit is contained in:
parent
0da1ae06d9
commit
2239e9cc2d
@ -2,18 +2,6 @@ import React from 'react';
|
||||
import { NavKey } from '@app/components/shared/config/types';
|
||||
import HotkeysSection from '@app/components/shared/config/configSections/HotkeysSection';
|
||||
import GeneralSection from '@app/components/shared/config/configSections/GeneralSection';
|
||||
import AdminGeneralSection from '@app/components/shared/config/configSections/AdminGeneralSection';
|
||||
import AdminSecuritySection from '@app/components/shared/config/configSections/AdminSecuritySection';
|
||||
import AdminConnectionsSection from '@app/components/shared/config/configSections/AdminConnectionsSection';
|
||||
import AdminPrivacySection from '@app/components/shared/config/configSections/AdminPrivacySection';
|
||||
import AdminDatabaseSection from '@app/components/shared/config/configSections/AdminDatabaseSection';
|
||||
import AdminAdvancedSection from '@app/components/shared/config/configSections/AdminAdvancedSection';
|
||||
import AdminLegalSection from '@app/components/shared/config/configSections/AdminLegalSection';
|
||||
import AdminPremiumSection from '@app/components/shared/config/configSections/AdminPremiumSection';
|
||||
import AdminFeaturesSection from '@app/components/shared/config/configSections/AdminFeaturesSection';
|
||||
import AdminEndpointsSection from '@app/components/shared/config/configSections/AdminEndpointsSection';
|
||||
import AdminAuditSection from '@app/components/shared/config/configSections/AdminAuditSection';
|
||||
import AdminUsageSection from '@app/components/shared/config/configSections/AdminUsageSection';
|
||||
|
||||
export interface ConfigNavItem {
|
||||
key: NavKey;
|
||||
@ -64,133 +52,5 @@ export const createConfigNavSections = (
|
||||
},
|
||||
];
|
||||
|
||||
// Add Admin sections if user is admin OR if login is disabled (but mark as disabled)
|
||||
if (isAdmin || !loginEnabled) {
|
||||
const requiresLogin = !loginEnabled;
|
||||
// Configuration
|
||||
sections.push({
|
||||
title: 'Configuration',
|
||||
items: [
|
||||
{
|
||||
key: 'adminGeneral',
|
||||
label: 'System Settings',
|
||||
icon: 'settings-rounded',
|
||||
component: <AdminGeneralSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminFeatures',
|
||||
label: 'Features',
|
||||
icon: 'extension-rounded',
|
||||
component: <AdminFeaturesSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminEndpoints',
|
||||
label: 'Endpoints',
|
||||
icon: 'api-rounded',
|
||||
component: <AdminEndpointsSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminDatabase',
|
||||
label: 'Database',
|
||||
icon: 'storage-rounded',
|
||||
component: <AdminDatabaseSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminAdvanced',
|
||||
label: 'Advanced',
|
||||
icon: 'tune-rounded',
|
||||
component: <AdminAdvancedSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Security & Authentication
|
||||
sections.push({
|
||||
title: 'Security & Authentication',
|
||||
items: [
|
||||
{
|
||||
key: 'adminSecurity',
|
||||
label: 'Security',
|
||||
icon: 'shield-rounded',
|
||||
component: <AdminSecuritySection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminConnections',
|
||||
label: 'Connections',
|
||||
icon: 'link-rounded',
|
||||
component: <AdminConnectionsSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Licensing & Analytics
|
||||
sections.push({
|
||||
title: 'Licensing & Analytics',
|
||||
items: [
|
||||
{
|
||||
key: 'adminPremium',
|
||||
label: 'Premium',
|
||||
icon: 'star-rounded',
|
||||
component: <AdminPremiumSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminAudit',
|
||||
label: 'Audit',
|
||||
icon: 'fact-check-rounded',
|
||||
component: <AdminAuditSection />,
|
||||
disabled: !runningEE || requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : 'Requires Enterprise license'
|
||||
},
|
||||
{
|
||||
key: 'adminUsage',
|
||||
label: 'Usage Analytics',
|
||||
icon: 'analytics-rounded',
|
||||
component: <AdminUsageSection />,
|
||||
disabled: !runningEE || requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : 'Requires Enterprise license'
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Policies & Privacy
|
||||
sections.push({
|
||||
title: 'Policies & Privacy',
|
||||
items: [
|
||||
{
|
||||
key: 'adminLegal',
|
||||
label: 'Legal',
|
||||
icon: 'gavel-rounded',
|
||||
component: <AdminLegalSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminPrivacy',
|
||||
label: 'Privacy',
|
||||
icon: 'visibility-rounded',
|
||||
component: <AdminPrivacySection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return sections;
|
||||
};
|
||||
|
||||
@ -2,40 +2,180 @@ import React from 'react';
|
||||
import { createConfigNavSections as createCoreConfigNavSections, ConfigNavSection } from '@core/components/shared/config/configNavSections';
|
||||
import PeopleSection from '@app/components/shared/config/configSections/PeopleSection';
|
||||
import TeamsSection from '@app/components/shared/config/configSections/TeamsSection';
|
||||
import AdminGeneralSection from '@app/components/shared/config/configSections/AdminGeneralSection';
|
||||
import AdminSecuritySection from '@app/components/shared/config/configSections/AdminSecuritySection';
|
||||
import AdminConnectionsSection from '@app/components/shared/config/configSections/AdminConnectionsSection';
|
||||
import AdminPrivacySection from '@app/components/shared/config/configSections/AdminPrivacySection';
|
||||
import AdminDatabaseSection from '@app/components/shared/config/configSections/AdminDatabaseSection';
|
||||
import AdminAdvancedSection from '@app/components/shared/config/configSections/AdminAdvancedSection';
|
||||
import AdminLegalSection from '@app/components/shared/config/configSections/AdminLegalSection';
|
||||
import AdminPremiumSection from '@app/components/shared/config/configSections/AdminPremiumSection';
|
||||
import AdminFeaturesSection from '@app/components/shared/config/configSections/AdminFeaturesSection';
|
||||
import AdminEndpointsSection from '@app/components/shared/config/configSections/AdminEndpointsSection';
|
||||
import AdminAuditSection from '@app/components/shared/config/configSections/AdminAuditSection';
|
||||
import AdminUsageSection from '@app/components/shared/config/configSections/AdminUsageSection';
|
||||
|
||||
/**
|
||||
* Proprietary extension of createConfigNavSections that adds workspace sections
|
||||
* Proprietary extension of createConfigNavSections that adds all admin and workspace sections
|
||||
*/
|
||||
export const createConfigNavSections = (
|
||||
isAdmin: boolean = false,
|
||||
runningEE: boolean = false,
|
||||
loginEnabled: boolean = true
|
||||
): ConfigNavSection[] => {
|
||||
// Get the core sections
|
||||
// Get the core sections (just Preferences)
|
||||
const sections = createCoreConfigNavSections(isAdmin, runningEE, loginEnabled);
|
||||
|
||||
// Add Workspace section if user is admin
|
||||
if (isAdmin) {
|
||||
const workspaceSection: ConfigNavSection = {
|
||||
// Add Admin sections if user is admin OR if login is disabled (but mark as disabled)
|
||||
if (isAdmin || !loginEnabled) {
|
||||
const requiresLogin = !loginEnabled;
|
||||
|
||||
// Workspace
|
||||
sections.push({
|
||||
title: 'Workspace',
|
||||
items: [
|
||||
{
|
||||
key: 'people',
|
||||
label: 'People',
|
||||
icon: 'group-rounded',
|
||||
component: <PeopleSection />
|
||||
component: <PeopleSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'teams',
|
||||
label: 'Teams',
|
||||
icon: 'groups-rounded',
|
||||
component: <TeamsSection />
|
||||
component: <TeamsSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
// Insert workspace section after Preferences (at index 1)
|
||||
sections.splice(1, 0, workspaceSection);
|
||||
// Configuration
|
||||
sections.push({
|
||||
title: 'Configuration',
|
||||
items: [
|
||||
{
|
||||
key: 'adminGeneral',
|
||||
label: 'System Settings',
|
||||
icon: 'settings-rounded',
|
||||
component: <AdminGeneralSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminFeatures',
|
||||
label: 'Features',
|
||||
icon: 'extension-rounded',
|
||||
component: <AdminFeaturesSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminEndpoints',
|
||||
label: 'Endpoints',
|
||||
icon: 'api-rounded',
|
||||
component: <AdminEndpointsSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminDatabase',
|
||||
label: 'Database',
|
||||
icon: 'storage-rounded',
|
||||
component: <AdminDatabaseSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminAdvanced',
|
||||
label: 'Advanced',
|
||||
icon: 'tune-rounded',
|
||||
component: <AdminAdvancedSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Security & Authentication
|
||||
sections.push({
|
||||
title: 'Security & Authentication',
|
||||
items: [
|
||||
{
|
||||
key: 'adminSecurity',
|
||||
label: 'Security',
|
||||
icon: 'shield-rounded',
|
||||
component: <AdminSecuritySection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminConnections',
|
||||
label: 'Connections',
|
||||
icon: 'link-rounded',
|
||||
component: <AdminConnectionsSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Licensing & Analytics
|
||||
sections.push({
|
||||
title: 'Licensing & Analytics',
|
||||
items: [
|
||||
{
|
||||
key: 'adminPremium',
|
||||
label: 'Premium',
|
||||
icon: 'star-rounded',
|
||||
component: <AdminPremiumSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminAudit',
|
||||
label: 'Audit',
|
||||
icon: 'fact-check-rounded',
|
||||
component: <AdminAuditSection />,
|
||||
disabled: !runningEE || requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : 'Requires Enterprise license'
|
||||
},
|
||||
{
|
||||
key: 'adminUsage',
|
||||
label: 'Usage Analytics',
|
||||
icon: 'analytics-rounded',
|
||||
component: <AdminUsageSection />,
|
||||
disabled: !runningEE || requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : 'Requires Enterprise license'
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Policies & Privacy
|
||||
sections.push({
|
||||
title: 'Policies & Privacy',
|
||||
items: [
|
||||
{
|
||||
key: 'adminLegal',
|
||||
label: 'Legal',
|
||||
icon: 'gavel-rounded',
|
||||
component: <AdminLegalSection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
{
|
||||
key: 'adminPrivacy',
|
||||
label: 'Privacy',
|
||||
icon: 'visibility-rounded',
|
||||
component: <AdminPrivacySection />,
|
||||
disabled: requiresLogin,
|
||||
disabledTooltip: requiresLogin ? 'Enable login mode first' : undefined
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return sections;
|
||||
|
||||
@ -28,10 +28,13 @@ import { userManagementService, User } from '@app/services/userManagementService
|
||||
import { teamService, Team } from '@app/services/teamService';
|
||||
import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex';
|
||||
import { useAppConfig } from '@app/contexts/AppConfigContext';
|
||||
import { useLoginRequired } from '@app/hooks/useLoginRequired';
|
||||
import LoginRequiredBanner from '@app/components/shared/config/LoginRequiredBanner';
|
||||
|
||||
export default function PeopleSection() {
|
||||
const { t } = useTranslation();
|
||||
const { config } = useAppConfig();
|
||||
const { loginEnabled } = useLoginRequired();
|
||||
const [users, setUsers] = useState<User[]>([]);
|
||||
const [teams, setTeams] = useState<Team[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -97,30 +100,103 @@ export default function PeopleSection() {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const [adminData, teamsData] = await Promise.all([
|
||||
userManagementService.getUsers(),
|
||||
teamService.getTeams(),
|
||||
]);
|
||||
|
||||
// Enrich users with session data
|
||||
const enrichedUsers = adminData.users.map(user => ({
|
||||
...user,
|
||||
isActive: adminData.userSessions[user.username] || false,
|
||||
lastRequest: adminData.userLastRequest[user.username] || undefined,
|
||||
}));
|
||||
if (loginEnabled) {
|
||||
const [adminData, teamsData] = await Promise.all([
|
||||
userManagementService.getUsers(),
|
||||
teamService.getTeams(),
|
||||
]);
|
||||
|
||||
setUsers(enrichedUsers);
|
||||
setTeams(teamsData);
|
||||
// Enrich users with session data
|
||||
const enrichedUsers = adminData.users.map(user => ({
|
||||
...user,
|
||||
isActive: adminData.userSessions[user.username] || false,
|
||||
lastRequest: adminData.userLastRequest[user.username] || undefined,
|
||||
}));
|
||||
|
||||
// Store license information
|
||||
setLicenseInfo({
|
||||
maxAllowedUsers: adminData.maxAllowedUsers,
|
||||
availableSlots: adminData.availableSlots,
|
||||
grandfatheredUserCount: adminData.grandfatheredUserCount,
|
||||
licenseMaxUsers: adminData.licenseMaxUsers,
|
||||
premiumEnabled: adminData.premiumEnabled,
|
||||
totalUsers: adminData.totalUsers,
|
||||
});
|
||||
setUsers(enrichedUsers);
|
||||
setTeams(teamsData);
|
||||
|
||||
// Store license information
|
||||
setLicenseInfo({
|
||||
maxAllowedUsers: adminData.maxAllowedUsers,
|
||||
availableSlots: adminData.availableSlots,
|
||||
grandfatheredUserCount: adminData.grandfatheredUserCount,
|
||||
licenseMaxUsers: adminData.licenseMaxUsers,
|
||||
premiumEnabled: adminData.premiumEnabled,
|
||||
totalUsers: adminData.totalUsers,
|
||||
});
|
||||
} else {
|
||||
// Provide example data when login is disabled
|
||||
const exampleUsers: User[] = [
|
||||
{
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@example.com',
|
||||
enabled: true,
|
||||
roleName: 'ROLE_ADMIN',
|
||||
rolesAsString: 'ROLE_ADMIN',
|
||||
authenticationType: 'password',
|
||||
isActive: true,
|
||||
lastRequest: new Date().toISOString(),
|
||||
team: { id: 1, name: 'Engineering', userCount: 3 }
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
username: 'john.doe',
|
||||
email: 'john.doe@example.com',
|
||||
enabled: true,
|
||||
roleName: 'ROLE_USER',
|
||||
rolesAsString: 'ROLE_USER',
|
||||
authenticationType: 'password',
|
||||
isActive: false,
|
||||
lastRequest: new Date(Date.now() - 86400000).toISOString(),
|
||||
team: { id: 1, name: 'Engineering', userCount: 3 }
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
username: 'jane.smith',
|
||||
email: 'jane.smith@example.com',
|
||||
enabled: true,
|
||||
roleName: 'ROLE_USER',
|
||||
rolesAsString: 'ROLE_USER',
|
||||
authenticationType: 'oauth',
|
||||
isActive: true,
|
||||
lastRequest: new Date().toISOString(),
|
||||
team: { id: 2, name: 'Marketing', userCount: 2 }
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
username: 'bob.wilson',
|
||||
email: 'bob.wilson@example.com',
|
||||
enabled: false,
|
||||
roleName: 'ROLE_USER',
|
||||
rolesAsString: 'ROLE_USER',
|
||||
authenticationType: 'password',
|
||||
isActive: false,
|
||||
lastRequest: new Date(Date.now() - 604800000).toISOString(),
|
||||
team: undefined
|
||||
}
|
||||
];
|
||||
|
||||
const exampleTeams: Team[] = [
|
||||
{ id: 1, name: 'Engineering', userCount: 3 },
|
||||
{ id: 2, name: 'Marketing', userCount: 2 }
|
||||
];
|
||||
|
||||
setUsers(exampleUsers);
|
||||
setTeams(exampleTeams);
|
||||
|
||||
// Example license information
|
||||
setLicenseInfo({
|
||||
maxAllowedUsers: 10,
|
||||
availableSlots: 6,
|
||||
grandfatheredUserCount: 0,
|
||||
licenseMaxUsers: 5,
|
||||
premiumEnabled: true,
|
||||
totalUsers: 4,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch people data:', error);
|
||||
alert({ alertType: 'error', title: 'Failed to load people data' });
|
||||
@ -405,6 +481,7 @@ export default function PeopleSection() {
|
||||
|
||||
return (
|
||||
<Stack gap="lg">
|
||||
<LoginRequiredBanner show={!loginEnabled} />
|
||||
<div>
|
||||
<Text fw={600} size="lg">
|
||||
{t('workspace.people.title')}
|
||||
@ -457,15 +534,15 @@ export default function PeopleSection() {
|
||||
style={{ maxWidth: 300 }}
|
||||
/>
|
||||
<Tooltip
|
||||
label={t('workspace.people.license.noSlotsAvailable', 'No user slots available')}
|
||||
disabled={!licenseInfo || licenseInfo.availableSlots > 0}
|
||||
label={!loginEnabled ? 'Enable login mode first' : t('workspace.people.license.noSlotsAvailable', 'No user slots available')}
|
||||
disabled={loginEnabled && (!licenseInfo || licenseInfo.availableSlots > 0)}
|
||||
position="bottom"
|
||||
withArrow
|
||||
>
|
||||
<Button
|
||||
leftSection={<LocalIcon icon="person-add" width="1rem" height="1rem" />}
|
||||
onClick={() => setInviteModalOpened(true)}
|
||||
disabled={licenseInfo ? licenseInfo.availableSlots === 0 : false}
|
||||
disabled={!loginEnabled || (licenseInfo ? licenseInfo.availableSlots === 0 : false)}
|
||||
>
|
||||
{t('workspace.people.addMembers')}
|
||||
</Button>
|
||||
@ -616,20 +693,21 @@ export default function PeopleSection() {
|
||||
{/* Actions menu */}
|
||||
<Menu position="bottom-end" withinPortal>
|
||||
<Menu.Target>
|
||||
<ActionIcon variant="subtle" color="gray">
|
||||
<ActionIcon variant="subtle" color="gray" disabled={!loginEnabled}>
|
||||
<LocalIcon icon="more-vert" width="1rem" height="1rem" />
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown style={{ zIndex: Z_INDEX_OVER_CONFIG_MODAL }}>
|
||||
<Menu.Item onClick={() => openEditModal(user)}>{t('workspace.people.editRole')}</Menu.Item>
|
||||
<Menu.Item onClick={() => openEditModal(user)} disabled={!loginEnabled}>{t('workspace.people.editRole')}</Menu.Item>
|
||||
<Menu.Item
|
||||
leftSection={user.enabled ? <LocalIcon icon="person-off" width="1rem" height="1rem" /> : <LocalIcon icon="person-check" width="1rem" height="1rem" />}
|
||||
onClick={() => handleToggleEnabled(user)}
|
||||
disabled={!loginEnabled}
|
||||
>
|
||||
{user.enabled ? t('workspace.people.disable') : t('workspace.people.enable')}
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item color="red" leftSection={<LocalIcon icon="delete" width="1rem" height="1rem" />} onClick={() => handleDeleteUser(user)}>
|
||||
<Menu.Item color="red" leftSection={<LocalIcon icon="delete" width="1rem" height="1rem" />} onClick={() => handleDeleteUser(user)} disabled={!loginEnabled}>
|
||||
{t('workspace.people.deleteUser')}
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
|
||||
@ -22,9 +22,12 @@ import { teamService, Team } from '@app/services/teamService';
|
||||
import { userManagementService, User } from '@app/services/userManagementService';
|
||||
import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex';
|
||||
import TeamDetailsSection from '@app/components/shared/config/configSections/TeamDetailsSection';
|
||||
import { useLoginRequired } from '@app/hooks/useLoginRequired';
|
||||
import LoginRequiredBanner from '@app/components/shared/config/LoginRequiredBanner';
|
||||
|
||||
export default function TeamsSection() {
|
||||
const { t } = useTranslation();
|
||||
const { loginEnabled } = useLoginRequired();
|
||||
const [teams, setTeams] = useState<Team[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [createModalOpened, setCreateModalOpened] = useState(false);
|
||||
@ -47,8 +50,18 @@ export default function TeamsSection() {
|
||||
const fetchTeams = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const teamsData = await teamService.getTeams();
|
||||
setTeams(teamsData);
|
||||
if (loginEnabled) {
|
||||
const teamsData = await teamService.getTeams();
|
||||
setTeams(teamsData);
|
||||
} else {
|
||||
// Provide example data when login is disabled
|
||||
const exampleTeams: Team[] = [
|
||||
{ id: 1, name: 'Engineering', userCount: 3 },
|
||||
{ id: 2, name: 'Marketing', userCount: 2 },
|
||||
{ id: 3, name: 'Internal', userCount: 1 },
|
||||
];
|
||||
setTeams(exampleTeams);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch teams:', error);
|
||||
alert({ alertType: 'error', title: 'Failed to load teams' });
|
||||
@ -207,6 +220,7 @@ export default function TeamsSection() {
|
||||
|
||||
return (
|
||||
<Stack gap="lg">
|
||||
<LoginRequiredBanner show={!loginEnabled} />
|
||||
<div>
|
||||
<Text fw={600} size="lg">
|
||||
{t('workspace.teams.title')}
|
||||
@ -218,7 +232,7 @@ export default function TeamsSection() {
|
||||
|
||||
{/* Header Actions */}
|
||||
<Group justify="flex-end">
|
||||
<Button leftSection={<LocalIcon icon="add" width="1rem" height="1rem" />} onClick={() => setCreateModalOpened(true)}>
|
||||
<Button leftSection={<LocalIcon icon="add" width="1rem" height="1rem" />} onClick={() => setCreateModalOpened(true)} disabled={!loginEnabled}>
|
||||
{t('workspace.teams.createNewTeam')}
|
||||
</Button>
|
||||
</Group>
|
||||
@ -257,8 +271,8 @@ export default function TeamsSection() {
|
||||
teams.map((team) => (
|
||||
<Table.Tr
|
||||
key={team.id}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => setViewingTeamId(team.id)}
|
||||
style={{ cursor: loginEnabled ? 'pointer' : 'default' }}
|
||||
onClick={() => loginEnabled && setViewingTeamId(team.id)}
|
||||
>
|
||||
<Table.Td>
|
||||
<Group gap="xs">
|
||||
@ -290,18 +304,18 @@ export default function TeamsSection() {
|
||||
<Table.Td onClick={(e) => e.stopPropagation()}>
|
||||
<Menu position="bottom-end" withinPortal>
|
||||
<Menu.Target>
|
||||
<ActionIcon variant="subtle" color="gray">
|
||||
<ActionIcon variant="subtle" color="gray" disabled={!loginEnabled}>
|
||||
<LocalIcon icon="more-vert" width="1rem" height="1rem" />
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown style={{ zIndex: Z_INDEX_OVER_CONFIG_MODAL }}>
|
||||
<Menu.Item leftSection={<LocalIcon icon="visibility" width="1rem" height="1rem" />} onClick={() => setViewingTeamId(team.id)}>
|
||||
<Menu.Item leftSection={<LocalIcon icon="visibility" width="1rem" height="1rem" />} onClick={() => setViewingTeamId(team.id)} disabled={!loginEnabled}>
|
||||
{t('workspace.teams.viewTeam', 'View Team')}
|
||||
</Menu.Item>
|
||||
<Menu.Item leftSection={<LocalIcon icon="group" width="1rem" height="1rem" />} onClick={() => openAddMemberModal(team)}>
|
||||
<Menu.Item leftSection={<LocalIcon icon="group" width="1rem" height="1rem" />} onClick={() => openAddMemberModal(team)} disabled={!loginEnabled}>
|
||||
{t('workspace.teams.addMember')}
|
||||
</Menu.Item>
|
||||
<Menu.Item leftSection={<LocalIcon icon="edit" width="1rem" height="1rem" />} onClick={() => openRenameModal(team)}>
|
||||
<Menu.Item leftSection={<LocalIcon icon="edit" width="1rem" height="1rem" />} onClick={() => openRenameModal(team)} disabled={!loginEnabled}>
|
||||
{t('workspace.teams.renameTeamLabel')}
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
@ -309,7 +323,7 @@ export default function TeamsSection() {
|
||||
color="red"
|
||||
leftSection={<LocalIcon icon="delete" width="1rem" height="1rem" />}
|
||||
onClick={() => handleDeleteTeam(team)}
|
||||
disabled={team.name === 'Internal'}
|
||||
disabled={!loginEnabled || team.name === 'Internal'}
|
||||
>
|
||||
{t('workspace.teams.deleteTeamLabel')}
|
||||
</Menu.Item>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user