Files
outline/app/scenes/Settings/components/SlackListItem.tsx
Apoorv Mishra 4dbad4e46c feat: Support embed configuration (#3980)
* wip

* stash

* fix: make authenticationId nullable fk

* fix: apply generics to resolve compile time type errors

* fix: loosen integration settings

* chore: refactor into functional component

* feat: pass integrations all the way to embeds

* perf: avoid re-fetching integrations

* fix: change attr name to avoid type overlap

* feat: use hostname from embed settings in matcher

* Revert "feat: use hostname from embed settings in matcher"

This reverts commit e7485d9cda4dcf45104e460465ca104a56c67ddc.

* feat: refactor  into a class

* chore: refactor url regex formation as a util

* fix: escape regex special chars

* fix: remove in-house escapeRegExp in favor of lodash's

* fix: sanitize url

* perf: memoize embeds

* fix: rename hostname to url and allow spreading entire settings instead of just url

* fix: replace diagrams with drawio

* fix: rename

* fix: support self-hosted and saas both

* fix: assert on settings url

* fix: move embed integrations loading to hook

* fix: address review comments

* fix: use observer in favor of explicit state setters

* fix: refactor useEmbedIntegrations into useEmbeds

* fix: use translations for toasts

Co-authored-by: Tom Moor <tom.moor@gmail.com>
2022-08-26 12:21:46 +05:30

119 lines
3.5 KiB
TypeScript

import { uniq } from "lodash";
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 { 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 CollectionIcon from "~/components/CollectionIcon";
import Flex from "~/components/Flex";
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: ${(props) => props.theme.text};
margin-top: -12px;
`;
export default observer(SlackListItem);