From cf2c7517eb200e781368d480407f21de52dae7a9 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Thu, 30 Oct 2025 13:30:17 +0000 Subject: [PATCH] team updates --- .../controller/api/UsageRestController.java | 63 ++++++++++++-- .../public/locales/en-GB/translation.json | 32 +++++-- .../core/components/shared/AppConfigModal.tsx | 10 ++- .../shared/config/configNavSections.tsx | 32 +------ .../configSections/AdminGeneralSection.tsx | 4 +- .../configSections/AdminUsageSection.tsx | 41 +++++---- .../config/configSections/GeneralSection.tsx | 85 +++++++++++++++++-- .../core/components/shared/config/types.ts | 1 - .../core/services/usageAnalyticsService.ts | 17 ++-- .../shared/config/configNavSections.tsx | 44 ++++++++++ .../config/configSections/GeneralSection.tsx | 53 ++++++++++++ .../config/configSections/PeopleSection.tsx | 2 +- .../configSections/TeamDetailsSection.tsx | 2 +- .../config/configSections/TeamsSection.tsx | 4 +- .../services/teamService.ts | 0 15 files changed, 298 insertions(+), 92 deletions(-) create mode 100644 frontend/src/proprietary/components/shared/config/configNavSections.tsx create mode 100644 frontend/src/proprietary/components/shared/config/configSections/GeneralSection.tsx rename frontend/src/{core => proprietary}/components/shared/config/configSections/PeopleSection.tsx (99%) rename frontend/src/{core => proprietary}/components/shared/config/configSections/TeamDetailsSection.tsx (99%) rename frontend/src/{core => proprietary}/components/shared/config/configSections/TeamsSection.tsx (98%) rename frontend/src/{core => proprietary}/services/teamService.ts (100%) diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/UsageRestController.java b/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/UsageRestController.java index 521dd32d5..0baa1c6b1 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/UsageRestController.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/UsageRestController.java @@ -36,15 +36,14 @@ public class UsageRestController { * events to generate usage statistics. * * @param limit Optional limit on number of endpoints to return - * @param includeHome Whether to include homepage ("/") in results - * @param includeLogin Whether to include login page ("/login") in results + * @param dataType Type of data to include: "all" (default), "api" (API endpoints excluding + * auth), or "ui" (non-API endpoints) * @return Endpoint statistics response */ @GetMapping("/usage-endpoint-statistics") public ResponseEntity getEndpointStatistics( @RequestParam(value = "limit", required = false) Integer limit, - @RequestParam(value = "includeHome", defaultValue = "true") boolean includeHome, - @RequestParam(value = "includeLogin", defaultValue = "true") boolean includeLogin) { + @RequestParam(value = "dataType", defaultValue = "all") String dataType) { // Get all HTTP_REQUEST audit events List httpEvents = @@ -56,11 +55,8 @@ public class UsageRestController { for (PersistentAuditEvent event : httpEvents) { String endpoint = extractEndpointFromAuditData(event.getData()); if (endpoint != null) { - // Apply filters - if (!includeHome && "/".equals(endpoint)) { - continue; - } - if (!includeLogin && "/login".equals(endpoint)) { + // Apply data type filter + if (!shouldIncludeEndpoint(endpoint, dataType)) { continue; } @@ -171,6 +167,55 @@ public class UsageRestController { return endpoint; } + /** + * Determine if an endpoint should be included based on the data type filter. + * + * @param endpoint The endpoint path to check + * @param dataType The filter type: "all", "api", or "ui" + * @return true if the endpoint should be included, false otherwise + */ + private boolean shouldIncludeEndpoint(String endpoint, String dataType) { + if ("all".equalsIgnoreCase(dataType)) { + return true; + } + + boolean isApiEndpoint = isApiEndpoint(endpoint); + + if ("api".equalsIgnoreCase(dataType)) { + return isApiEndpoint; + } else if ("ui".equalsIgnoreCase(dataType)) { + return !isApiEndpoint; + } + + // Default to including all if unrecognized type + return true; + } + + /** + * Check if an endpoint is an API endpoint. API endpoints match /api/v1/* pattern but exclude + * /api/v1/auth/* paths. + * + * @param endpoint The endpoint path to check + * @return true if this is an API endpoint (excluding auth endpoints), false otherwise + */ + private boolean isApiEndpoint(String endpoint) { + if (endpoint == null) { + return false; + } + + // Check if it starts with /api/v1/ + if (!endpoint.startsWith("/api/v1/")) { + return false; + } + + // Exclude auth endpoints + if (endpoint.startsWith("/api/v1/auth/")) { + return false; + } + + return true; + } + // DTOs for response formatting @lombok.Data diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json index c5cbd61ba..a67ade89d 100644 --- a/frontend/public/locales/en-GB/translation.json +++ b/frontend/public/locales/en-GB/translation.json @@ -298,6 +298,20 @@ "general": { "title": "General", "description": "Configure general application preferences.", + "account": "Account", + "accountDescription": "Manage your account settings", + "user": "User", + "signedInAs": "Signed in as", + "logout": "Log out", + "enableFeatures": { + "title": "For System Administrators", + "intro": "Enable user authentication, team management, and workspace features for your organization.", + "action": "Configure", + "and": "and", + "benefit": "Enables user roles, team collaboration, admin controls, and enterprise features.", + "learnMore": "Learn more in documentation", + "dismiss": "Dismiss" + }, "autoUnzip": "Auto-unzip API responses", "autoUnzipDescription": "Automatically extract files from ZIP responses", "autoUnzipTooltip": "Automatically extract ZIP files returned from API operations. Disable to keep ZIP files intact. This does not affect automation workflows.", @@ -399,8 +413,10 @@ "top20": "Top 20", "all": "All", "refresh": "Refresh", - "includeHomepage": "Include Homepage ('/')", - "includeLoginPage": "Include Login Page ('/login')", + "dataTypeLabel": "Data Type:", + "dataTypeAll": "All", + "dataTypeApi": "API", + "dataTypeUi": "UI", "totalEndpoints": "Total Endpoints", "totalVisits": "Total Visits", "showing": "Showing", @@ -3524,8 +3540,8 @@ "restartingMessage": "The server is restarting. Please wait a moment...", "restartError": "Failed to restart server. Please restart manually.", "general": { - "title": "General", - "description": "Configure general application settings including branding and default behaviour.", + "title": "System Settings", + "description": "Configure system-wide application settings including branding and default behaviour.", "ui": "User Interface", "system": "System", "appName": "Application Name", @@ -4812,8 +4828,12 @@ "top20": "Top 20", "all": "All", "refresh": "Refresh", - "includeHome": "Include Homepage ('/')", - "includeLogin": "Include Login Page ('/login')" + "dataTypeLabel": "Data Type:", + "dataType": { + "all": "All", + "api": "API", + "ui": "UI" + } }, "showing": { "top10": "Top 10", diff --git a/frontend/src/core/components/shared/AppConfigModal.tsx b/frontend/src/core/components/shared/AppConfigModal.tsx index f2a4ec6de..d11da7fa0 100644 --- a/frontend/src/core/components/shared/AppConfigModal.tsx +++ b/frontend/src/core/components/shared/AppConfigModal.tsx @@ -18,7 +18,7 @@ interface AppConfigModalProps { const AppConfigModal: React.FC = ({ opened, onClose }) => { const navigate = useNavigate(); const location = useLocation(); - const [active, setActive] = useState('overview'); + const [active, setActive] = useState('general'); const isMobile = useMediaQuery("(max-width: 1024px)"); const { config } = useAppConfig(); @@ -27,7 +27,7 @@ const AppConfigModal: React.FC = ({ opened, onClose }) => { const match = pathname.match(/\/settings\/([^/]+)/); if (match && match[1]) { const validSections: NavKey[] = [ - 'overview', 'people', 'teams', 'general', 'hotkeys', + 'people', 'teams', 'general', 'hotkeys', 'adminGeneral', 'adminSecurity', 'adminConnections', 'adminLegal', 'adminPrivacy', 'adminDatabase', 'adminPremium', 'adminFeatures', 'adminPlan', 'adminAudit', 'adminUsage', 'adminEndpoints', 'adminAdvanced' @@ -44,8 +44,8 @@ const AppConfigModal: React.FC = ({ opened, onClose }) => { if (opened && section) { setActive(section); } else if (opened && location.pathname.startsWith('/settings') && !section) { - // If at /settings without a section, redirect to overview - navigate('/settings/overview', { replace: true }); + // If at /settings without a section, redirect to general + navigate('/settings/general', { replace: true }); } }, [location.pathname, opened, navigate]); @@ -81,6 +81,8 @@ const AppConfigModal: React.FC = ({ opened, onClose }) => { const isAdmin = config?.isAdmin ?? false; const runningEE = config?.runningEE ?? false; + console.log('[AppConfigModal] Config:', { isAdmin, runningEE, fullConfig: config }); + // Left navigation structure and icons const configNavSections = useMemo(() => createConfigNavSections( diff --git a/frontend/src/core/components/shared/config/configNavSections.tsx b/frontend/src/core/components/shared/config/configNavSections.tsx index f91fd9725..7f2cd94b7 100644 --- a/frontend/src/core/components/shared/config/configNavSections.tsx +++ b/frontend/src/core/components/shared/config/configNavSections.tsx @@ -2,8 +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 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'; @@ -49,34 +47,6 @@ export const createConfigNavSections = ( runningEE: boolean = false ): ConfigNavSection[] => { const sections: ConfigNavSection[] = [ - { - title: 'Account', - items: [ - { - key: 'overview', - label: 'Overview', - icon: 'person-rounded', - component: - }, - ], - }, - { - title: 'Workspace', - items: [ - { - key: 'people', - label: 'People', - icon: 'group-rounded', - component: - }, - { - key: 'teams', - label: 'Teams', - icon: 'groups-rounded', - component: - }, - ], - }, { title: 'Preferences', items: [ @@ -104,7 +74,7 @@ export const createConfigNavSections = ( items: [ { key: 'adminGeneral', - label: 'General', + label: 'System Settings', icon: 'settings-rounded', component: }, diff --git a/frontend/src/core/components/shared/config/configSections/AdminGeneralSection.tsx b/frontend/src/core/components/shared/config/configSections/AdminGeneralSection.tsx index c17c88f6a..d6d5bb0cc 100644 --- a/frontend/src/core/components/shared/config/configSections/AdminGeneralSection.tsx +++ b/frontend/src/core/components/shared/config/configSections/AdminGeneralSection.tsx @@ -165,9 +165,9 @@ export default function AdminGeneralSection() { return (
- {t('admin.settings.general.title', 'General')} + {t('admin.settings.general.title', 'System Settings')} - {t('admin.settings.general.description', 'Configure general application settings including branding and default behaviour.')} + {t('admin.settings.general.description', 'Configure system-wide application settings including branding and default behaviour.')}
diff --git a/frontend/src/core/components/shared/config/configSections/AdminUsageSection.tsx b/frontend/src/core/components/shared/config/configSections/AdminUsageSection.tsx index 2af5e375f..2ce1c4ec7 100644 --- a/frontend/src/core/components/shared/config/configSections/AdminUsageSection.tsx +++ b/frontend/src/core/components/shared/config/configSections/AdminUsageSection.tsx @@ -8,7 +8,6 @@ import { Loader, Alert, Card, - Checkbox, } from '@mantine/core'; import { useTranslation } from 'react-i18next'; import usageAnalyticsService, { EndpointStatisticsResponse } from '@app/services/usageAnalyticsService'; @@ -22,8 +21,7 @@ const AdminUsageSection: React.FC = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [displayMode, setDisplayMode] = useState<'top10' | 'top20' | 'all'>('top10'); - const [includeHome, setIncludeHome] = useState(true); - const [includeLogin, setIncludeLogin] = useState(true); + const [dataType, setDataType] = useState<'all' | 'api' | 'ui'>('all'); const fetchData = async () => { try { @@ -31,11 +29,7 @@ const AdminUsageSection: React.FC = () => { setError(null); const limit = displayMode === 'all' ? undefined : displayMode === 'top10' ? 10 : 20; - const response = await usageAnalyticsService.getEndpointStatistics( - limit, - includeHome, - includeLogin - ); + const response = await usageAnalyticsService.getEndpointStatistics(limit, dataType); setData(response); } catch (err) { @@ -47,7 +41,7 @@ const AdminUsageSection: React.FC = () => { useEffect(() => { fetchData(); - }, [displayMode, includeHome, includeLogin]); + }, [displayMode, dataType]); const handleRefresh = () => { fetchData(); @@ -136,15 +130,26 @@ const AdminUsageSection: React.FC = () => { - setIncludeHome(event.currentTarget.checked)} - /> - setIncludeLogin(event.currentTarget.checked)} + + {t('usage.controls.dataTypeLabel', 'Data Type:')} + + setDataType(value as 'all' | 'api' | 'ui')} + data={[ + { + value: 'all', + label: t('usage.controls.dataType.all', 'All'), + }, + { + value: 'api', + label: t('usage.controls.dataType.api', 'API'), + }, + { + value: 'ui', + label: t('usage.controls.dataType.ui', 'UI'), + }, + ]} /> diff --git a/frontend/src/core/components/shared/config/configSections/GeneralSection.tsx b/frontend/src/core/components/shared/config/configSections/GeneralSection.tsx index da71d3c6c..556f14757 100644 --- a/frontend/src/core/components/shared/config/configSections/GeneralSection.tsx +++ b/frontend/src/core/components/shared/config/configSections/GeneralSection.tsx @@ -1,29 +1,98 @@ import React, { useState, useEffect } from 'react'; -import { Paper, Stack, Switch, Text, Tooltip, NumberInput, SegmentedControl } from '@mantine/core'; +import { Paper, Stack, Switch, Text, Tooltip, NumberInput, SegmentedControl, Alert, Code, Group, Anchor, ActionIcon } from '@mantine/core'; import { useTranslation } from 'react-i18next'; import { usePreferences } from '@app/contexts/PreferencesContext'; +import { useAppConfig } from '@app/contexts/AppConfigContext'; import type { ToolPanelMode } from '@app/constants/toolPanel'; +import LocalIcon from '@app/components/shared/LocalIcon'; const DEFAULT_AUTO_UNZIP_FILE_LIMIT = 4; +const BANNER_DISMISSED_KEY = 'stirlingpdf_features_banner_dismissed'; -const GeneralSection: React.FC = () => { +interface GeneralSectionProps { + hideTitle?: boolean; +} + +const GeneralSection: React.FC = ({ hideTitle = false }) => { const { t } = useTranslation(); const { preferences, updatePreference } = usePreferences(); + const { config } = useAppConfig(); const [fileLimitInput, setFileLimitInput] = useState(preferences.autoUnzipFileLimit); + const [bannerDismissed, setBannerDismissed] = useState(() => { + // Check localStorage on mount + return localStorage.getItem(BANNER_DISMISSED_KEY) === 'true'; + }); // Sync local state with preference changes useEffect(() => { setFileLimitInput(preferences.autoUnzipFileLimit); }, [preferences.autoUnzipFileLimit]); + // Check if login is disabled + const loginDisabled = !config?.enableLogin; + + const handleDismissBanner = () => { + setBannerDismissed(true); + localStorage.setItem(BANNER_DISMISSED_KEY, 'true'); + }; + return ( -
- {t('settings.general.title', 'General')} - - {t('settings.general.description', 'Configure general application preferences.')} - -
+ {!hideTitle && ( +
+ {t('settings.general.title', 'General')} + + {t('settings.general.description', 'Configure general application preferences.')} + +
+ )} + + {loginDisabled && !bannerDismissed && ( + + + + + + + + + {t('settings.general.enableFeatures.title', 'For System Administrators')} + + + + {t('settings.general.enableFeatures.intro', 'Enable user authentication, team management, and workspace features for your organization.')} + + + + {t('settings.general.enableFeatures.action', 'Configure')} + + SECURITY_ENABLELOGIN=true + + {t('settings.general.enableFeatures.and', 'and')} + + DISABLE_ADDITIONAL_FEATURES=false + + + {t('settings.general.enableFeatures.benefit', 'Enables user roles, team collaboration, admin controls, and enterprise features.')} + + + {t('settings.general.enableFeatures.learnMore', 'Learn more in documentation')} → + + + + )} diff --git a/frontend/src/core/components/shared/config/types.ts b/frontend/src/core/components/shared/config/types.ts index 047a4272c..6e7c3cf59 100644 --- a/frontend/src/core/components/shared/config/types.ts +++ b/frontend/src/core/components/shared/config/types.ts @@ -1,5 +1,4 @@ export type NavKey = - | 'overview' | 'preferences' | 'notifications' | 'connections' diff --git a/frontend/src/core/services/usageAnalyticsService.ts b/frontend/src/core/services/usageAnalyticsService.ts index d88dfc3d6..4268a91f5 100644 --- a/frontend/src/core/services/usageAnalyticsService.ts +++ b/frontend/src/core/services/usageAnalyticsService.ts @@ -23,18 +23,18 @@ const usageAnalyticsService = { */ async getEndpointStatistics( limit?: number, - includeHome: boolean = true, - includeLogin: boolean = true + dataType: 'all' | 'api' | 'ui' = 'all' ): Promise { - const params: Record = { - includeHome, - includeLogin, - }; + const params: Record = {}; if (limit !== undefined) { params.limit = limit; } + if (dataType !== 'all') { + params.dataType = dataType; + } + const response = await apiClient.get( '/api/v1/proprietary/ui-data/usage-endpoint-statistics', { params } @@ -47,10 +47,9 @@ const usageAnalyticsService = { */ async getChartData( limit?: number, - includeHome: boolean = true, - includeLogin: boolean = true + dataType: 'all' | 'api' | 'ui' = 'all' ): Promise { - const stats = await this.getEndpointStatistics(limit, includeHome, includeLogin); + const stats = await this.getEndpointStatistics(limit, dataType); return { labels: stats.endpoints.map((e) => e.endpoint), diff --git a/frontend/src/proprietary/components/shared/config/configNavSections.tsx b/frontend/src/proprietary/components/shared/config/configNavSections.tsx new file mode 100644 index 000000000..44b5e6330 --- /dev/null +++ b/frontend/src/proprietary/components/shared/config/configNavSections.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { createConfigNavSections as createCoreConfigNavSections, ConfigNavSection } from '@core/components/shared/config/configNavSections'; +import PeopleSection from '@proprietary/components/shared/config/configSections/PeopleSection'; +import TeamsSection from '@proprietary/components/shared/config/configSections/TeamsSection'; + +/** + * Proprietary extension of createConfigNavSections that adds workspace sections + */ +export const createConfigNavSections = ( + Overview: React.ComponentType<{ onLogoutClick: () => void }>, + onLogoutClick: () => void, + isAdmin: boolean = false, + runningEE: boolean = false +): ConfigNavSection[] => { + // Get the core sections + const sections = createCoreConfigNavSections(Overview, onLogoutClick, isAdmin, runningEE); + + // Add Workspace section after Preferences (index 1) + const workspaceSection: ConfigNavSection = { + title: 'Workspace', + items: [ + { + key: 'people', + label: 'People', + icon: 'group-rounded', + component: + }, + { + key: 'teams', + label: 'Teams', + icon: 'groups-rounded', + component: + }, + ], + }; + + // Insert workspace section after Preferences (at index 1) + sections.splice(1, 0, workspaceSection); + + return sections; +}; + +// Re-export types for convenience +export type { ConfigNavSection, ConfigNavItem, ConfigColors } from '@core/components/shared/config/configNavSections'; diff --git a/frontend/src/proprietary/components/shared/config/configSections/GeneralSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/GeneralSection.tsx new file mode 100644 index 000000000..e6ea63e1c --- /dev/null +++ b/frontend/src/proprietary/components/shared/config/configSections/GeneralSection.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Paper, Stack, Text, Button, Divider } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { useAuth } from '@app/auth/UseSession'; +import { useNavigate } from 'react-router-dom'; +import CoreGeneralSection from '@core/components/shared/config/configSections/GeneralSection'; + +/** + * Proprietary extension of GeneralSection that adds account management + */ +const GeneralSection: React.FC = () => { + const { t } = useTranslation(); + const { signOut, user } = useAuth(); + const navigate = useNavigate(); + + const handleLogout = async () => { + try { + await signOut(); + navigate('/login'); + } catch (error) { + console.error('Logout error:', error); + } + }; + + return ( + +
+
+ {t('settings.general.title', 'General')} + + {t('settings.general.description', 'Configure general application preferences.')} + +
+ + {user && ( + + + {t('settings.general.user', 'User')}: {user.email || user.username} + + + + )} +
+ + {/* Render core general section preferences (without title since we show it above) */} + +
+ ); +}; + +export default GeneralSection; diff --git a/frontend/src/core/components/shared/config/configSections/PeopleSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/PeopleSection.tsx similarity index 99% rename from frontend/src/core/components/shared/config/configSections/PeopleSection.tsx rename to frontend/src/proprietary/components/shared/config/configSections/PeopleSection.tsx index 1a5b8b722..e7095612d 100644 --- a/frontend/src/core/components/shared/config/configSections/PeopleSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/PeopleSection.tsx @@ -23,7 +23,7 @@ import { import LocalIcon from '@app/components/shared/LocalIcon'; import { alert } from '@app/components/toast'; import { userManagementService, User } from '@app/services/userManagementService'; -import { teamService, Team } from '@app/services/teamService'; +import { teamService, Team } from '@proprietary/services/teamService'; import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex'; import { useAppConfig } from '@app/contexts/AppConfigContext'; diff --git a/frontend/src/core/components/shared/config/configSections/TeamDetailsSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/TeamDetailsSection.tsx similarity index 99% rename from frontend/src/core/components/shared/config/configSections/TeamDetailsSection.tsx rename to frontend/src/proprietary/components/shared/config/configSections/TeamDetailsSection.tsx index dd6e14bef..8b5de13b1 100644 --- a/frontend/src/core/components/shared/config/configSections/TeamDetailsSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/TeamDetailsSection.tsx @@ -18,7 +18,7 @@ import { } from '@mantine/core'; import LocalIcon from '@app/components/shared/LocalIcon'; import { alert } from '@app/components/toast'; -import { teamService, Team } from '@app/services/teamService'; +import { teamService, Team } from '@proprietary/services/teamService'; import { User, userManagementService } from '@app/services/userManagementService'; import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex'; diff --git a/frontend/src/core/components/shared/config/configSections/TeamsSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/TeamsSection.tsx similarity index 98% rename from frontend/src/core/components/shared/config/configSections/TeamsSection.tsx rename to frontend/src/proprietary/components/shared/config/configSections/TeamsSection.tsx index bc932e4dc..d93dca9de 100644 --- a/frontend/src/core/components/shared/config/configSections/TeamsSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/TeamsSection.tsx @@ -19,10 +19,10 @@ import { } from '@mantine/core'; import LocalIcon from '@app/components/shared/LocalIcon'; import { alert } from '@app/components/toast'; -import { teamService, Team } from '@app/services/teamService'; +import { teamService, Team } from '@proprietary/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 TeamDetailsSection from '@proprietary/components/shared/config/configSections/TeamDetailsSection'; export default function TeamsSection() { const { t } = useTranslation(); diff --git a/frontend/src/core/services/teamService.ts b/frontend/src/proprietary/services/teamService.ts similarity index 100% rename from frontend/src/core/services/teamService.ts rename to frontend/src/proprietary/services/teamService.ts