Files
outline/plugins/slack/client/components/SlackListItem.tsx

120 lines
3.5 KiB
TypeScript

import uniq from "lodash/uniq";
import { observer } from "mobx-react";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { usePopoverState, PopoverDisclosure } from "reakit/Popover";
import styled from "styled-components";
import { s } from "@shared/styles";
import { IntegrationType } from "@shared/types";
import Collection from "~/models/Collection";
import Integration from "~/models/Integration";
import Button from "~/components/Button";
import ButtonLink from "~/components/ButtonLink";
import Flex from "~/components/Flex";
import CollectionIcon from "~/components/Icons/CollectionIcon";
import ListItem from "~/components/List/Item";
import Popover from "~/components/Popover";
import Switch from "~/components/Switch";
import Text from "~/components/Text";
import useToasts from "~/hooks/useToasts";
type Props = {
integration: Integration<IntegrationType.Post>;
collection: Collection;
};
function SlackListItem({ integration, collection }: Props) {
const { t } = useTranslation();
const { showToast } = useToasts();
const handleChange = async (ev: React.ChangeEvent<HTMLInputElement>) => {
if (ev.target.checked) {
integration.events = uniq([...integration.events, ev.target.name]);
} else {
integration.events = integration.events.filter(
(n) => n !== ev.target.name
);
}
await integration.save();
showToast(t("Settings saved"), {
type: "success",
});
};
const mapping = {
"documents.publish": t("document published"),
"documents.update": t("document updated"),
};
const popover = usePopoverState({
gutter: 0,
placement: "bottom-start",
});
return (
<ListItem
key={integration.id}
title={
<Flex align="center" gap={6}>
<CollectionIcon collection={collection} /> {collection.name}
</Flex>
}
subtitle={
<>
<Trans
defaults={`Posting to the <em>{{ channelName }}</em> channel on`}
values={{
channelName: integration.settings.channel,
events: integration.events.map((ev) => mapping[ev]).join(", "),
}}
components={{
em: <strong />,
}}
/>{" "}
<PopoverDisclosure {...popover}>
{(props) => (
<ButtonLink {...props}>
{integration.events.map((ev) => mapping[ev]).join(", ")}
</ButtonLink>
)}
</PopoverDisclosure>
<Popover {...popover} aria-label={t("Settings")}>
<Events>
<h3>{t("Notifications")}</h3>
<Text type="secondary">
{t("These events should be posted to Slack")}
</Text>
<Switch
label={t("Document published")}
name="documents.publish"
checked={integration.events.includes("documents.publish")}
onChange={handleChange}
/>
<Switch
label={t("Document updated")}
name="documents.update"
checked={integration.events.includes("documents.update")}
onChange={handleChange}
/>
</Events>
</Popover>
</>
}
actions={
<Button onClick={integration.delete} neutral>
{t("Disconnect")}
</Button>
}
/>
);
}
const Events = styled.div`
color: ${s("text")};
margin-top: -12px;
`;
export default observer(SlackListItem);