Skip to content

Commit

Permalink
Merge pull request #64 from KSJaay/0.7.2
Browse files Browse the repository at this point in the history
0.7.2 - Cleans up codebase, adds support for cloning and pausing monitors
  • Loading branch information
KSJaay authored Dec 24, 2024
2 parents 7a674bf + 8f5af35 commit fdca745
Show file tree
Hide file tree
Showing 33 changed files with 494 additions and 179 deletions.
5 changes: 4 additions & 1 deletion app/components/home/monitor/layout/card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ const MonitorCard = ({ monitor = {} }) => {
<div>{uptimePercentage}%</div>
</div>
</div>
<div className="home-monitor-status">
<div
className="home-monitor-status"
style={{ filter: `grayscale(${monitor.paused ? 0.75 : 0})` }}
>
<h1>Status</h1>
<StatusBar heartbeats={heartbeats} />
</div>
Expand Down
6 changes: 6 additions & 0 deletions app/components/icons/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
FaPlus,
FaSignOutAlt,
FaUsers,
FaClone,
} from 'react-icons/fa';
import { FiLayout } from 'react-icons/fi';
import { HiStatusOffline, HiStatusOnline } from 'react-icons/hi';
Expand All @@ -23,6 +24,8 @@ import {
FaBars,
FaTrashCan,
FaFilter,
FaPause,
FaPlay,
} from 'react-icons/fa6';
import { IoArrowBack, IoColorPalette, IoGrid, IoReload } from 'react-icons/io5';
import { RiStackFill } from 'react-icons/ri';
Expand All @@ -37,10 +40,13 @@ export {
FaChevronRight,
FaChevronUp,
FaCircleCheck,
FaClone,
FaCog,
FaEllipsisVertical,
FaFilter,
FaHome,
FaPause,
FaPlay,
FaPlus,
FaSignOutAlt,
FaTrashCan,
Expand Down
35 changes: 24 additions & 11 deletions app/components/monitor/graph/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,40 @@ import {
ResponsiveContainer,
} from 'recharts';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

// import local files
import useLocalStorageContext from '../../../hooks/useLocalstorage';
import GraphMenu from './menu';
import useGraphStatus from '../../../hooks/useGraphStatus';
import { fullMonitorPropType } from '../../../../shared/utils/propTypes';

dayjs.extend(timezone);
dayjs.extend(utc);

const MonitorGraph = ({ monitor }) => {
const { dateformat, timeformat, theme } = useLocalStorageContext();
const { dateformat, timeformat, theme, timezone } = useLocalStorageContext();

const { statusType, statusHeartbeats, setStatusType } =
useGraphStatus(monitor);

const data = statusHeartbeats.map((heartbeat = {}) => {
return {
Latency: heartbeat.latency,
time: dayjs(heartbeat.date).format(timeformat),
};
});
const data = statusHeartbeats
.map(({ latency = 0, date = 0 } = {}) => {
return { Latency: latency, time: date };
})
.reverse();

const gridColor =
theme.type === 'light' ? 'rgba(0,0,0,0.1)' : 'rgba(255,255,255,0.1)';

return (
<div className="monitor-chart-container">
<GraphMenu statusType={statusType} setStatusType={setStatusType} />
<GraphMenu
statusType={statusType}
setStatusType={setStatusType}
showFilters={monitor.showFilters}
/>
<div className="monitor-chart-content">
<ResponsiveContainer>
<AreaChart data={data}>
Expand All @@ -45,6 +53,9 @@ const MonitorGraph = ({ monitor }) => {
dataKey="time"
style={{ fill: 'var(--accent-200)' }}
tick={{ fontSize: 12 }}
tickFormatter={(value) => {
return dayjs(value).tz(timezone).format(timeformat);
}}
/>
<YAxis
label={{
Expand All @@ -58,9 +69,11 @@ const MonitorGraph = ({ monitor }) => {
<CartesianGrid vertical={false} stroke={gridColor} />
<Tooltip
formatter={(value) => `${value} ms`}
labelFormatter={(value) =>
dayjs(value).format(`${dateformat} - ${timeformat}`)
}
labelFormatter={(value) => {
return dayjs(value)
.tz(timezone)
.format(`${dateformat} - ${timeformat}`);
}}
separator=": "
contentStyle={{
backgroundColor: 'var(--accent-800)',
Expand Down
31 changes: 18 additions & 13 deletions app/components/monitor/graph/menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Dropdown from '../../ui/dropdown';
import useDropdown from '../../../hooks/useDropdown';
import { FaEllipsisVertical } from '../../icons';

const GraphMenu = ({ statusType, setStatusType }) => {
const GraphMenu = ({ statusType, setStatusType, showFilters }) => {
const { dropdownIsOpen, toggleDropdown } = useDropdown();

return (
Expand All @@ -25,18 +25,22 @@ const GraphMenu = ({ statusType, setStatusType }) => {
>
1 Day
</Button>
<Button
color={statusType === 'week' ? 'primary' : null}
onClick={() => setStatusType('week')}
>
1 Week
</Button>
<Button
color={statusType === 'month' ? 'primary' : null}
onClick={() => setStatusType('month')}
>
1 Month
</Button>
{showFilters ? (
<>
<Button
color={statusType === 'week' ? 'primary' : null}
onClick={() => setStatusType('week')}
>
1 Week
</Button>
<Button
color={statusType === 'month' ? 'primary' : null}
onClick={() => setStatusType('month')}
>
1 Month
</Button>
</>
) : null}
</div>

<div className="monitor-chart-dropdown-container">
Expand Down Expand Up @@ -96,6 +100,7 @@ GraphMenu.displayName = 'GraphMenu';
GraphMenu.propTypes = {
statusType: PropTypes.string.isRequired,
setStatusType: PropTypes.func.isRequired,
showFilters: PropTypes.bool.isRequired,
};

export default GraphMenu;
118 changes: 100 additions & 18 deletions app/components/monitor/menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,23 @@ import { useNavigate } from 'react-router-dom';
import Button from '../ui/button';
import useContextStore from '../../context';
import MonitorModal from '../modal/monitor/delete';
import { createGetRequest } from '../../services/axios';
import { createGetRequest, createPostRequest } from '../../services/axios';
import MonitorConfigureModal from '../modal/monitor/configure';
import { FaTrashCan, MdEdit } from '../icons';
import { FaClone, FaEllipsisVertical, FaTrashCan, MdEdit } from '../icons';
import { FaPlay, FaPause } from '../icons';
import Dropdown from '../ui/dropdown';
import useDropdown from '../../hooks/useDropdown';

const MonitorMenu = ({ name = 'Unknown', monitorId }) => {
const {
modalStore: { openModal, closeModal },
globalStore: { getMonitor, editMonitor, removeMonitor },
globalStore: { addMonitor, getMonitor, editMonitor, removeMonitor },
userStore: { user },
} = useContextStore();
const { toggleDropdown, dropdownIsOpen } = useDropdown();
const navigate = useNavigate();

const monitor = getMonitor(monitorId);
const isEditor = user.permission <= 3;

const handleConfirm = async () => {
Expand All @@ -37,9 +42,38 @@ const MonitorMenu = ({ name = 'Unknown', monitorId }) => {
navigate('/');
};

const handleEdit = () => {
const monitor = getMonitor(monitorId);
const handlePause = async () => {
try {
await createPostRequest('/api/monitor/pause', {
monitorId,
pause: !monitor.paused,
});

editMonitor({ ...monitor, paused: !monitor.paused });

toast.success(
monitor.paused
? 'Monitor resumed successfully!'
: 'Monitor paused successfully!'
);
} catch (error) {
console.log(error);
toast.error('Error occurred while pausing monitor!');
}
};

const handleClone = () => {
openModal(
<MonitorConfigureModal
monitor={monitor}
closeModal={closeModal}
handleMonitorSubmit={addMonitor}
/>,
false
);
};

const handleEdit = () => {
openModal(
<MonitorConfigureModal
monitor={monitor}
Expand All @@ -61,6 +95,37 @@ const MonitorMenu = ({ name = 'Unknown', monitorId }) => {
);
};

const options = [
{
value: 'Clone',
icon: <FaClone style={{ width: '20px', height: '20px' }} />,
onClick: handleClone,
id: 'monitor-pause-button',
},
{
value: 'Edit',
icon: <MdEdit style={{ width: '20px', height: '20px' }} />,
onClick: handleEdit,
id: 'monitor-edit-button',
},
{
value: 'Delete',
icon: <FaTrashCan style={{ width: '20px', height: '20px' }} />,
onClick: handleDelete,
id: 'monitor-delete-button',
},
{
value: monitor.paused ? 'Resume' : 'Pause',
icon: monitor.paused ? (
<FaPlay style={{ width: '20px', height: '20px' }} />
) : (
<FaPause style={{ width: '20px', height: '20px' }} />
),
onClick: handlePause,
id: 'monitor-clone-button',
},
];

return (
<div className="monitor-view-menu-container">
<div className="monitor-view-menu-name" id="monitor-view-menu-name">
Expand All @@ -70,20 +135,37 @@ const MonitorMenu = ({ name = 'Unknown', monitorId }) => {
{/* <Button iconLeft={<FaTrashCan style={{ width: '20px', height: '20px' }} />}>Duplicate</Button> */}
{isEditor && (
<>
<Button
id="monitor-edit-button"
iconLeft={<MdEdit style={{ width: '20px', height: '20px' }} />}
onClick={handleEdit}
>
Edit
</Button>
<Button
id="monitor-delete-button"
iconLeft={<FaTrashCan style={{ width: '20px', height: '20px' }} />}
onClick={handleDelete}
{options.map((option) => (
<Button
key={option.value}
id={option.id}
iconLeft={option.icon}
onClick={option.onClick}
>
{option.value}
</Button>
))}

<Dropdown.Container
toggleDropdown={toggleDropdown}
isOpen={dropdownIsOpen}
position="left"
>
Delete
</Button>
<Dropdown.Trigger
toggleDropdown={toggleDropdown}
isOpen={dropdownIsOpen}
>
<FaEllipsisVertical style={{ width: '25px', height: '25px' }} />
</Dropdown.Trigger>
<Dropdown.List isOpen={dropdownIsOpen}>
{options.map((option) => (
<Dropdown.Item key={option.value} onClick={option.onClick}>
{option.icon}
{option.value}
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Container>
</>
)}
</div>
Expand Down
21 changes: 21 additions & 0 deletions app/components/monitor/menu.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use '../../styles/breakpoints.scss' as *;

.monitor-view-menu-container {
display: flex;
gap: 10px;
Expand All @@ -13,3 +15,22 @@
font-size: var(--font-2xl);
font-weight: bold;
}

.monitor-view-menu-container .dropdown {
display: none;
}

@include mobile {
.monitor-view-menu-container {
justify-content: center;
align-items: center;
}

.monitor-view-menu-container .button {
display: none;
}

.monitor-view-menu-container .dropdown {
display: block;
}
}
5 changes: 5 additions & 0 deletions app/pages/home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ const Home = () => {

return true;
})
.sort((a, b) => {
if (a.paused && !b.paused) return 1;
if (!a.paused && b.paused) return -1;
return a.name.localeCompare(b.name);
})
.map((monitor, index) => {
if (layout === 'list') {
return (
Expand Down
Loading

0 comments on commit fdca745

Please sign in to comment.