Skip to content

Commit

Permalink
feat: add initial ui changes
Browse files Browse the repository at this point in the history
  • Loading branch information
iamKunalGupta committed Mar 6, 2024
1 parent 43bfdcb commit 0e6f295
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 27 deletions.
253 changes: 247 additions & 6 deletions ui/app/alert-config/new.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { Button } from '@/lib/Button';
import { TextField } from '@/lib/TextField';
import Image from 'next/image';
import { useState } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import ReactSelect from 'react-select';
import { PulseLoader } from 'react-spinners';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import SelectTheme from '../styles/select';
import { alertConfigReqSchema, alertConfigType } from './validation';
import {
alertConfigReqSchema,
alertConfigType,
emailConfigType,
serviceConfigType,
slackConfigType,
} from './validation';

export interface AlertConfigProps {
id?: bigint;
Expand All @@ -19,22 +25,257 @@ export interface AlertConfigProps {
forEdit?: boolean;
}

export type serviceType2 = 'slack' | 'email';

export interface AlertConfigProps2 {
id?: bigint;
serviceType: serviceType2;
alertConfig: serviceConfigType;
forEdit?: boolean;
}

const notifyErr = (errMsg: string) => {
toast.error(errMsg, {
position: 'bottom-center',
});
};

function ConfigLabel() {
function ConfigLabel(data: { label: string; value: string }) {
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
<Image src={'/images/slack.png'} alt='slack' height={60} width={60} />
<Image
src={`/images/${data.value}.png`}
alt={data.value}
height={20}
width={20}
style={{
marginRight: '5px',
}}
/>
{data.label}
</div>
);
}

const NewAlertConfig = (alertProps: AlertConfigProps) => {
function getSlackProps(
config: slackConfigType,
setConfig: Dispatch<SetStateAction<slackConfigType>>
) {
return (
<>
<div>
<p>Authorisation Token</p>
<TextField
style={{ height: '2.5rem', marginTop: '0.5rem' }}
variant='simple'
placeholder='Auth Token'
value={config.auth_token}
onChange={(e) => {
setConfig((value) => {
value.auth_token = e.target.value;
return value;
});
}}
/>
</div>
<div>
<p>Channel IDs</p>
<TextField
style={{ height: '2.5rem', marginTop: '0.5rem' }}
variant='simple'
placeholder='Comma separated'
value={config.channel_ids?.join(',')}
onChange={(e) => {
setConfig((value) => {
value.channel_ids = e.target.value.split(',');
return value;
});
}}
/>
</div>
</>
);
}

function getEmailProps(
config: emailConfigType,
setConfig: Dispatch<SetStateAction<emailConfigType>>
) {
return (
<>
<div>
<p>Email Addresses</p>
<TextField
style={{ height: '2.5rem', marginTop: '0.5rem' }}
variant='simple'
placeholder='Comma separated'
value={config.email_addresses?.join(',')}
onChange={(e) => {
setConfig((value) => {
value.email_addresses = e.target.value.split(',');
return value;
});
}}
/>
</div>
</>
);
}
function getExtraProps<T extends serviceConfigType>(
serviceType: serviceType2,
config: T,
setConfig: Dispatch<SetStateAction<T>>
) {
switch (serviceType) {
case 'email':
return getEmailProps(
config as emailConfigType,
setConfig as Dispatch<SetStateAction<emailConfigType>>
);
case 'slack': {
return getSlackProps(
config as slackConfigType,
setConfig as Dispatch<SetStateAction<slackConfigType>>
);
}
}
}

export function NewConfig(alertProps: AlertConfigProps2) {
const [serviceType, setServiceType] = useState<serviceType2>(
alertProps.serviceType
);

const [config, setConfig] = useState<serviceConfigType>(
alertProps.alertConfig
);
const [slotLagGBAlertThreshold, setSlotLagGBAlertThreshold] =
useState<number>(alertProps.alertConfig.slot_lag_mb_alert_threshold);
const [openConnectionsAlertThreshold, setOpenConnectionsAlertThreshold] =
useState<number>(alertProps.alertConfig.open_connections_alert_threshold);
const [loading, setLoading] = useState(false);
const handleAdd = async () => {
if (serviceType !== 'slack') {
notifyErr('Service Type must be selected');
return;
}

const alertConfigReq: alertConfigType = {
serviceType: serviceType,
serviceConfig: config,
};
const alertReqValidity = alertConfigReqSchema.safeParse(alertConfigReq);
if (!alertReqValidity.success) {
notifyErr(alertReqValidity.error.issues[0].message);
return;
}
setLoading(true);
if (alertProps.forEdit) {
alertConfigReq.id = Number(alertProps.id);
}
const createRes = await fetch('/api/alert-config', {
method: alertProps.forEdit ? 'PUT' : 'POST',
body: JSON.stringify(alertConfigReq),
});
const createStatus = await createRes.text();
setLoading(false);
if (createStatus !== 'success') {
notifyErr('Something went wrong. Please try again');
return;
}

window.location.reload();
};
const extraProps = getExtraProps(serviceType, config, setConfig);
return (
<form onSubmit={handleAdd}>
<div
style={{
display: 'flex',
flexDirection: 'column',
rowGap: '2rem',
marginTop: '3rem',
width: '40%',
}}
>
<div style={{ width: '50%' }}>
<p style={{ marginBottom: '0.5rem' }}>Alert Provider</p>
<ReactSelect
options={[
{
value: 'slack',
label: 'Slack',
},
{
value: 'email',
label: 'Email',
},
]}
placeholder='Select provider'
defaultValue={{
value: 'slack',
label: 'Slack',
}}
formatOptionLabel={ConfigLabel}
onChange={(val, _) => val && setServiceType(val.value)}
theme={SelectTheme}
/>
</div>
<div>
<p>Slot Lag Alert Threshold (in GB)</p>
<TextField
style={{ height: '2.5rem', marginTop: '0.5rem' }}
variant='simple'
type={'number'}
placeholder='optional'
value={slotLagGBAlertThreshold}
onChange={(e) => setSlotLagGBAlertThreshold(e.target.valueAsNumber)}
/>
</div>
<div>
<p>Open Connections Alert Threshold</p>
<TextField
style={{ height: '2.5rem', marginTop: '0.5rem' }}
variant='simple'
type={'number'}
placeholder='optional'
value={openConnectionsAlertThreshold}
onChange={(e) =>
setOpenConnectionsAlertThreshold(e.target.valueAsNumber)
}
/>
</div>
{getExtraProps(serviceType, config, setConfig)}
<Button
style={{ marginTop: '1rem', width: '20%', height: '2.5rem' }}
onClick={handleAdd}
type={'submit'}
variant='normalSolid'
>
{loading ? (
<PulseLoader color='white' size={10} />
) : alertProps.forEdit ? (
'Update'
) : (
'Create'
)}
</Button>
<ToastContainer />
</div>
</form>
);
}
//
export const NewAlertConfig = (alertProps: AlertConfigProps) => {
const [serviceType, setServiceType] = useState<string>('slack');
const [config, setConfig] = useState<serviceConfigType>({
auth_token: alertProps.authToken ?? '',
channel_ids: alertProps.channelIdString?.split(',')!,
slot_lag_mb_alert_threshold:
alertProps.slotLagGBAlertThreshold * 1000 || 20000,
open_connections_alert_threshold:
alertProps.openConnectionsAlertThreshold || 5,
});
const [authToken, setAuthToken] = useState<string>(alertProps.authToken);
const [channelIdString, setChannelIdString] = useState<string>(
alertProps.channelIdString
Expand Down Expand Up @@ -177,4 +418,4 @@ const NewAlertConfig = (alertProps: AlertConfigProps) => {
);
};

export default NewAlertConfig;
export default NewConfig;
24 changes: 21 additions & 3 deletions ui/app/alert-config/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import useSWR from 'swr';
import { UAlertConfigResponse } from '../dto/AlertDTO';
import { tableStyle } from '../peers/[peerName]/style';
import { fetcher } from '../utils/swr';
import NewAlertConfig, { AlertConfigProps } from './new';
import { AlertConfigProps, AlertConfigProps2, NewConfig } from './new';
const ServiceIcon = (serviceType: string) => {
switch (serviceType.toLowerCase()) {
default:
Expand All @@ -36,10 +36,22 @@ const AlertConfigPage: React.FC = () => {
openConnectionsAlertThreshold: 5,
forEdit: false,
};
const blankAlert2: AlertConfigProps2 = {
serviceType: 'slack',
alertConfig: {
email_addresses: [''],
auth_token: '',
channel_ids: [''],
open_connections_alert_threshold: 20,
slot_lag_mb_alert_threshold: 5,
},
forEdit: false,
};
const [inEditOrAddMode, setInEditOrAddMode] = useState(false);
const [editAlertConfig, setEditAlertConfig] =
useState<AlertConfigProps>(blankAlert);

const [editAlertConfig2, setEditAlertConfig2] =
useState<AlertConfigProps2>(blankAlert2);
const onEdit = (alertConfig: UAlertConfigResponse, id: bigint) => {
setInEditOrAddMode(true);
const configJSON = JSON.stringify(alertConfig.service_config);
Expand All @@ -55,6 +67,11 @@ const AlertConfigPage: React.FC = () => {
JSON.parse(configJSON)?.open_connections_alert_threshold,
forEdit: true,
});
setEditAlertConfig2({
id,
serviceType: alertConfig.service_type,
alertConfig: alertConfig.service_config,
});
};
return (
<div style={{ padding: '2rem' }}>
Expand Down Expand Up @@ -141,7 +158,8 @@ const AlertConfigPage: React.FC = () => {
{inEditOrAddMode ? 'Cancel' : 'Add Configuration'}
</Label>
</Button>
{inEditOrAddMode && <NewAlertConfig {...editAlertConfig} />}
{/*{inEditOrAddMode && <NewAlertConfig {...editAlertConfig} />}*/}
{inEditOrAddMode && <NewConfig {...editAlertConfig2} />}
</div>
);
};
Expand Down
Loading

0 comments on commit 0e6f295

Please sign in to comment.