Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module.exports = {
rules: {
'react-refresh/only-export-components': 'warn',
'react/react-in-jsx-scope': 0,
'react-refresh/only-export-components': 0,
'react-hooks/exhaustive-deps': 0,
},
settings: {
react: {
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"@mantine/notifications": "^6.0.11",
"@mantine/prism": "^6.0.11",
"@tabler/icons-react": "^2.20.0",
"@tanstack/react-query": "^4.29.7",
"axios": "^1.4.0",
"dayjs": "^1.11.7",
"http-status-codes": "^2.2.0",
Expand Down
33 changes: 0 additions & 33 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/@types/parseable/api/stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type LogStreamData = Array<{ name: string }>;
2 changes: 1 addition & 1 deletion src/api/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const API_V1 = 'api/v1';

export const HEALTH_LIVENESS_QUERY_KEY = 'health_liveness';
export const HEALTH_LIVENESS_URL = `${API_V1}/liveness`;
export const LOG_STREAM_LIST_URL = `${API_V1}/logstream`;
7 changes: 7 additions & 0 deletions src/api/logStream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Axios } from './axios';
import { LOG_STREAM_LIST_URL } from './constants';
import { LogStreamData } from '@/@types/parseable/api/stream';

export const getLogStreamList = () => {
return Axios().get<LogStreamData>(LOG_STREAM_LIST_URL);
};
101 changes: 101 additions & 0 deletions src/components/Empty/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import type { CenterProps, TextProps } from '@mantine/core';
import { Center, Text } from '@mantine/core';
import type { FC } from 'react';
import { useEmptyStyles } from './styles';

type EmptyProps = {
height?: number | string;
width?: number | string;
};

export const Empty: FC<EmptyProps> = ({ height, width }) => {
return (
<svg height={height} width={width} viewBox="0 0 184 152" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<g transform="translate(24 31.67)">
<ellipse fill="#f5f5f5" cx="67.797" cy="106.89" rx="67.797" ry="12.668" />
<path
fill="#aeb8c2"
d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
/>
<path
fill="#fff"
d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z"
transform="translate(13.56)"
/>
<path
fill="#f5f5f7"
d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
/>
<path
fill="#dce0e6"
d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
/>
</g>
<path
fill="#dce0e6"
d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
/>
<g fill="#fff" transform="translate(149.65 15.383)">
<ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" />
<path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" />
</g>
</g>
</svg>
);
};

export const EmptySimple: FC<EmptyProps> = ({ height, width }) => {
return (
<svg height={height} width={width} viewBox="0 0 64 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M32 41C49.6731 41 64 37.866 64 34C64 30.134 49.6731 27 32 27C14.3269 27 0 30.134 0 34C0 37.866 14.3269 41 32 41Z"
fill="#F5F5F5"
/>
<path
d="M55 13.76L44.854 2.258C44.367 1.474 43.656 1 42.907 1H21.093C20.344 1 19.633 1.474 19.146 2.257L9 13.761V23H55V13.76Z"
fill="white"
stroke="#D9D9D9"
/>
<path
d="M41.613 16.931C41.613 15.326 42.607 14.001 43.84 14H55V32.137C55 34.26 53.68 36 52.05 36H11.95C10.32 36 9 34.259 9 32.137V14H20.16C21.393 14 22.387 15.323 22.387 16.928V16.95C22.387 18.555 23.392 19.851 24.624 19.851H39.376C40.608 19.851 41.613 18.543 41.613 16.938V16.931V16.931Z"
fill="#FAFAFA"
stroke="#D9D9D9"
/>
</svg>
);
};

type EmptyBoxProps = {
imgHeight?: number | string;
imgWidth?: number | string;
message?: string;
textProps?: TextProps;
} & Omit<CenterProps, 'children'>;

const EmptyBox: FC<EmptyBoxProps> = (props) => {
const { message, imgHeight, imgWidth, textProps, ...restProps } = props;
const { classes } = useEmptyStyles();
const { container, messageStyle } = classes;

return (
<Center className={container} {...restProps}>
<EmptySimple height={imgHeight || 70} width={imgWidth || 100} />
<Text className={messageStyle} {...textProps}>
{message || 'No Data'}
</Text>
</Center>
);
};

EmptySimple.defaultProps = {
width: 64,
height: 41,
};

Empty.defaultProps = {
width: 184,
height: 152,
};

export default EmptyBox;
21 changes: 21 additions & 0 deletions src/components/Empty/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createStyles } from '@mantine/core';

export const useEmptyStyles = createStyles((theme) => {
const { colors, spacing } = theme;

return {
container: {
height: '100%',
width: '100%',
paddingTop: spacing.xl,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
},

messageStyle: {
marginTop: spacing.md,
color: colors.dimmed[0],
},
};
});
11 changes: 5 additions & 6 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import slackLogo from '@/assets/images/slack-logo.webp';
import { HOME_ROUTE, LOGIN_ROUTE } from '@/constants/routes';
import { HEADER_HEIGHT } from '@/constants/theme';
import type { BoxProps, HeaderProps as MantineHeaderProps, UnstyledButtonProps } from '@mantine/core';
import { Anchor, Box, Card, Image, Header as MantineHeader, Text, UnstyledButton } from '@mantine/core';
import { Anchor, Box, Card, Image, Header as MantineHeader, Text, UnstyledButton, Modal, px } from '@mantine/core';
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
import { IconHelpCircle, IconLogout, IconUser } from '@tabler/icons-react';
import { FC, Fragment } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useHeaderStyles } from './styles';
import Modal from '../Modal';

