diff --git a/app/components/home/monitor/layout/compact.jsx b/app/components/home/monitor/layout/compact.jsx deleted file mode 100644 index 878fcec3..00000000 --- a/app/components/home/monitor/layout/compact.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import './compact.scss'; - -// import dependencies -import { useNavigate } from 'react-router-dom'; - -// import local files -import { monitorPropType } from '../../../../../shared/utils/propTypes'; - -const MonitorList = ({ monitor = {} }) => { - const navigate = useNavigate(); - - const { name, uptimePercentage = '0', heartbeats = [] } = monitor; - const [heartbeat = {}] = heartbeats; - - return ( -
navigate(`/monitor/${monitor.monitorId}`)} - id={`monitor-${monitor.name}`} - > -
{name}
- -
- {heartbeat.latency ? `${heartbeat.latency}ms` : '0ms'} -
- -
{uptimePercentage}%
-
- ); -}; - -MonitorList.displayName = 'MonitorList'; - -MonitorList.propTypes = { - monitor: monitorPropType.isRequired, -}; - -export default MonitorList; diff --git a/app/components/home/monitor/layout/compact.scss b/app/components/home/monitor/layout/compact.scss deleted file mode 100644 index d1e7de9e..00000000 --- a/app/components/home/monitor/layout/compact.scss +++ /dev/null @@ -1,35 +0,0 @@ -@use '../../../../styles/pxToRem.scss' as *; - -.home-monitor-container-compact { - width: 100%; - display: grid; - grid-template-columns: 1fr 100px 100px; - background-color: var(--accent-900); - padding: pxToRem(8) pxToRem(12); - transition: var(--transition-base); - - &:hover { - cursor: pointer; - - .home-monitor-name-compact { - color: var(--primary-500); - } - } -} - -.home-monitor-name-compact { - display: flex; - flex-direction: column; - justify-content: center; - color: var(--font-color); - font-size: var(--font-lg); -} - -.home-monitor-uptime-compact { - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - color: var(--font-color); - font-size: var(--font-lg); -} diff --git a/app/components/home/monitor/layout/compact/index.jsx b/app/components/home/monitor/layout/compact/index.jsx new file mode 100644 index 00000000..2b3584a7 --- /dev/null +++ b/app/components/home/monitor/layout/compact/index.jsx @@ -0,0 +1,43 @@ +import './styles.scss'; + +// import dependencies +import PropTypes from 'prop-types'; +import Monitor from '../../../../../pages/monitor'; + +const MonitorCompact = ({ children, monitor_id }) => { + return ( +
+
+
+
Name
+
+ +
{children}
+
+
+ {monitor_id && } + + {!monitor_id && ( +
+ Select a monitor +
+ )} +
+
+ ); +}; + +MonitorCompact.displayName = 'MonitorCompact'; +MonitorCompact.propTypes = { + children: PropTypes.node, + monitor_id: PropTypes.string, +}; + +export default MonitorCompact; diff --git a/app/components/home/monitor/layout/compact/monitor.jsx b/app/components/home/monitor/layout/compact/monitor.jsx new file mode 100644 index 00000000..d6f6e42d --- /dev/null +++ b/app/components/home/monitor/layout/compact/monitor.jsx @@ -0,0 +1,48 @@ +// import dependencies +import PropTypes from 'prop-types'; +import { useNavigate } from 'react-router-dom'; + +// import local files +import { monitorPropType } from '../../../../../../shared/utils/propTypes'; +import classNames from 'classnames'; + +const MonitorCompactItem = ({ monitor = {}, isActive, setActive }) => { + const navigate = useNavigate(); + + const { name, url } = monitor; + + const classes = classNames('home-monitor-name-compact', { + 'home-monitor-name-compact-active': isActive, + }); + + return ( +
{ + if (window.innerWidth <= 1024) { + return navigate(`/monitor/${monitor.monitorId}`); + } + + setActive(monitor.monitorId); + }} + id={`monitor-${monitor.name}`} + > +
+
{name}
+
+ {url} +
+
+
+ ); +}; + +MonitorCompactItem.displayName = 'MonitorCompactItem'; + +MonitorCompactItem.propTypes = { + monitor: monitorPropType.isRequired, + isActive: PropTypes.bool, + setActive: PropTypes.func, +}; + +export default MonitorCompactItem; diff --git a/app/components/home/monitor/layout/compact/styles.scss b/app/components/home/monitor/layout/compact/styles.scss new file mode 100644 index 00000000..5c261453 --- /dev/null +++ b/app/components/home/monitor/layout/compact/styles.scss @@ -0,0 +1,81 @@ +@use '../../../../../styles/pxToRem.scss' as *; +@use '../../../../../styles/breakpoints.scss' as *; + +.home-monitor-compact { + display: grid; + grid-template-columns: 350px 1fr; + background-color: var(--accent-800); + overflow: hidden; +} + +.home-monitor-compact-content { + display: flex; + justify-content: center; + overflow: auto; + overflow-x: hidden; + border-radius: var(--radius-md); + margin-bottom: 1rem; +} + +.home-monitor-container-compact { + width: 100%; + background-color: var(--accent-900); + padding: pxToRem(4) pxToRem(8); + transition: var(--transition-base); + + &:hover { + cursor: pointer; + + .home-monitor-name-compact { + color: var(--primary-500); + background-color: var(--accent-800); + } + } +} + +.home-monitor-name-compact { + display: flex; + flex-direction: column; + justify-content: center; + color: var(--font-color); + font-size: var(--font-lg); + padding: pxToRem(4) pxToRem(8); + border-radius: var(--radius-sm); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + transition: var(--transition-base); + + &-active { + color: var(--primary-500); + background-color: var(--accent-800); + } +} + +.home-monitor-uptime-compact { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + color: var(--font-color); + font-size: var(--font-lg); +} + +.home-monitor-compact-content-empty { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + font-size: var(--font-2xl); + color: var(--accent-200); +} + +@include tablet { + .home-monitor-compact { + grid-template-columns: 1fr; + } + + .home-monitor-compact-content { + display: none; + } +} diff --git a/app/components/home/monitor/layout/table.jsx b/app/components/home/monitor/layout/table.jsx index b94f7b60..2cf929ee 100644 --- a/app/components/home/monitor/layout/table.jsx +++ b/app/components/home/monitor/layout/table.jsx @@ -2,33 +2,11 @@ import './table.scss'; // import dependencies import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -const MonitorTable = ({ layout, children }) => { - const isCompact = layout === 'compact'; - - const classes = classNames({ - 'home-monitor-table-container-list': !isCompact, - 'home-monitor-table-container-compact': isCompact, - }); - - if (isCompact) { - return ( -
-
-
Name
-
Ping
-
Uptime
-
- -
{children}
-
- ); - } +const MonitorTable = ({ children }) => { return (
-
+
Name
Ping
Uptime
@@ -42,7 +20,6 @@ const MonitorTable = ({ layout, children }) => { MonitorTable.displayName = 'MonitorTable'; MonitorTable.propTypes = { - layout: PropTypes.oneOf(['compact', 'list']), children: PropTypes.node, }; diff --git a/app/components/home/monitor/layout/table.scss b/app/components/home/monitor/layout/table.scss index 49f26590..ce295107 100644 --- a/app/components/home/monitor/layout/table.scss +++ b/app/components/home/monitor/layout/table.scss @@ -31,6 +31,7 @@ border-radius: var(--radius-md) var(--radius-md) 0 0; transition: var(--transition-base); border-bottom: 1px solid var(--accent-700); + margin-bottom: 0.25rem; div { display: flex; @@ -55,6 +56,11 @@ } } +.home-monitor-compact-table-content { + overflow: auto; + height: calc(100vh - 220px); +} + @include tablet { .home-monitor-table-container-list { grid-template-columns: 1fr 100px 100px; @@ -77,4 +83,8 @@ .home-monitor-table-header-uptime { display: none; } + + .home-monitor-compact-table-content { + height: calc(100vh - 280px); + } } diff --git a/app/components/notifications/layout/card.jsx b/app/components/notifications/layout/card.jsx index 8863df82..854211b5 100644 --- a/app/components/notifications/layout/card.jsx +++ b/app/components/notifications/layout/card.jsx @@ -30,9 +30,12 @@ const NotificationCard = ({ notification = {} }) => { deleteNotification, toggleNotification, }, + userStore: { user }, } = useContextStore(); const { dropdownIsOpen, toggleDropdown } = useDropdown(); + const isEditor = user.permission <= 3; + const handleDelete = async (id) => { try { await createGetRequest('/api/notifications/delete', { @@ -83,78 +86,82 @@ const NotificationCard = ({ notification = {} }) => { {friendlyName}
- - - - + openModal( + + ) + } + id={`notification-configure-${friendlyName}`} + > + Configure + + )} + + {isEditor && ( + -
- -
-
- - { - handleToggle(notification.id, !notification.isEnabled); - }} - id={`notification-toggle-${friendlyName}`} - > - {notification.isEnabled ? 'Disable' : 'Enable'} - - - openModal( - - ) - } - > - Edit - - { - openModal( - handleDelete(notification.id)} - /> - ); - }} - id={`notification-delete-${friendlyName}`} + - Delete - - -
+
+ +
+ + + { + handleToggle(notification.id, !notification.isEnabled); + }} + id={`notification-toggle-${friendlyName}`} + > + {notification.isEnabled ? 'Disable' : 'Enable'} + + + openModal( + + ) + } + > + Edit + + { + openModal( + handleDelete(notification.id)} + /> + ); + }} + id={`notification-delete-${friendlyName}`} + > + Delete + + + + )}
); }; diff --git a/app/components/settings/account/index.jsx b/app/components/settings/account/index.jsx index 0aadcd7a..c70625ab 100644 --- a/app/components/settings/account/index.jsx +++ b/app/components/settings/account/index.jsx @@ -33,6 +33,7 @@ const accountItems = [
), + permissionLevel: 1, }, { title: 'Delete Account', diff --git a/app/components/settings/account/item/desktop.jsx b/app/components/settings/account/item/desktop.jsx index 309853dd..a16ccc29 100644 --- a/app/components/settings/account/item/desktop.jsx +++ b/app/components/settings/account/item/desktop.jsx @@ -44,6 +44,7 @@ const SettingsAccountDesktopItem = ({ canEdit, description, customButton, + permissionLevel, ...props }) => { const classes = classNames({ @@ -56,6 +57,10 @@ const SettingsAccountDesktopItem = ({ modalStore: { openModal, closeModal }, } = useContextStore(); + if (permissionLevel && permissionLevel < user.permission) { + return null; + } + return (
@@ -103,6 +108,7 @@ SettingsAccountDesktopItem.propTypes = { canEdit: PropTypes.bool, description: PropTypes.string, customButton: PropTypes.element, + permissionLevel: PropTypes.number, }; export default observer(SettingsAccountDesktopItem); diff --git a/app/components/settings/account/item/mobile.jsx b/app/components/settings/account/item/mobile.jsx index 7fbe1dde..e339c135 100644 --- a/app/components/settings/account/item/mobile.jsx +++ b/app/components/settings/account/item/mobile.jsx @@ -39,6 +39,7 @@ const SettingsAccountMobileItem = ({ id, canEdit, fontColor, + permissionLevel, ...props }) => { const { @@ -46,6 +47,10 @@ const SettingsAccountMobileItem = ({ modalStore: { openModal, closeModal }, } = useContextStore(); + if (permissionLevel && permissionLevel < user.permission) { + return null; + } + const color = !fontColor ? {} : { color: `var(--${fontColor}-700)` }; return ( @@ -88,6 +93,7 @@ SettingsAccountMobileItem.propTypes = { id: PropTypes.string.isRequired, canEdit: PropTypes.bool, fontColor: PropTypes.string, + permissionLevel: PropTypes.number, }; export default observer(SettingsAccountMobileItem); diff --git a/app/pages/error.jsx b/app/pages/error.jsx index 41a3ff99..c30377c4 100644 --- a/app/pages/error.jsx +++ b/app/pages/error.jsx @@ -1,4 +1,4 @@ -import './error.scss'; +import '../styles/pages/error.scss'; // import dependencies import { useNavigate } from 'react-router-dom'; diff --git a/app/pages/home.jsx b/app/pages/home.jsx index 3dae0152..e44c979c 100644 --- a/app/pages/home.jsx +++ b/app/pages/home.jsx @@ -1,5 +1,5 @@ // import styles -import './home.scss'; +import '../styles/pages/home.scss'; // import dependencies import { useState } from 'react'; @@ -15,6 +15,7 @@ import useContextStore from '../context'; import HomeMenu from '../components/home/menu'; import MonitorTable from '../components/home/monitor/layout/table'; import useLocalStorageContext from '../hooks/useLocalstorage'; +import MonitorCompactItem from '../components/home/monitor/layout/compact/monitor'; const Home = () => { const { @@ -23,6 +24,7 @@ const Home = () => { const [search, setSearch] = useState(''); const { layout, status, setStatus } = useLocalStorageContext(); + const [activeMonitor, setActiveMonitor] = useState(''); const handleReset = () => { setSearch(''); @@ -63,7 +65,12 @@ const Home = () => { if (layout === 'compact') { return ( - + ); } @@ -84,6 +91,22 @@ const Home = () => { ); } + if (layout === 'compact') { + return ( +
+ setSearch(e.target.value)} + /> + + + {monitorsList} + +
+ ); + } + return (
{ setSearch={(e) => setSearch(e.target.value)} /> - {monitorsList} + {monitorsList}
); }; diff --git a/app/pages/login.jsx b/app/pages/login.jsx index 6b16330a..544df210 100644 --- a/app/pages/login.jsx +++ b/app/pages/login.jsx @@ -1,4 +1,4 @@ -import './register.scss'; +import '../styles/pages/register.scss'; // import dependencies import { useNavigate } from 'react-router-dom'; diff --git a/app/pages/monitor.jsx b/app/pages/monitor.jsx index c7120216..18db867c 100644 --- a/app/pages/monitor.jsx +++ b/app/pages/monitor.jsx @@ -1,6 +1,7 @@ -import './monitor.scss'; +import '../styles/pages/monitor.scss'; // import dependencies +import PropTypes from 'prop-types'; import { observer } from 'mobx-react-lite'; // import local files @@ -12,13 +13,13 @@ import useContextStore from '../context'; import MonitorMenu from '../components/monitor/menu'; import { useParams } from 'react-router-dom'; -const Monitor = () => { +const Monitor = ({ monitor_id }) => { const { globalStore: { getMonitor }, } = useContextStore(); const query = useParams(); - const monitorId = query['monitor_id']; + const monitorId = query['monitor_id'] || monitor_id; const monitor = getMonitor(monitorId); @@ -39,4 +40,8 @@ const Monitor = () => { Monitor.displayName = 'MonitorPage'; +Monitor.propTypes = { + monitor_id: PropTypes.string, +}; + export default observer(Monitor); diff --git a/app/pages/notifications.jsx b/app/pages/notifications.jsx index bcef0228..409f7413 100644 --- a/app/pages/notifications.jsx +++ b/app/pages/notifications.jsx @@ -1,5 +1,5 @@ // import styles -import './notifications.scss'; +import '../styles/pages/notifications.scss'; // import dependencies import { observer } from 'mobx-react-lite'; diff --git a/app/pages/register.jsx b/app/pages/register.jsx index 87a50d8e..0afeba46 100644 --- a/app/pages/register.jsx +++ b/app/pages/register.jsx @@ -1,4 +1,4 @@ -import './register.scss'; +import '../styles/pages/register.scss'; // import dependencies import { useNavigate } from 'react-router-dom'; diff --git a/app/pages/settings.jsx b/app/pages/settings.jsx index 6fa8cab1..48f93d98 100644 --- a/app/pages/settings.jsx +++ b/app/pages/settings.jsx @@ -1,4 +1,4 @@ -import './settings.scss'; +import '../styles/pages/settings.scss'; // import dependencies import { useEffect, useState } from 'react'; diff --git a/app/pages/verify.jsx b/app/pages/verify.jsx index c6474bed..7f556bde 100644 --- a/app/pages/verify.jsx +++ b/app/pages/verify.jsx @@ -1,4 +1,4 @@ -import './verify.scss'; +import '../styles/pages/verify.scss'; import { StatusLogo } from '../components/icons'; diff --git a/app/pages/error.scss b/app/styles/pages/error.scss similarity index 94% rename from app/pages/error.scss rename to app/styles/pages/error.scss index 5764586a..edf1eec1 100644 --- a/app/pages/error.scss +++ b/app/styles/pages/error.scss @@ -1,4 +1,4 @@ -@use '../styles/breakpoints.scss' as *; +@use '../breakpoints.scss' as *; .error-page-container { display: flex; diff --git a/app/pages/home.scss b/app/styles/pages/home.scss similarity index 84% rename from app/pages/home.scss rename to app/styles/pages/home.scss index ce11de15..428907fc 100644 --- a/app/pages/home.scss +++ b/app/styles/pages/home.scss @@ -1,4 +1,4 @@ -@use '../styles/pxToRem.scss' as *; +@use '../pxToRem.scss' as *; .home-container { display: flex; diff --git a/app/pages/monitor.scss b/app/styles/pages/monitor.scss similarity index 77% rename from app/pages/monitor.scss rename to app/styles/pages/monitor.scss index a5a74c39..f065bfb2 100644 --- a/app/pages/monitor.scss +++ b/app/styles/pages/monitor.scss @@ -1,4 +1,4 @@ -@use '../styles/pxToRem.scss' as *; +@use '../pxToRem.scss' as *; .monitor-container { display: flex; diff --git a/app/pages/notifications.scss b/app/styles/pages/notifications.scss similarity index 100% rename from app/pages/notifications.scss rename to app/styles/pages/notifications.scss diff --git a/app/pages/register.scss b/app/styles/pages/register.scss similarity index 98% rename from app/pages/register.scss rename to app/styles/pages/register.scss index 805cdc97..56fe2e45 100644 --- a/app/pages/register.scss +++ b/app/styles/pages/register.scss @@ -1,4 +1,4 @@ -@use '../styles/pxToRem.scss' as *; +@use '../pxToRem.scss' as *; .auth-form-container { width: 100vw; diff --git a/app/pages/settings.scss b/app/styles/pages/settings.scss similarity index 94% rename from app/pages/settings.scss rename to app/styles/pages/settings.scss index ed66681f..73b1d3bc 100644 --- a/app/pages/settings.scss +++ b/app/styles/pages/settings.scss @@ -1,5 +1,5 @@ -@use '../styles/pxToRem.scss' as *; -@use '../styles/breakpoints.scss' as *; +@use '../pxToRem.scss' as *; +@use '../breakpoints.scss' as *; .settings-content { display: flex; diff --git a/app/pages/verify.scss b/app/styles/pages/verify.scss similarity index 100% rename from app/pages/verify.scss rename to app/styles/pages/verify.scss diff --git a/package.json b/package.json index 2c24f6d9..58a0ba15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lunalytics", - "version": "0.6.2", + "version": "0.6.3", "description": "Open source Node.js server/website monitoring tool", "private": true, "author": "KSJaay ",