From fa52bc5afdb5fa15d65a3c52a6a2287f27fc9582 Mon Sep 17 00:00:00 2001
From: Tom Moor
Date: Sun, 18 Apr 2021 18:34:49 -0700
Subject: [PATCH] chore: Slack integration screen improvements (#2049)
* feat: Add collection iconography and colors to Slack settings page
fix: Use standardized list components
fix: Slack icon size
chore: Convert to translation strings
* fix: Missing translation, convert to Scene
---
app/components/{ => AuthLogo}/SlackLogo.js | 0
app/components/AuthLogo/index.js | 2 +-
app/components/Sidebar/Settings.js | 4 +-
.../{Sidebar/icons/Slack.js => SlackIcon.js} | 0
.../icons/Zapier.js => ZapierIcon.js} | 0
app/scenes/Settings/Slack.js | 206 +++++++++---------
app/scenes/Settings/components/SlackButton.js | 23 +-
package.json | 2 +-
server/auth/providers/slack.js | 2 +-
server/models/User.js | 10 +-
shared/i18n/locales/en_US/translation.json | 8 +
11 files changed, 130 insertions(+), 127 deletions(-)
rename app/components/{ => AuthLogo}/SlackLogo.js (100%)
rename app/components/{Sidebar/icons/Slack.js => SlackIcon.js} (100%)
rename app/components/{Sidebar/icons/Zapier.js => ZapierIcon.js} (100%)
diff --git a/app/components/SlackLogo.js b/app/components/AuthLogo/SlackLogo.js
similarity index 100%
rename from app/components/SlackLogo.js
rename to app/components/AuthLogo/SlackLogo.js
diff --git a/app/components/AuthLogo/index.js b/app/components/AuthLogo/index.js
index c7d0d66f..d2b444f2 100644
--- a/app/components/AuthLogo/index.js
+++ b/app/components/AuthLogo/index.js
@@ -1,9 +1,9 @@
// @flow
import * as React from "react";
import styled from "styled-components";
-import SlackLogo from "../SlackLogo";
import GoogleLogo from "./GoogleLogo";
import MicrosoftLogo from "./MicrosoftLogo";
+import SlackLogo from "./SlackLogo";
type Props = {|
providerName: string,
diff --git a/app/components/Sidebar/Settings.js b/app/components/Sidebar/Settings.js
index 72ac4d03..240d1812 100644
--- a/app/components/Sidebar/Settings.js
+++ b/app/components/Sidebar/Settings.js
@@ -19,14 +19,14 @@ import styled from "styled-components";
import Flex from "components/Flex";
import Scrollable from "components/Scrollable";
+import SlackIcon from "components/SlackIcon";
+import ZapierIcon from "components/ZapierIcon";
import Sidebar from "./Sidebar";
import Header from "./components/Header";
import Section from "./components/Section";
import SidebarLink from "./components/SidebarLink";
import TeamButton from "./components/TeamButton";
import Version from "./components/Version";
-import SlackIcon from "./icons/Slack";
-import ZapierIcon from "./icons/Zapier";
import env from "env";
import useCurrentTeam from "hooks/useCurrentTeam";
import useStores from "hooks/useStores";
diff --git a/app/components/Sidebar/icons/Slack.js b/app/components/SlackIcon.js
similarity index 100%
rename from app/components/Sidebar/icons/Slack.js
rename to app/components/SlackIcon.js
diff --git a/app/components/Sidebar/icons/Zapier.js b/app/components/ZapierIcon.js
similarity index 100%
rename from app/components/Sidebar/icons/Zapier.js
rename to app/components/ZapierIcon.js
diff --git a/app/scenes/Settings/Slack.js b/app/scenes/Settings/Slack.js
index 1e58d1e7..83eee9e8 100644
--- a/app/scenes/Settings/Slack.js
+++ b/app/scenes/Settings/Slack.js
@@ -1,138 +1,136 @@
// @flow
import { find } from "lodash";
-import { inject, observer } from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
+import { useTranslation, Trans } from "react-i18next";
import styled from "styled-components";
import getQueryVariable from "shared/utils/getQueryVariable";
-import AuthStore from "stores/AuthStore";
-import CollectionsStore from "stores/CollectionsStore";
-import IntegrationsStore from "stores/IntegrationsStore";
import Button from "components/Button";
-import CenteredContent from "components/CenteredContent";
+import CollectionIcon from "components/CollectionIcon";
+import Heading from "components/Heading";
import HelpText from "components/HelpText";
+import List from "components/List";
+import ListItem from "components/List/Item";
import Notice from "components/Notice";
-import PageTitle from "components/PageTitle";
+import Scene from "components/Scene";
+import SlackIcon from "components/SlackIcon";
import SlackButton from "./components/SlackButton";
import env from "env";
+import useCurrentTeam from "hooks/useCurrentTeam";
+import useStores from "hooks/useStores";
-type Props = {
- collections: CollectionsStore,
- integrations: IntegrationsStore,
- auth: AuthStore,
-};
+function Slack() {
+ const team = useCurrentTeam();
+ const { collections, integrations } = useStores();
+ const { t } = useTranslation();
+ const error = getQueryVariable("error");
-@observer
-class Slack extends React.Component {
- error: ?string;
+ React.useEffect(() => {
+ collections.fetchPage({ limit: 100 });
+ integrations.fetchPage({ limit: 100 });
+ }, [collections, integrations]);
- componentDidMount() {
- this.error = getQueryVariable("error");
- this.props.collections.fetchPage({ limit: 100 });
- this.props.integrations.fetchPage();
- }
+ const commandIntegration = find(integrations.slackIntegrations, {
+ type: "command",
+ });
- get commandIntegration() {
- return find(this.props.integrations.slackIntegrations, {
- type: "command",
- });
- }
-
- render() {
- const { collections, integrations, auth } = this.props;
- const teamId = auth.team ? auth.team.id : "";
-
- return (
-
-
-
Slack
- {this.error === "access_denied" && (
-
+ return (
+ }>
+ Slack
+ {error === "access_denied" && (
+
+
Whoops, you need to accept the permissions in Slack to connect
Outline to your team. Try again?
-
- )}
- {this.error === "unauthenticated" && (
-
+
+
+ )}
+ {error === "unauthenticated" && (
+
+
Something went wrong while authenticating your request. Please try
logging in again?
-
+
+
+ )}
+
+ }}
+ />
+
+
+ {commandIntegration ? (
+
+ ) : (
+
)}
-
- Preview Outline links your team mates share and use the{" "}
- /outline slash command in Slack to search for documents
- in your team’s wiki.
-
-
- {this.commandIntegration ? (
-
- ) : (
-
- )}
-
-
+
+
-
Collections
-
+
{t("Collections")}
+
+
Connect Outline collections to Slack channels and messages will be
- posted in Slack when documents are published or updated.
-
+ automatically posted to Slack when documents are published or updated.
+
+
-
- {collections.orderedData.map((collection) => {
- const integration = find(integrations.slackIntegrations, {
- collectionId: collection.id,
- });
-
- if (integration) {
- return (
-
-
- {collection.name} posting activity to the{" "}
- {integration.settings.channel} Slack
- channel
-
-
-
- );
- }
+
+ {collections.orderedData.map((collection) => {
+ const integration = find(integrations.slackIntegrations, {
+ collectionId: collection.id,
+ });
+ if (integration) {
return (
-
- {collection.name}
+ }
+ subtitle={
+ {{ channelName }} channel`}
+ values={{ channelName: integration.settings.channel }}
+ components={{ em: }}
+ />
+ }
+ actions={
+
+ }
+ />
+ );
+ }
+
+ return (
+ }
+ actions={
-
- );
- })}
-
-
- );
- }
+ }
+ />
+ );
+ })}
+
+
+ );
}
-const List = styled.ol`
- list-style: none;
- margin: 8px 0;
- padding: 0;
-`;
-
-const ListItem = styled.li`
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 8px 0;
- border-bottom: 1px solid #eaebea;
-`;
-
const Code = styled.code`
padding: 4px 6px;
margin: 0 2px;
@@ -140,4 +138,4 @@ const Code = styled.code`
border-radius: 4px;
`;
-export default inject("collections", "integrations", "auth")(Slack);
+export default observer(Slack);
diff --git a/app/scenes/Settings/components/SlackButton.js b/app/scenes/Settings/components/SlackButton.js
index fec74ee7..7eeefe88 100644
--- a/app/scenes/Settings/components/SlackButton.js
+++ b/app/scenes/Settings/components/SlackButton.js
@@ -1,19 +1,20 @@
// @flow
import * as React from "react";
-import styled from "styled-components";
+import { useTranslation } from "react-i18next";
import { slackAuth } from "shared/utils/routeHelpers";
import Button from "components/Button";
-import SlackLogo from "components/SlackLogo";
+import SlackIcon from "components/SlackIcon";
import env from "env";
-type Props = {
+type Props = {|
scopes?: string[],
redirectUri: string,
state?: string,
label?: string,
-};
+|};
function SlackButton({ state = "", scopes, redirectUri, label }: Props) {
+ const { t } = useTranslation();
const handleClick = () =>
(window.location.href = slackAuth(
state,
@@ -25,22 +26,12 @@ function SlackButton({ state = "", scopes, redirectUri, label }: Props) {
return (
}
+ icon={}
neutral
>
- {label ? (
- label
- ) : (
-
- Add to Slack
-
- )}
+ {label || t("Add to Slack")}
);
}
-const SpacedSlackLogo = styled(SlackLogo)`
- padding-right: 4px;
-`;
-
export default SlackButton;
diff --git a/package.json b/package.json
index bfedc8ef..0fc919b4 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"build:webpack": "webpack --config webpack.config.prod.js",
"build": "yarn clean && yarn build:webpack && yarn build:i18n && yarn build:server",
"start": "node ./build/server/index.js",
- "dev": "nodemon --exec \"yarn build:server && yarn build:i18n && node build/server/index.js\" -e js --ignore build/ --ignore app/",
+ "dev": "nodemon --exec \"yarn build:server && yarn build:i18n && node --inspect=0.0.0.0 build/server/index.js\" -e js --ignore build/ --ignore app/",
"lint": "eslint app server shared",
"deploy": "git push heroku master",
"heroku-postbuild": "yarn build && yarn db:migrate",
diff --git a/server/auth/providers/slack.js b/server/auth/providers/slack.js
index 3c1e8acd..bedec9bb 100644
--- a/server/auth/providers/slack.js
+++ b/server/auth/providers/slack.js
@@ -149,7 +149,7 @@ if (SLACK_CLIENT_ID) {
}
// this code block accounts for the root domain being unable to
- // access authentcation for subdomains. We must forward to the
+ // access authentication for subdomains. We must forward to the
// appropriate subdomain to complete the oauth flow
if (!user) {
try {
diff --git a/server/models/User.js b/server/models/User.js
index 8842c56a..439e7d0e 100644
--- a/server/models/User.js
+++ b/server/models/User.js
@@ -10,8 +10,14 @@ import { sendEmail } from "../mailer";
import { DataTypes, sequelize, encryptedFields, Op } from "../sequelize";
import { DEFAULT_AVATAR_HOST } from "../utils/avatars";
import { publicS3Endpoint, uploadToS3FromUrl } from "../utils/s3";
-import UserAuthentication from "./UserAuthentication";
-import { Star, Team, Collection, NotificationSetting, ApiKey } from ".";
+import {
+ UserAuthentication,
+ Star,
+ Team,
+ Collection,
+ NotificationSetting,
+ ApiKey,
+} from ".";
const User = sequelize.define(
"user",
diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json
index 60f27277..a8b3071e 100644
--- a/shared/i18n/locales/en_US/translation.json
+++ b/shared/i18n/locales/en_US/translation.json
@@ -348,6 +348,7 @@
"Shared": "Shared",
"by {{ name }}": "by {{ name }}",
"Last accessed": "Last accessed",
+ "Add to Slack": "Add to Slack",
"Import started": "Import started",
"Export in progress…": "Export in progress…",
"It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. Support will soon be added for importing from other services.": "It is possible to import a zip file of folders and Markdown files previously exported from an Outline instance. Support will soon be added for importing from other services.",
@@ -384,6 +385,13 @@
"You can globally enable and disable public document sharing in the security settings.": "You can globally enable and disable public document sharing in the security settings.",
"Shared documents": "Shared documents",
"No share links, yet.": "No share links, yet.",
+ "Whoops, you need to accept the permissions in Slack to connect Outline to your team. Try again?": "Whoops, you need to accept the permissions in Slack to connect Outline to your team. Try again?",
+ "Something went wrong while authenticating your request. Please try logging in again?": "Something went wrong while authenticating your request. Please try logging in again?",
+ "Get rich previews of Outline links shared in Slack and use the {{ command }} slash command to search for documents without leaving your chat.": "Get rich previews of Outline links shared in Slack and use the {{ command }} slash command to search for documents without leaving your chat.",
+ "Connect Outline collections to Slack channels and messages will be automatically posted to Slack when documents are published or updated.": "Connect Outline collections to Slack channels and messages will be automatically posted to Slack when documents are published or updated.",
+ "Connected to the {{ channelName }} channel": "Connected to the {{ channelName }} channel",
+ "Disconnect": "Disconnect",
+ "Connect": "Connect",
"You’ve not starred any documents yet.": "You’ve not starred any documents yet.",
"There are no templates just yet.": "There are no templates just yet.",
"You can create templates to help your team create consistent and accurate documentation.": "You can create templates to help your team create consistent and accurate documentation.",