bazarr/frontend/src/Settings/Notifications/components.tsx

187 lines
4.5 KiB
TypeScript
Raw Normal View History

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";
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,
"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) {
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 = () => {
const notifications = useLatestArray<Settings.NotificationInfo>(
2021-03-25 14:22:43 +00:00
notificationsKey,
"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>
);
};