From 77574594f2d652d9204f2aaef874a660bd16b197 Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Mon, 10 Mar 2025 19:02:40 +0530 Subject: [PATCH] admin panel fast follows (#10723) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fast follows: - https://discord.com/channels/1130383047699738754/1346433965451382845 - https://discord.com/channels/1130383047699738754/1346434512757981264 - https://discord.com/channels/1130383047699738754/1346453484911853610 --------- Co-authored-by: Félix Malfait --- .../modules/app/components/SettingsRoutes.tsx | 26 ++-- .../components/SettingsAdminContent.tsx | 9 ++ .../components/SettingsAdminEnvVariables.tsx | 96 ++++---------- .../components/SettingsAdminGeneral.tsx | 94 +++++++------- .../SettingsAdminVersionContainer.tsx | 118 ++++++++++++++++++ .../ConnectedAccountHealthStatus.tsx | 5 +- .../components/SettingsAdminHealthStatus.tsx | 6 +- .../SettingsHealthStatusListCard.tsx | 26 +++- .../components/WorkerHealthStatus.tsx | 3 +- .../components/WorkerMetricsGraph.tsx | 34 ++--- .../components/WorkerQueueMetricsSection.tsx | 3 +- .../utils/checkTwentyVersionExists.ts | 12 ++ .../utils/fetchLatestTwentyRelease.ts | 11 ++ .../settings/components/SettingsListCard.tsx | 7 +- .../SettingsListItemCardContent.tsx | 27 +++- .../hooks/useSettingsNavigationItems.tsx | 4 +- .../src/modules/types/SettingsPath.ts | 8 +- .../settings/admin-panel/SettingsAdmin.tsx | 6 +- .../SettingsAdminIndicatorHealthStatus.tsx | 46 ++++--- .../SettingsAdminSecondaryEnvVariables.tsx | 61 +++++++++ .../admin-panel/admin-panel.resolver.ts | 10 +- .../core-modules/health/health.module.ts | 2 - .../indicators/__tests__/app.health.spec.ts | 11 +- .../health/indicators/app.health.ts | 2 - .../__tests__/admin-panel-guard.spec.ts | 52 ++++++++ .../{ => __tests__}/impersonate-guard.spec.ts | 0 .../src/engine/guards/admin-panel-guard.ts | 15 +++ .../display/icon/components/TablerIcons.ts | 5 + .../navigation/link/components/ActionLink.tsx | 9 +- 29 files changed, 496 insertions(+), 212 deletions(-) create mode 100644 packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminVersionContainer.tsx create mode 100644 packages/twenty-front/src/modules/settings/admin-panel/utils/checkTwentyVersionExists.ts create mode 100644 packages/twenty-front/src/modules/settings/admin-panel/utils/fetchLatestTwentyRelease.ts create mode 100644 packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminSecondaryEnvVariables.tsx create mode 100644 packages/twenty-server/src/engine/guards/__tests__/admin-panel-guard.spec.ts rename packages/twenty-server/src/engine/guards/{ => __tests__}/impersonate-guard.spec.ts (100%) create mode 100644 packages/twenty-server/src/engine/guards/admin-panel-guard.ts diff --git a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx index 0e72485df..5b36573bc 100644 --- a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx +++ b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx @@ -274,14 +274,6 @@ const SettingsAdmin = lazy(() => })), ); -const SettingsAdminContent = lazy(() => - import('@/settings/admin-panel/components/SettingsAdminContent').then( - (module) => ({ - default: module.SettingsAdminContent, - }), - ), -); - const SettingsAdminIndicatorHealthStatus = lazy(() => import( '~/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus' @@ -290,6 +282,14 @@ const SettingsAdminIndicatorHealthStatus = lazy(() => })), ); +const SettingsAdminSecondaryEnvVariables = lazy(() => + import( + '~/pages/settings/admin-panel/SettingsAdminSecondaryEnvVariables' + ).then((module) => ({ + default: module.SettingsAdminSecondaryEnvVariables, + })), +); + const SettingsLab = lazy(() => import('~/pages/settings/lab/SettingsLab').then((module) => ({ default: module.SettingsLab, @@ -482,14 +482,14 @@ export const SettingsRoutes = ({ {isAdminPageEnabled && ( <> - } /> + } /> } + path={SettingsPath.AdminPanelIndicatorHealthStatus} + element={} /> } + path={SettingsPath.AdminPanelOtherEnvVariables} + element={} /> )} diff --git a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminContent.tsx b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminContent.tsx index 8c7b174df..998a9d0a5 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminContent.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminContent.tsx @@ -1,9 +1,11 @@ +import { currentUserState } from '@/auth/states/currentUserState'; import { SettingsAdminTabContent } from '@/settings/admin-panel/components/SettingsAdminTabContent'; import { SETTINGS_ADMIN_TABS } from '@/settings/admin-panel/constants/SettingsAdminTabs'; import { SETTINGS_ADMIN_TABS_ID } from '@/settings/admin-panel/constants/SettingsAdminTabsId'; import { TabList } from '@/ui/layout/tab/components/TabList'; import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; +import { useRecoilValue } from 'recoil'; import { IconHeart, IconSettings2, IconVariable } from 'twenty-ui'; const StyledTabListContainer = styled.div` @@ -15,21 +17,28 @@ const StyledTabListContainer = styled.div` `; export const SettingsAdminContent = () => { + const currentUser = useRecoilValue(currentUserState); + + const canAccessFullAdminPanel = currentUser?.canAccessFullAdminPanel; + const canImpersonate = currentUser?.canImpersonate; const tabs = [ { id: SETTINGS_ADMIN_TABS.GENERAL, title: t`General`, Icon: IconSettings2, + disabled: !canAccessFullAdminPanel && !canImpersonate, }, { id: SETTINGS_ADMIN_TABS.ENV_VARIABLES, title: t`Env Variables`, Icon: IconVariable, + disabled: !canAccessFullAdminPanel, }, { id: SETTINGS_ADMIN_TABS.HEALTH_STATUS, title: t`Health Status`, Icon: IconHeart, + disabled: !canAccessFullAdminPanel, }, ]; diff --git a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminEnvVariables.tsx b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminEnvVariables.tsx index 2856ce0e0..206e33f39 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminEnvVariables.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminEnvVariables.tsx @@ -1,60 +1,35 @@ import { SettingsAdminEnvVariablesTable } from '@/settings/admin-panel/components/SettingsAdminEnvVariablesTable'; import { SettingsAdminTabSkeletonLoader } from '@/settings/admin-panel/components/SettingsAdminTabSkeletonLoader'; +import { SettingsListItemCardContent } from '@/settings/components/SettingsListItemCardContent'; +import { SettingsPath } from '@/types/SettingsPath'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useState } from 'react'; -import { Button, H1Title, H1TitleFontColor, H2Title, Section } from 'twenty-ui'; +import { t } from '@lingui/core/macro'; + +import { Card, H2Title, IconHeartRateMonitor, Section } from 'twenty-ui'; import { useGetEnvironmentVariablesGroupedQuery } from '~/generated/graphql'; +import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; const StyledGroupContainer = styled.div` margin-bottom: ${({ theme }) => theme.spacing(6)}; `; -const StyledGroupDescription = styled.div` - margin-bottom: ${({ theme }) => theme.spacing(4)}; -`; - -const StyledButtonsRow = styled.div` - display: flex; - flex-wrap: wrap; - gap: ${({ theme }) => theme.spacing(2)}; - margin-bottom: ${({ theme }) => theme.spacing(6)}; -`; - -const StyledShowMoreButton = styled(Button)<{ isSelected?: boolean }>` - ${({ isSelected, theme }) => - isSelected && - ` - background-color: ${theme.background.transparent.light}; - `} +const StyledInfoText = styled.div` + color: ${({ theme }) => theme.font.color.secondary}; `; export const SettingsAdminEnvVariables = () => { + const theme = useTheme(); const { data: environmentVariables, loading: environmentVariablesLoading } = useGetEnvironmentVariablesGroupedQuery({ fetchPolicy: 'network-only', }); - const [selectedGroup, setSelectedGroup] = useState(null); - - const toggleGroupVisibility = (groupName: string) => { - setSelectedGroup(selectedGroup === groupName ? null : groupName); - }; - - const hiddenGroups = - environmentVariables?.getEnvironmentVariablesGrouped.groups.filter( - (group) => group.isHiddenOnLoad, - ) ?? []; - const visibleGroups = environmentVariables?.getEnvironmentVariablesGrouped.groups.filter( (group) => !group.isHiddenOnLoad, ) ?? []; - const selectedGroupData = - environmentVariables?.getEnvironmentVariablesGrouped.groups.find( - (group) => group.name === selectedGroup, - ); - if (environmentVariablesLoading) { return ; } @@ -62,9 +37,11 @@ export const SettingsAdminEnvVariables = () => { return ( <>
- These are only the server values. Ensure your worker environment has the + + {t` These are only the server values. Ensure your worker environment has the same variables and values, this is required for asynchronous tasks like - email sync. + email sync.`} +
{visibleGroups.map((group) => ( @@ -76,42 +53,15 @@ export const SettingsAdminEnvVariables = () => { ))} - {hiddenGroups.length > 0 && ( - <> - - {hiddenGroups.map((group) => ( - toggleGroupVisibility(group.name)} - title={group.name} - variant="secondary" - isSelected={selectedGroup === group.name} - > - {group.name} variables - - ))} - - - {selectedGroupData && ( - - - {selectedGroupData.description !== '' && ( - - {selectedGroupData.description} - - )} - {selectedGroupData.variables.length > 0 && ( - - )} - - )} - - )} + + +
); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx index 6c422e1ed..f50cfaf90 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx @@ -16,7 +16,6 @@ import { useRecoilState, useRecoilValue } from 'recoil'; import { getImageAbsoluteURI, isDefined } from 'twenty-shared'; import { Button, - GithubVersionLink, H1Title, H1TitleFontColor, H2Title, @@ -27,7 +26,7 @@ import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { useUserLookupAdminPanelMutation } from '~/generated/graphql'; import { currentUserState } from '@/auth/states/currentUserState'; -import packageJson from '../../../../../package.json'; +import { SettingsAdminVersionContainer } from '@/settings/admin-panel/components/SettingsAdminVersionContainer'; const StyledContainer = styled.div` align-items: center; @@ -54,11 +53,6 @@ const StyledContentContainer = styled.div` padding: ${({ theme }) => theme.spacing(4)} 0; `; -const StyledErrorMessage = styled.div` - color: ${({ theme }) => theme.color.red}; - margin-top: ${({ theme }) => theme.spacing(2)}; -`; - export const SettingsAdminGeneral = () => { const [userIdentifier, setUserIdentifier] = useState(''); const { enqueueSnackBar } = useSnackBar(); @@ -75,6 +69,8 @@ export const SettingsAdminGeneral = () => { const currentUser = useRecoilValue(currentUserState); + const canAccessFullAdminPanel = currentUser?.canAccessFullAdminPanel; + const canImpersonate = currentUser?.canImpersonate; const canManageFeatureFlags = useRecoilValue(canManageFeatureFlagsState); @@ -130,51 +126,51 @@ export const SettingsAdminGeneral = () => { return ( <> -
- - -
- -
- - - - + -
+ )} + + {canImpersonate && ( +
+ - - {!canImpersonate && ( - - {t`You do not have access to impersonate users.`} - - )} -
+ + + +