Plugin architecture (#4861)
* wip * Refactor, tasks, processors, routes loading * Move Slack settings config to plugin * Fix translations in plugins * Move Slack auth to plugin * test * Move other slack-related files into plugin * Forgot to save * refactor
This commit is contained in:
176
plugins/slack/client/Settings.tsx
Normal file
176
plugins/slack/client/Settings.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { find } from "lodash";
|
||||
import { observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
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 Heading from "~/components/Heading";
|
||||
import CollectionIcon from "~/components/Icons/CollectionIcon";
|
||||
import List from "~/components/List";
|
||||
import ListItem from "~/components/List/Item";
|
||||
import Notice from "~/components/Notice";
|
||||
import Scene from "~/components/Scene";
|
||||
import Text from "~/components/Text";
|
||||
import env from "~/env";
|
||||
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
||||
import useQuery from "~/hooks/useQuery";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import SlackIcon from "./Icon";
|
||||
import SlackButton from "./components/SlackButton";
|
||||
import SlackListItem from "./components/SlackListItem";
|
||||
|
||||
function Slack() {
|
||||
const team = useCurrentTeam();
|
||||
const { collections, integrations } = useStores();
|
||||
const { t } = useTranslation();
|
||||
const query = useQuery();
|
||||
const error = query.get("error");
|
||||
|
||||
React.useEffect(() => {
|
||||
collections.fetchPage({
|
||||
limit: 100,
|
||||
});
|
||||
integrations.fetchPage({
|
||||
limit: 100,
|
||||
});
|
||||
}, [collections, integrations]);
|
||||
|
||||
const commandIntegration = find(
|
||||
integrations.slackIntegrations,
|
||||
(i) => i.type === IntegrationType.Command
|
||||
);
|
||||
|
||||
const groupedCollections = collections.orderedData
|
||||
.map<[Collection, Integration | undefined]>((collection) => {
|
||||
const integration = find(integrations.slackIntegrations, {
|
||||
collectionId: collection.id,
|
||||
});
|
||||
|
||||
return [collection, integration];
|
||||
})
|
||||
.sort((a) => (a[1] ? -1 : 1));
|
||||
|
||||
const appName = env.APP_NAME;
|
||||
|
||||
return (
|
||||
<Scene title="Slack" icon={<SlackIcon color="currentColor" />}>
|
||||
<Heading>Slack</Heading>
|
||||
|
||||
{error === "access_denied" && (
|
||||
<Notice>
|
||||
<Trans>
|
||||
Whoops, you need to accept the permissions in Slack to connect
|
||||
{{ appName }} to your team. Try again?
|
||||
</Trans>
|
||||
</Notice>
|
||||
)}
|
||||
{error === "unauthenticated" && (
|
||||
<Notice>
|
||||
<Trans>
|
||||
Something went wrong while authenticating your request. Please try
|
||||
logging in again?
|
||||
</Trans>
|
||||
</Notice>
|
||||
)}
|
||||
<Text type="secondary">
|
||||
<Trans
|
||||
defaults="Get rich previews of {{ appName }} links shared in Slack and use the <em>{{ command }}</em> slash command to search for documents without leaving your chat."
|
||||
values={{
|
||||
command: "/outline",
|
||||
appName,
|
||||
}}
|
||||
components={{
|
||||
em: <Code />,
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
{env.SLACK_CLIENT_ID ? (
|
||||
<>
|
||||
<p>
|
||||
{commandIntegration ? (
|
||||
<Button onClick={() => commandIntegration.delete()}>
|
||||
{t("Disconnect")}
|
||||
</Button>
|
||||
) : (
|
||||
<SlackButton
|
||||
scopes={[
|
||||
"commands",
|
||||
"links:read",
|
||||
"links:write",
|
||||
// TODO: Wait forever for Slack to approve these scopes.
|
||||
//"users:read",
|
||||
//"users:read.email",
|
||||
]}
|
||||
redirectUri={`${env.URL}/auth/slack.commands`}
|
||||
state={team.id}
|
||||
icon={<SlackIcon color="currentColor" />}
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
<h2>{t("Collections")}</h2>
|
||||
<Text type="secondary">
|
||||
<Trans>
|
||||
Connect {{ appName }} collections to Slack channels. Messages will
|
||||
be automatically posted to Slack when documents are published or
|
||||
updated.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
<List>
|
||||
{groupedCollections.map(([collection, integration]) => {
|
||||
if (integration) {
|
||||
return (
|
||||
<SlackListItem
|
||||
key={integration.id}
|
||||
collection={collection}
|
||||
integration={
|
||||
integration as Integration<IntegrationType.Post>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={collection.id}
|
||||
title={collection.name}
|
||||
image={<CollectionIcon collection={collection} />}
|
||||
actions={
|
||||
<SlackButton
|
||||
scopes={["incoming-webhook"]}
|
||||
redirectUri={`${env.URL}/auth/slack.post`}
|
||||
state={collection.id}
|
||||
label={t("Connect")}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</>
|
||||
) : (
|
||||
<Notice>
|
||||
<Trans>
|
||||
The Slack integration is currently disabled. Please set the
|
||||
associated environment variables and restart the server to enable
|
||||
the integration.
|
||||
</Trans>
|
||||
</Notice>
|
||||
)}
|
||||
</Scene>
|
||||
);
|
||||
}
|
||||
|
||||
const Code = styled.code`
|
||||
padding: 4px 6px;
|
||||
margin: 0 2px;
|
||||
background: ${(props) => props.theme.codeBackground};
|
||||
border-radius: 4px;
|
||||
`;
|
||||
|
||||
export default observer(Slack);
|
||||
Reference in New Issue
Block a user