Add ability to link Slack <-> Outline accounts (#6682)
This commit is contained in:
@@ -5,7 +5,9 @@ import styled from "styled-components";
|
||||
import { IntegrationService, IntegrationType } from "@shared/types";
|
||||
import Collection from "~/models/Collection";
|
||||
import Integration from "~/models/Integration";
|
||||
import Button from "~/components/Button";
|
||||
import { ConnectedButton } from "~/scenes/Settings/components/ConnectedButton";
|
||||
import SettingRow from "~/scenes/Settings/components/SettingRow";
|
||||
import Flex from "~/components/Flex";
|
||||
import Heading from "~/components/Heading";
|
||||
import CollectionIcon from "~/components/Icons/CollectionIcon";
|
||||
import List from "~/components/List";
|
||||
@@ -15,6 +17,7 @@ import Scene from "~/components/Scene";
|
||||
import Text from "~/components/Text";
|
||||
import env from "~/env";
|
||||
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
||||
import usePolicy from "~/hooks/usePolicy";
|
||||
import useQuery from "~/hooks/useQuery";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import { SlackUtils } from "../shared/SlackUtils";
|
||||
@@ -27,6 +30,7 @@ function Slack() {
|
||||
const { collections, integrations } = useStores();
|
||||
const { t } = useTranslation();
|
||||
const query = useQuery();
|
||||
const can = usePolicy(team);
|
||||
const error = query.get("error");
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -34,6 +38,7 @@ function Slack() {
|
||||
limit: 100,
|
||||
});
|
||||
void integrations.fetchPage({
|
||||
service: IntegrationService.Slack,
|
||||
limit: 100,
|
||||
});
|
||||
}, [collections, integrations]);
|
||||
@@ -43,6 +48,11 @@ function Slack() {
|
||||
service: IntegrationService.Slack,
|
||||
});
|
||||
|
||||
const linkedAccountIntegration = integrations.find({
|
||||
type: IntegrationType.LinkedAccount,
|
||||
service: IntegrationService.Slack,
|
||||
});
|
||||
|
||||
const groupedCollections = collections.orderedData
|
||||
.map<[Collection, Integration | undefined]>((collection) => {
|
||||
const integration = integrations.find({
|
||||
@@ -76,44 +86,80 @@ function Slack() {
|
||||
</Trans>
|
||||
</Notice>
|
||||
)}
|
||||
<Text as="p" 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={SlackUtils.commandsUrl()}
|
||||
state={team.id}
|
||||
icon={<SlackIcon />}
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
<h2>{t("Collections")}</h2>
|
||||
<SettingRow
|
||||
name="link"
|
||||
label={t("Personal account")}
|
||||
description={
|
||||
<Trans>
|
||||
Link your {{ appName }} account to Slack to enable searching the
|
||||
documents you have access to directly within chat.
|
||||
</Trans>
|
||||
}
|
||||
>
|
||||
<Flex align="flex-end" column>
|
||||
{linkedAccountIntegration ? (
|
||||
<ConnectedButton
|
||||
onClick={linkedAccountIntegration.delete}
|
||||
confirmationMessage={t(
|
||||
"Disconnecting your personal account will prevent searching for documents from Slack. Are you sure?"
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<SlackButton
|
||||
redirectUri={SlackUtils.connectUrl()}
|
||||
state={SlackUtils.createState(
|
||||
team.id,
|
||||
IntegrationType.LinkedAccount
|
||||
)}
|
||||
label={t("Connect")}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</SettingRow>
|
||||
|
||||
{can.update && (
|
||||
<>
|
||||
<SettingRow
|
||||
name="slash"
|
||||
border={false}
|
||||
label={t("Slash command")}
|
||||
description={
|
||||
<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 />,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Flex align="flex-end" column>
|
||||
{commandIntegration ? (
|
||||
<ConnectedButton
|
||||
onClick={commandIntegration.delete}
|
||||
confirmationMessage={t(
|
||||
"This will remove the Outline slash command from your Slack workspace. Are you sure?"
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<SlackButton
|
||||
scopes={["commands", "links:read", "links:write"]}
|
||||
redirectUri={SlackUtils.connectUrl()}
|
||||
state={SlackUtils.createState(
|
||||
team.id,
|
||||
IntegrationType.Command
|
||||
)}
|
||||
icon={<SlackIcon />}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</SettingRow>
|
||||
|
||||
<Heading as="h2">{t("Collections")}</Heading>
|
||||
<Text as="p" type="secondary">
|
||||
<Trans>
|
||||
Connect {{ appName }} collections to Slack channels. Messages will
|
||||
@@ -144,8 +190,12 @@ function Slack() {
|
||||
actions={
|
||||
<SlackButton
|
||||
scopes={["incoming-webhook"]}
|
||||
redirectUri={`${env.URL}/auth/slack.post`}
|
||||
state={collection.id}
|
||||
redirectUri={SlackUtils.connectUrl()}
|
||||
state={SlackUtils.createState(
|
||||
team.id,
|
||||
IntegrationType.Post,
|
||||
{ collectionId: collection.id }
|
||||
)}
|
||||
label={t("Connect")}
|
||||
/>
|
||||
}
|
||||
@@ -154,14 +204,6 @@ function Slack() {
|
||||
})}
|
||||
</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>
|
||||
);
|
||||
@@ -172,6 +214,7 @@ const Code = styled.code`
|
||||
margin: 0 2px;
|
||||
background: ${(props) => props.theme.codeBackground};
|
||||
border-radius: 4px;
|
||||
font-size: 80%;
|
||||
`;
|
||||
|
||||
export default observer(Slack);
|
||||
|
||||
@@ -9,7 +9,7 @@ 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 { ConnectedButton } from "~/scenes/Settings/components/ConnectedButton";
|
||||
import ButtonLink from "~/components/ButtonLink";
|
||||
import Flex from "~/components/Flex";
|
||||
import CollectionIcon from "~/components/Icons/CollectionIcon";
|
||||
@@ -100,9 +100,12 @@ function SlackListItem({ integration, collection }: Props) {
|
||||
</>
|
||||
}
|
||||
actions={
|
||||
<Button onClick={integration.delete} neutral>
|
||||
{t("Disconnect")}
|
||||
</Button>
|
||||
<ConnectedButton
|
||||
onClick={integration.delete}
|
||||
confirmationMessage={t(
|
||||
"This will prevent any future updates from being posted to this Slack channel. Are you sure?"
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user