2021-03-25 14:22:43 +00:00
|
|
|
import React, {
|
|
|
|
FunctionComponent,
|
|
|
|
useCallback,
|
|
|
|
useMemo,
|
|
|
|
useState,
|
|
|
|
} from "react";
|
|
|
|
import { Button, Col, Container, Form, Row } from "react-bootstrap";
|
|
|
|
import { SystemApi } from "../../apis";
|
|
|
|
import {
|
|
|
|
AsyncButton,
|
|
|
|
BaseModal,
|
|
|
|
BaseModalProps,
|
|
|
|
Selector,
|
2021-08-16 18:28:18 +00:00
|
|
|
useModalInformation,
|
2021-03-25 14:22:43 +00:00
|
|
|
useOnModalShow,
|
|
|
|
useShowModal,
|
|
|
|
} from "../../components";
|
2021-08-24 01:31:47 +00:00
|
|
|
import { BuildKey } from "../../utilities";
|
2021-05-08 14:25:29 +00:00
|
|
|
import { ColCard, useLatestArray, useUpdateArray } from "../components";
|
2021-03-25 14:22:43 +00:00
|
|
|
import { notificationsKey } from "../keys";
|
|
|
|
|
|
|
|
interface ModalProps {
|
|
|
|
selections: readonly Settings.NotificationInfo[];
|
|
|
|
}
|
|
|
|
|
|
|
|
const NotificationModal: FunctionComponent<ModalProps & BaseModalProps> = ({
|
|
|
|
selections,
|
|
|
|
...modal
|
|
|
|
}) => {
|
|
|
|
const options = useMemo<SelectorOption<Settings.NotificationInfo>[]>(
|
|
|
|
() =>
|
|
|
|
selections
|
|
|
|
.filter((v) => !v.enabled)
|
|
|
|
.map((v) => ({
|
|
|
|
label: v.name,
|
|
|
|
value: v,
|
|
|
|
})),
|
|
|
|
[selections]
|
|
|
|
);
|
|
|
|
|
|
|
|
const update = useUpdateArray<Settings.NotificationInfo>(
|
|
|
|
notificationsKey,
|
2021-05-08 14:25:29 +00:00
|
|
|
"name"
|
2021-03-25 14:22:43 +00:00
|
|
|
);
|
|
|
|
|
2021-08-16 18:28:18 +00:00
|
|
|
const { payload, closeModal } =
|
|
|
|
useModalInformation<Settings.NotificationInfo>(modal.modalKey);
|
2021-03-25 14:22:43 +00:00
|
|
|
|
2021-08-16 18:28:18 +00:00
|
|
|
const [current, setCurrent] =
|
|
|
|
useState<Nullable<Settings.NotificationInfo>>(payload);
|
2021-03-25 14:22:43 +00:00
|
|
|
|
2021-08-16 18:28:18 +00:00
|
|
|
useOnModalShow<Settings.NotificationInfo>(
|
|
|
|
(p) => setCurrent(p),
|
|
|
|
modal.modalKey
|
|
|
|
);
|
2021-03-25 14:22:43 +00:00
|
|
|
|
2021-08-16 18:28:18 +00:00
|
|
|
const updateUrl = useCallback((url: string) => {
|
|
|
|
setCurrent((current) => {
|
2021-03-25 14:22:43 +00:00
|
|
|
if (current) {
|
2021-08-16 18:28:18 +00:00
|
|
|
return {
|
|
|
|
...current,
|
|
|
|
url,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return current;
|
2021-03-25 14:22:43 +00:00
|
|
|
}
|
2021-08-16 18:28:18 +00:00
|
|
|
});
|
|
|
|
}, []);
|
2021-03-25 14:22:43 +00:00
|
|
|
|
|
|
|
const canSave =
|
|
|
|
current !== null && current?.url !== null && current?.url.length !== 0;
|
|
|
|
|
|
|
|
const footer = useMemo(
|
|
|
|
() => (
|
|
|
|
<React.Fragment>
|
|
|
|
<AsyncButton
|
|
|
|
className="mr-auto"
|
|
|
|
disabled={!canSave}
|
|
|
|
variant="outline-secondary"
|
|
|
|
promise={() => {
|
|
|
|
if (current && current.url) {
|
2021-04-15 16:46:19 +00:00
|
|
|
return SystemApi.testNotification(current.url);
|
2021-03-25 14:22:43 +00:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Test
|
|
|
|
</AsyncButton>
|
|
|
|
<Button
|
|
|
|
hidden={payload === null}
|
|
|
|
variant="danger"
|
|
|
|
onClick={() => {
|
|
|
|
if (current) {
|
2021-10-28 10:50:50 +00:00
|
|
|
update({ ...current, enabled: false });
|
2021-03-25 14:22:43 +00:00
|
|
|
}
|
|
|
|
closeModal();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Remove
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
disabled={!canSave}
|
|
|
|
onClick={() => {
|
|
|
|
if (current) {
|
2021-08-16 18:28:18 +00:00
|
|
|
update({ ...current, enabled: true });
|
2021-03-25 14:22:43 +00:00
|
|
|
}
|
|
|
|
closeModal();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Save
|
|
|
|
</Button>
|
|
|
|
</React.Fragment>
|
|
|
|
),
|
|
|
|
[canSave, closeModal, current, update, payload]
|
|
|
|
);
|
|
|
|
|
2021-04-21 15:14:54 +00:00
|
|
|
const getLabel = useCallback((v: Settings.NotificationInfo) => v.name, []);
|
|
|
|
|
2021-03-25 14:22:43 +00:00
|
|
|
return (
|
|
|
|
<BaseModal title="Notification" footer={footer} {...modal}>
|
|
|
|
<Container fluid>
|
|
|
|
<Row>
|
|
|
|
<Col xs={12}>
|
|
|
|
<Selector
|
|
|
|
disabled={payload !== null}
|
|
|
|
options={options}
|
|
|
|
value={current}
|
|
|
|
onChange={setCurrent}
|
2021-04-21 15:14:54 +00:00
|
|
|
label={getLabel}
|
2021-03-25 14:22:43 +00:00
|
|
|
></Selector>
|
|
|
|
</Col>
|
|
|
|
<Col hidden={current === null}>
|
|
|
|
<Form.Group className="mt-4">
|
|
|
|
<Form.Control
|
|
|
|
as="textarea"
|
|
|
|
rows={4}
|
|
|
|
placeholder="URL"
|
|
|
|
value={current?.url ?? ""}
|
|
|
|
onChange={(e) => {
|
|
|
|
const value = e.currentTarget.value;
|
|
|
|
updateUrl(value);
|
|
|
|
}}
|
|
|
|
></Form.Control>
|
|
|
|
</Form.Group>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
</Container>
|
|
|
|
</BaseModal>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const NotificationView: FunctionComponent = () => {
|
2021-05-08 14:25:29 +00:00
|
|
|
const notifications = useLatestArray<Settings.NotificationInfo>(
|
2021-03-25 14:22:43 +00:00
|
|
|
notificationsKey,
|
2021-05-08 14:25:29 +00:00
|
|
|
"name",
|
|
|
|
(s) => s.notifications.providers
|
2021-03-25 14:22:43 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
const showModal = useShowModal();
|
|
|
|
|
|
|
|
const elements = useMemo(() => {
|
|
|
|
return notifications
|
|
|
|
?.filter((v) => v.enabled)
|
|
|
|
.map((v, idx) => (
|
|
|
|
<ColCard
|
|
|
|
key={BuildKey(idx, v.name)}
|
|
|
|
header={v.name}
|
|
|
|
onClick={() => showModal("notifications", v)}
|
|
|
|
></ColCard>
|
|
|
|
));
|
|
|
|
}, [notifications, showModal]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Container fluid>
|
|
|
|
<Row>
|
|
|
|
{elements}{" "}
|
|
|
|
<ColCard plus onClick={() => showModal("notifications")}></ColCard>
|
|
|
|
</Row>
|
|
|
|
<NotificationModal
|
|
|
|
selections={notifications ?? []}
|
|
|
|
modalKey="notifications"
|
|
|
|
></NotificationModal>
|
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
};
|