diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index f35663c3..e1b3bea3 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -1,11 +1,11 @@ -import { Box, Stack, Tooltip } from '@mantine/core'; +import { Box, Divider, Stack, Tooltip } from '@mantine/core'; import { IconLogout, IconUser, IconBinaryTree2, IconInfoCircle, IconUserCog, IconHome, IconServerCog } from '@tabler/icons-react'; import { FC, useCallback, useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import { useNavigate } from 'react-router-dom'; import { useHeaderContext } from '@/layouts/MainLayout/Context'; import { useDisclosure } from '@mantine/hooks'; -import { HOME_ROUTE, LOGS_ROUTE, SYSTEMS_ROUTE, USERS_MANAGEMENT_ROUTE } from '@/constants/routes'; +import { HOME_ROUTE, LOGS_ROUTE, CLUSTER_ROUTE, USERS_MANAGEMENT_ROUTE } from '@/constants/routes'; import InfoModal from './infoModal'; import { getStreamsSepcificAccess, getUserSepcificStreams } from './rolesHandler'; import Cookies from 'js-cookie'; @@ -30,6 +30,9 @@ const navItems = [ path: '/logs', route: LOGS_ROUTE, }, +]; + +const previlagedActions = [ { icon: IconUserCog, label: 'Users', @@ -38,11 +41,11 @@ const navItems = [ }, { icon: IconServerCog, - label: 'Systems', - path: '/systems', - route: SYSTEMS_ROUTE, + label: 'Cluster', + path: '/cluster', + route: CLUSTER_ROUTE, } -]; +] const navActions = [ { @@ -138,7 +141,24 @@ const Navbar: FC = () => {
{navItems.map((navItem, index) => { + const isActiveItem = navItem.route === currentRoute; + return ( + navigateToPage(navItem.route)} + key={index}> + + + + + ); + })} + + + {previlagedActions.map((navItem, index) => { if (navItem.route === USERS_MANAGEMENT_ROUTE && !userSpecificAccessMap.hasUserAccess) return null; + if (navItem.route === CLUSTER_ROUTE && !userSpecificAccessMap.hasUserAccess) return null; const isActiveItem = navItem.route === currentRoute; return ( @@ -153,8 +173,7 @@ const Navbar: FC = () => { ); })} - - + {navActions.map((navAction, index) => { const isActiveItem = false; const onClick = diff --git a/src/components/Navbar/rolesHandler.ts b/src/components/Navbar/rolesHandler.ts index 11fd85c9..b6008711 100644 --- a/src/components/Navbar/rolesHandler.ts +++ b/src/components/Navbar/rolesHandler.ts @@ -18,6 +18,7 @@ const adminAccess = [ 'DeleteUser', 'PutRoles', 'GetRole', + 'Cluster' ]; const editorAccess = [ 'Ingest', diff --git a/src/constants/routes.ts b/src/constants/routes.ts index b5bae604..4eb25835 100644 --- a/src/constants/routes.ts +++ b/src/constants/routes.ts @@ -7,7 +7,7 @@ export const STATS_ROUTE = '/:streamName/stats'; export const CONFIG_ROUTE = '/:streamName/config'; export const USERS_MANAGEMENT_ROUTE = '/users'; export const OIDC_NOT_CONFIGURED_ROUTE = '/oidc-not-configured'; -export const SYSTEMS_ROUTE = '/systems'; +export const CLUSTER_ROUTE = '/cluster'; export const PATHS = { all: '/*', @@ -19,5 +19,5 @@ export const PATHS = { config: '/:streamName/config', users: '/users', oidcNotConfigured: '/oidc-not-configured', - systems: '/systems', + cluster: '/cluster', } as { [key: string]: string }; diff --git a/src/layouts/MainLayout/Context.tsx b/src/layouts/MainLayout/Context.tsx index 2026fdf3..90e7cb5d 100644 --- a/src/layouts/MainLayout/Context.tsx +++ b/src/layouts/MainLayout/Context.tsx @@ -86,7 +86,8 @@ const accessKeyMap: { [key: string]: string } = { hasDeleteAccess: 'DeleteStream', hasUpdateAlertAccess: 'PutAlert', hasGetAlertAccess: 'GetAlert', - hasCreateStreamAccess: 'CreateStream' + hasCreateStreamAccess: 'CreateStream', + hasClusterAccess: 'Cluster' }; const generateUserAcccessMap = (accessRoles: string[] | null) => { diff --git a/src/pages/Logs/EventTimeLineGraph.tsx b/src/pages/Logs/EventTimeLineGraph.tsx index b0a75f4c..f50800eb 100644 --- a/src/pages/Logs/EventTimeLineGraph.tsx +++ b/src/pages/Logs/EventTimeLineGraph.tsx @@ -42,7 +42,6 @@ const calcAverage = (data: GraphRecord[]) => { const getAllTimestamps = (startTime: Dayjs) => { const timestamps = []; for (let i = 0; i < START_RANGE; i++) { - // Your code to be executed 30 times goes here const ts = startTime.add(i + 1, 'minute') timestamps.push(ts.toISOString().split('.')[0]+"Z") } @@ -87,7 +86,7 @@ function ChartTooltip({ payload }: ChartTooltipProps) { const { minute, aboveAvgPercent } = payload[0]?.payload || {}; const isAboveAvg = aboveAvgPercent > 0; const startTime = dayjs(minute).utc(true); - const endTime = dayjs(minute).add(59, 'seconds'); + const endTime = dayjs(minute).add(60, 'seconds'); return ( @@ -154,7 +153,7 @@ const EventTimeLineGraph = () => { const { minute } = samplePayload.payload || {}; const startTime = dayjs(minute); - const endTime = dayjs(minute).add(59, 'seconds'); + const endTime = dayjs(minute).add(60, 'seconds'); subLogQuery.set((query) => { query.startTime = startTime.toDate(); query.endTime = endTime.toDate(); diff --git a/src/pages/Logs/LogTable.tsx b/src/pages/Logs/LogTable.tsx index e97b7c32..39775a29 100644 --- a/src/pages/Logs/LogTable.tsx +++ b/src/pages/Logs/LogTable.tsx @@ -400,7 +400,7 @@ const LogTable: FC = () => { ? PRIMARY_HEADER_HEIGHT + LOGS_PRIMARY_TOOLBAR_HEIGHT + LOGS_SECONDARY_TOOLBAR_HEIGHT : 0; - const totalCount = Array.isArray(fetchQueryMutation?.data) ? fetchQueryMutation.data[0]?.count : null; + const totalCount = Array.isArray(fetchQueryMutation?.data) ? fetchQueryMutation.data[0]?.["COUNT(*)"] : null; const loadedCount = pageLogData?.data.length || null; return ( ( ); function sanitizeIngestorUrl(url: string) { - if (url.startsWith("http://")) { - url = url.slice(7); - } else if (url.startsWith("https://")) { - url = url.slice(8); - } - - if (url.endsWith("/")) { - url = url.slice(0, -1); - } - - return url; + if (url.startsWith('http://')) { + url = url.slice(7); + } else if (url.startsWith('https://')) { + url = url.slice(8); + } + + if (url.endsWith('/')) { + url = url.slice(0, -1); + } + + return url; } const TableRow = (props: IngestorTableRow) => { const { ingestor, metrics } = props; const isOfflineIngestor = !ingestor.reachable; const { deleteIngestorMutation, deleteIngestorIsLoading } = useDeleteIngestor(); - const {getClusterInfoRefetch} = useClusterInfo() + const { getClusterInfoRefetch } = useClusterInfo(); return ( - + {ingestor.domain_name} {!ingestor.reachable && ( @@ -54,27 +54,43 @@ const TableRow = (props: IngestorTableRow) => { ) : ( <> - + {isOfflineIngestor ? '–' : HumanizeNumber(metrics?.parseable_events_ingested || 0)} + + + + {isOfflineIngestor ? '–' : formatBytes(metrics?.parseable_storage_size.data || 0)} + + + + + {ingestor.storage_path || 'Unknown'} + - - {isOfflineIngestor ? '–' : formatBytes(metrics?.parseable_storage_size.data || 0)} + + + {isOfflineIngestor ? '–' : HumanizeNumber(metrics?.parseable_staging_files || 0)} + - - {isOfflineIngestor ? '–' : formatBytes(metrics?.process_resident_memory_bytes || 0)} + + + {isOfflineIngestor ? '–' : formatBytes(metrics?.parseable_storage_size.staging || 0)} + - - {isOfflineIngestor ? '–' : HumanizeNumber(metrics?.parseable_staging_files || 0)} + + + {ingestor.staging_path || 'Unknown'} + - - {isOfflineIngestor ? '–' : formatBytes(metrics?.parseable_storage_size.staging || 0)} + + + {isOfflineIngestor ? '–' : formatBytes(metrics?.process_resident_memory_bytes || 0)} + - {ingestor.staging_path || 'Unknown'} - {ingestor.storage_path || 'Unknown'} )} @@ -84,7 +100,13 @@ const TableRow = (props: IngestorTableRow) => { {!ingestor.reachable ? ( - deleteIngestorMutation({ ingestorUrl: sanitizeIngestorUrl(ingestor.domain_name), onSuccess: getClusterInfoRefetch })}> + + deleteIngestorMutation({ + ingestorUrl: sanitizeIngestorUrl(ingestor.domain_name), + onSuccess: getClusterInfoRefetch, + }) + }> {deleteIngestorIsLoading ? ( ) : ( @@ -107,14 +129,36 @@ type IngestorTable = { const TableHead = () => ( - Domain - Events Ingested - Storage - Memory Usage - Staging Files - Staging Size - Staging Path - Storage Path + Domain + + Events Ingested + + + S3 + + + Size + + + Path + + + + + Staging + + + Files + + + Size + + + Path + + + + Memory Usage Status @@ -126,7 +170,7 @@ const IngestorsTable = (props: IngestorTable) => { if (!ingestors || !allMetrics) return null; return ( - +
{ingestors.map((ingestor) => { @@ -151,8 +195,8 @@ const Ingestors: FC = () => { const totalActiveMachines = clusterInfoData?.data.filter((ingestor) => ingestor.reachable).length; const totalMachines = clusterInfoData?.data.length; return ( - - + + Ingestors diff --git a/src/pages/Systems/styles/Systems.module.css b/src/pages/Systems/styles/Systems.module.css index 2da641ef..f2038502 100644 --- a/src/pages/Systems/styles/Systems.module.css +++ b/src/pages/Systems/styles/Systems.module.css @@ -105,4 +105,14 @@ .infoText { font-size: 0.875rem; /* font-weight: 600; */ +} + +.cellTitle { + font-size: 14px; + font-weight: 600; + padding: 0.5rem 1.25rem; +} + +.cellText { + font-size: 14px; } \ No newline at end of file diff --git a/src/routes/index.tsx b/src/routes/index.tsx index e3a81639..437599ff 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -5,7 +5,7 @@ import { LOGS_ROUTE, OIDC_NOT_CONFIGURED_ROUTE, USERS_MANAGEMENT_ROUTE, - SYSTEMS_ROUTE + CLUSTER_ROUTE } from '@/constants/routes'; import FullPageLayout from '@/layouts/FullPageLayout'; import NotFound from '@/pages/Errors/NotFound'; @@ -29,7 +29,9 @@ const AppRouter: FC = () => { }> } /> - } /> + }> + } /> + } />