Skip to content
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: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<a href="https://discord.gg/HkpDnUdf4u">Discord</a>
</div>

![Demo](https://raw.githubusercontent.com/KSJaay/Lunalytics/refs/heads/main/docs/public/demo.gif)
![Demo](https://raw.githubusercontent.com/KSJaay/Lunalytics/refs/heads/main/public/demo.gif)

## 📔 Features

Expand Down
3 changes: 2 additions & 1 deletion app/components/incident/content/impact.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { toast } from 'react-toastify';
import { observer } from 'mobx-react-lite';

// import local files
import Dropdown from '../../ui/dropdown';
Expand Down Expand Up @@ -88,4 +89,4 @@ const IncidentContentImpact = () => {

IncidentContentImpact.displayName = 'IncidentContentImpact';

export default IncidentContentImpact;
export default observer(IncidentContentImpact);
51 changes: 35 additions & 16 deletions app/components/modal/monitor/configure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import MonitorConfigureDockerModal from './configure/docker';
import MonitorConfigureJsonQueryModal from './configure/json';
import type { MonitorProps } from '../../../types/monitor';
import MonitorConfigurePushModal from './configure/push';
import classNames from 'classnames';

const pages = [
{ id: 'basic', title: 'Basic', icon: <FaCog size={20} /> },
Expand All @@ -43,11 +44,19 @@ const MonitorConfigureModal = ({
isEdit = false,
}: ModalProps) => {
const [pageId, setPageId] = useState('basic');
const { errors, inputs, handleActionButtons, handleInput } = useMonitorForm(
const {
errors,
inputs,
handleActionButtons,
handleInput,
errorPages,
setErrorPages,
} = useMonitorForm(
monitor,
isEdit,
closeModal,
handleMonitorSubmit
handleMonitorSubmit,
setPageId
);

return (
Expand All @@ -63,20 +72,30 @@ const MonitorConfigureModal = ({
settings to your liking.
</div>
<div className="monitor-configure-left-pages">
{pages.map((page) => (
<div
className={
page.id === pageId
? 'monitor-configure-page-button active'
: 'monitor-configure-page-button'
}
onClick={() => setPageId(page.id)}
key={page.id}
>
{page.icon}
<div>{page.title}</div>
</div>
))}
{pages.map((page) => {
const classes = classNames('monitor-configure-page-button', {
active: page.id === pageId,
'error-circle': errorPages.has(page.id),
});

return (
<div
className={classes}
onClick={() => {
setErrorPages((oldSet) => {
const trimmedErrorPages = new Set([...oldSet]);
trimmedErrorPages.delete(pageId);
return trimmedErrorPages;
});
setPageId(page.id);
}}
key={page.id}
>
{page.icon}
<div>{page.title}</div>
</div>
);
})}
</div>

<div className="monitor-configure-buttons">
Expand Down
3 changes: 3 additions & 0 deletions app/components/modal/monitor/pages/initial/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Input } from '@lunalytics/ui';
// import local files
import MonitorInitialDropdown from './type';
import MonitorIconSelect from './icons';
import MonitorParentSelect from './parent';

interface MonitorInitialTypeProps {
inputs: any;
Expand Down Expand Up @@ -51,6 +52,8 @@ const MonitorInitialType = ({
)}

<MonitorIconSelect inputs={inputs} handleInput={handleInput} />

<MonitorParentSelect inputs={inputs} handleInput={handleInput} />
</div>
);
};
Expand Down
71 changes: 71 additions & 0 deletions app/components/modal/monitor/pages/initial/parent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { observer } from 'mobx-react-lite';
import useDropdown from '../../../../../hooks/useDropdown';
import Dropdown from '../../../../ui/dropdown';
import useContextStore from '../../../../../context';

const MonitorParentSelect = ({
inputs,
handleInput,
}: {
inputs: any;
handleInput: (key: string, value: any) => void;
}) => {
const {
globalStore: { allMonitors },
} = useContextStore();
const { toggleDropdown, dropdownIsOpen } = useDropdown(true);

const onSelect = (monitorId: string | null) => {
handleInput('parentId', monitorId);
toggleDropdown();
};

const monitors = allMonitors.filter(
(monitor) => monitor.monitorId !== inputs.monitorId
);

return (
<div className="luna-input-wrapper">
<label className="input-label">Monitor Parent</label>
<label className="luna-input-subtitle">
If parent is down notification won&#39;t be sent for this monitor
</label>

<div>
<Dropdown.Container
isOpen={dropdownIsOpen}
toggleDropdown={toggleDropdown}
position="center"
>
<Dropdown.Trigger
isOpen={dropdownIsOpen}
toggleDropdown={toggleDropdown}
color="var(--lunaui-accent-900)"
asInput
>
{inputs.parentId
? monitors.find(
(monitor) => monitor.monitorId === inputs.parentId
)?.name
: 'No parent'}
</Dropdown.Trigger>
<Dropdown.List isOpen={dropdownIsOpen} fullWidth>
<Dropdown.Item onClick={() => onSelect(null)}>
No parent
</Dropdown.Item>
{monitors.map((monitor) => (
<Dropdown.Item
key={monitor.monitorId}
onClick={() => onSelect(monitor.monitorId)}
>
{monitor.name}
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Container>
</div>
</div>
);
};

export default observer(MonitorParentSelect);
12 changes: 12 additions & 0 deletions app/components/modal/monitor/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
}

.monitor-configure-page-button {
position: relative;
padding: 12px;
background-color: var(--accent-800);
border-radius: 8px;
Expand All @@ -31,6 +32,17 @@
&:hover {
background-color: var(--accent-700);
}

&.error-circle::after {
content: "";
position: absolute;
top: 40%;
right: 10px;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
}
}

.monitor-configure-left-container {
Expand Down
2 changes: 2 additions & 0 deletions app/handlers/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const handleMonitor = async (

const {
name,
parentId,
type,
url,
method,
Expand All @@ -57,6 +58,7 @@ const handleMonitor = async (

const query = await createPostRequest(apiPath, {
name,
parentId,
type,
url,
method,
Expand Down
49 changes: 43 additions & 6 deletions app/hooks/useMonitorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,71 @@ const useMonitorForm = (
values: Partial<MonitorProps> = defaultInputs,
isEdit: boolean = false,
closeModal: () => void,
setMonitor: (monitor: Partial<MonitorProps>) => void
setMonitor: (monitor: Partial<MonitorProps>) => void,
setPageId: (id: string) => void,
) => {
const [inputs, setInput] = useState<Partial<MonitorProps>>({
...defaultInputs,
...values,
});
const [errors, setErrors] = useState({});
const [errorPages, setErrorPages] = useState<Set<string>>(new Set())

const handleInput = (name: string, value: any) => {
setInput((prev) => ({ ...prev, [name]: value }));
};

const getPagesWithErrors = (errorsObj: Record<string,string>) => {

const associatedPage: Record<string, string> = {
'name': "basic",
'type': "basic",
'url': "basic",
'port': "basic",
'icon': "basic",
'method': "basic",
'json_query': "basic",
'interval': "interval",
'retry': "interval",
'retryInterval': "interval",
'requestTimeout': "interval",
'notificationType': "notification",
'headers': "advanced",
'body': "advanced",
'valid_status_codes': "advanced",
}
const pagesWithError = new Set<string>();

Object.keys(errorsObj).forEach(error => {
const page = associatedPage[error]
if(error && page) pagesWithError.add(page)
})

return pagesWithError
}


const handleActionButtons = (action: string) => () => {
switch (action) {
case 'Create': {
const type = inputs.type ?? defaultInputs.type;
const validator = monitorValidators[type];
if (!validator) return console.log("Validator doesn't exist");

const errorsObj = validator(inputs);
const errorsObj = validator(inputs) as Record<string, string> | false;

if (errorsObj !== false) {
const pagesWithErrors = getPagesWithErrors(errorsObj)
setErrorPages(pagesWithErrors);
setPageId(Array.from(pagesWithErrors)[0])

if (errorsObj) {
setErrors(errorsObj);
setErrors(errorsObj);
break;
}

setErrorPages(new Set<string>())
setErrors({});

handleMonitor(inputs, isEdit, closeModal, setMonitor);
break;
}
Expand All @@ -66,7 +103,7 @@ const useMonitorForm = (
}
};

return { inputs, errors, handleActionButtons, handleInput };
return { inputs, errors, handleActionButtons, handleInput, errorPages, setErrorPages };
};

export default useMonitorForm;
Binary file removed docs/public/icon-192x192.png
Binary file not shown.
Binary file removed docs/public/icon-512x512.png
Binary file not shown.
31 changes: 29 additions & 2 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lunalytics",
"version": "0.10.12",
"version": "0.10.13",
"description": "Open source Node.js server/website monitoring tool",
"private": true,
"author": "KSJaay <ksjaay@gmail.com>",
Expand Down Expand Up @@ -81,6 +81,7 @@
"react-window": "1.8.11",
"recharts": "3.2.1",
"swapy": "1.0.5",
"systeminformation": "^5.27.11",
"ua-parser-js": "2.0.3",
"uuid": "11.1.0",
"winston": "3.17.0",
Expand Down
File renamed without changes
File renamed without changes
Loading