type HeaderProps = Omit<MantineHeaderProps, 'children' | 'height' | 'className'>;

Expand Down Expand Up @@ -63,12 +62,12 @@ const Help: FC<UnstyledButtonProps> = (props) => {
return (
<Fragment>
<UnstyledButton {...props} className={actionBtn} onClick={open} color="brandSecondary.1" variant="filled">
<IconHelpCircle size="1.1rem" className={actionBtnIcon} />
<IconHelpCircle size={px('1.1rem')} className={actionBtnIcon} />
<Text ml="xs" className={actionBtnText}>
Help
</Text>
</UnstyledButton>
<Modal opened={opened} onClose={close} withCloseButton={false} size="sm" centered>
<Modal withinPortal opened={opened} onClose={close} withCloseButton={false} size="sm" centered>
<Text className={helpTitle}>Need any help?</Text>
<Text className={helpDescription}>Here you can find useful resources and information.</Text>
<Box>
Expand Down Expand Up @@ -112,7 +111,7 @@ const User: FC<BoxProps> = (props) => {

return (
<Box className={userContainer} {...props}>
<IconUser size="1.1rem" className={userIcon} />
<IconUser size={px('1.1rem')} className={userIcon} />
<Text ml="xs" className={userText}>
{username}
</Text>
Expand Down Expand Up @@ -141,7 +140,7 @@ const SignOut: FC<UnstyledButtonProps> = (props) => {

return (
<UnstyledButton {...props} onClick={onSignOut} className={actionBtn}>
<IconLogout size="1.2rem" className={actionBtnIcon} />
<IconLogout size={px('1.2rem')} className={actionBtnIcon} />
</UnstyledButton>
);
};
Expand Down
23 changes: 22 additions & 1 deletion src/components/Mantine/theme.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CSSObject, MantineThemeOverride } from '@mantine/core';
import type { CSSObject, MantineTheme, MantineThemeOverride } from '@mantine/core';
import { heights, widths, sizing } from './sizing';

const globalStyles = (): CSSObject => {
Expand Down Expand Up @@ -40,4 +40,25 @@ export const theme: MantineThemeOverride = {
black: 900,
},
},
components: {
Modal: {
defaultProps: ({ colors }: MantineTheme) => ({
withinPortal: true,
overlayProps: {
color: colors.gray[3],
opacity: 0.55,
blur: 3,
},
}),
},
Highlight: {
defaultProps: ({ colors, other }: MantineTheme) => ({
highlightStyles: {
color: colors.dark,
background: colors.yellow[3],
fontWeight: other.fontWeights.bold,
},
}),
},
},
};
23 changes: 0 additions & 23 deletions src/components/Modal/index.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LOGS_ROUTE } from '@/constants/routes';
import useMountedState from '@/hooks/useMountedState';
import type { NavbarProps as MantineNavbarProps } from '@mantine/core';
import { Navbar as MantineNavbar, Tooltip, UnstyledButton } from '@mantine/core';
import { Navbar as MantineNavbar, Tooltip, UnstyledButton, px } from '@mantine/core';
import { IconFileReport } from '@tabler/icons-react';
import type { FC } from 'react';
import { useNavbarStyles } from './styles';
Expand Down Expand Up @@ -62,7 +62,7 @@ const NavbarLink: FC<NavbarLinkProps> = (props) => {
return (
<Tooltip label={link.label} position="right" withArrow transitionProps={{ duration: 0 }} key={link.label}>
<UnstyledButton onClick={setActive} className={cx(linkBtnStyle, { [linkBtnActiveStyle]: isActive })}>
<link.icon size="1.4rem" stroke={1.7} />
<link.icon size={px('1.4rem')} stroke={1.7} />
</UnstyledButton>
</Tooltip>
);
Expand Down
16 changes: 16 additions & 0 deletions src/components/Text/ErrorText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { TextProps } from '@mantine/core';
import { Text } from '@mantine/core';
import type { FC } from 'react';

const ErrorText: FC<TextProps> = (props) => {
return (
<Text
{...props}
sx={({ colors }) => ({
color: colors.error[0],
})}
/>
);
};

export default ErrorText;
2 changes: 2 additions & 0 deletions src/constants/theme.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const HEADER_HEIGHT = 50;
export const NAVBAR_WIDTH = 60;
export const APP_MIN_WIDTH = 650;
40 changes: 40 additions & 0 deletions src/hooks/useGetLogStreamList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { LogStreamData } from '@/@types/parseable/api/stream';

import { getLogStreamList } from '@/api/logStream';
import { StatusCodes } from 'http-status-codes';
import { useEffect } from 'react';
import useMountedState from './useMountedState';

export const useGetLogStreamList = () => {
const [data, setData] = useMountedState<LogStreamData | null>(null);
const [error, setError] = useMountedState<string | null>(null);
const [loading, setLoading] = useMountedState<boolean>(false);

const getData = async () => {
try {
setLoading(true);
setError(null);
const res = await getLogStreamList();

switch (res.status) {
case StatusCodes.OK: {
const streams = res.data;

setData(streams);
break;
}
default: {
setError('Something went wrong!.');
}
}
} finally {
setLoading(false);
}
};

useEffect(() => {
getData();
}, []);

return { data, error, loading };
};
Loading