Просмотр исходного кода

imprv: Use SWR for isSlackEnabled (#4827)

* impl

* cleanup

* removed console.log

* wip fb fix

* change ordering

* revert

* revert

* optional props

* err fix

* Update EditorNavbarBottom.tsx

Co-authored-by: Yuki Takei <yuki@weseek.co.jp>
stevenfukase 4 лет назад
Родитель
Сommit
6ddb326572

+ 0 - 1
packages/app/src/client/services/EditorContainer.js

@@ -27,7 +27,6 @@ export default class EditorContainer extends Container {
     this.state = {
       tags: null,
 
-      isSlackEnabled: false,
       slackChannels: mainContent.getAttribute('data-slack-channels') || '',
 
       grant: 1, // default: public

+ 1 - 1
packages/app/src/components/PageComment/CommentEditor.jsx

@@ -17,7 +17,7 @@ import GrowiRenderer from '~/client/util/GrowiRenderer';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import Editor from '../PageEditor/Editor';
-import SlackNotification from '../SlackNotification';
+import { SlackNotification } from '../SlackNotification';
 
 import CommentPreview from './CommentPreview';
 import NotAvailableForGuest from '../NotAvailableForGuest';

+ 13 - 14
packages/app/src/components/PageEditor/EditorNavbarBottom.jsx → packages/app/src/components/PageEditor/EditorNavbarBottom.tsx

@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useCallback, useState } from 'react';
 import PropTypes from 'prop-types';
 
 import { Collapse, Button } from 'reactstrap';
@@ -9,13 +9,14 @@ import {
   EditorMode, useDrawerOpened, useEditorMode, useIsDeviceSmallerThanMd,
 } from '~/stores/ui';
 
-import SlackNotification from '../SlackNotification';
+import { SlackNotification } from '../SlackNotification';
 import SlackLogo from '../SlackLogo';
 import { withUnstatedContainers } from '../UnstatedUtils';
 
 import SavePageControls from '../SavePageControls';
 
 import OptionsSelector from './OptionsSelector';
+import { useIsSlackEnabled } from '~/stores/editor';
 
 const EditorNavbarBottom = (props) => {
 
@@ -28,9 +29,13 @@ const EditorNavbarBottom = (props) => {
 
   const { mutate: mutateDrawerOpened } = useDrawerOpened();
   const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
-
+  const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useIsSlackEnabled();
   const additionalClasses = ['grw-editor-navbar-bottom'];
 
+  const isSlackEnabledToggleHandler = useCallback(
+    bool => mutateIsSlackEnabled(bool), [mutateIsSlackEnabled],
+  );
+
   const renderDrawerButton = () => (
     <button
       type="button"
@@ -41,10 +46,6 @@ const EditorNavbarBottom = (props) => {
     </button>
   );
 
-  const slackEnabledFlagChangedHandler = (isSlackEnabled) => {
-    props.editorContainer.setState({ isSlackEnabled });
-  };
-
   const slackChannelsChangedHandler = (slackChannels) => {
     props.editorContainer.setState({ slackChannels });
   };
@@ -69,15 +70,14 @@ const EditorNavbarBottom = (props) => {
     <div className={`${isCollapsedOptionsSelectorEnabled ? 'fixed-bottom' : ''} `}>
       {/* Collapsed SlackNotification */}
       {isSlackConfigured && (
-        <Collapse isOpen={isSlackExpanded && isDeviceSmallerThanMd}>
+        <Collapse isOpen={isSlackExpanded && isDeviceSmallerThanMd === true}>
           <nav className={`navbar navbar-expand-lg border-top ${additionalClasses.join(' ')}`}>
             <SlackNotification
-              isSlackEnabled={props.editorContainer.state.isSlackEnabled}
+              isSlackEnabled={isSlackEnabled ?? false}
               slackChannels={props.editorContainer.state.slackChannels}
-              onEnabledFlagChange={slackEnabledFlagChangedHandler}
+              onEnabledFlagChange={isSlackEnabledToggleHandler}
               onChannelChange={slackChannelsChangedHandler}
               id="idForEditorNavbarBottomForMobile"
-              popUp
             />
           </nav>
         </Collapse>
@@ -104,12 +104,11 @@ const EditorNavbarBottom = (props) => {
           ) : (
             <div className="mr-2">
               <SlackNotification
-                isSlackEnabled={props.editorContainer.state.isSlackEnabled}
+                isSlackEnabled={isSlackEnabled ?? false}
                 slackChannels={props.editorContainer.state.slackChannels}
-                onEnabledFlagChange={slackEnabledFlagChangedHandler}
+                onEnabledFlagChange={isSlackEnabledToggleHandler}
                 onChannelChange={slackChannelsChangedHandler}
                 id="idForEditorNavbarBottom"
-                popUp={false}
               />
             </div>
           ))}

+ 0 - 87
packages/app/src/components/SlackNotification.jsx

@@ -1,87 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { withTranslation } from 'react-i18next';
-import { UncontrolledPopover, PopoverHeader, PopoverBody } from 'reactstrap';
-/**
- *
- * @author Yuki Takei <yuki@weseek.co.jp>
- *
- * @export
- * @class SlackNotification
- * @extends {React.Component}
- */
-
-class SlackNotification extends React.Component {
-
-  constructor(props) {
-    super(props);
-    this.idForSlackPopover = `${this.props.id}ForSlackPopover`;
-    this.updateCheckboxHandler = this.updateCheckboxHandler.bind(this);
-    this.updateSlackChannelsHandler = this.updateSlackChannelsHandler.bind(this);
-  }
-
-  updateCheckboxHandler(event) {
-    const value = event.target.checked;
-    if (this.props.onEnabledFlagChange != null) {
-      this.props.onEnabledFlagChange(value);
-    }
-  }
-
-  updateSlackChannelsHandler(event) {
-    const value = event.target.value;
-    if (this.props.onChannelChange != null) {
-      this.props.onChannelChange(value);
-    }
-  }
-
-  render() {
-    const { t } = this.props;
-
-    return (
-      <div className="grw-slack-notification w-100">
-        <div className="grw-input-group-slack-notification input-group extended-setting">
-          <label className="input-group-addon">
-            <div className="custom-control custom-switch custom-switch-lg custom-switch-slack">
-              <input
-                type="checkbox"
-                className="custom-control-input border-0"
-                id={this.props.id}
-                checked={this.props.isSlackEnabled}
-                onChange={this.updateCheckboxHandler}
-              />
-              <label className="custom-control-label align-center" htmlFor={this.props.id}>
-              </label>
-            </div>
-          </label>
-          <input
-            className="grw-form-control-slack-notification form-control align-top pl-0"
-            id={this.idForSlackPopover}
-            type="text"
-            value={this.props.slackChannels}
-            placeholder="Input channels"
-            onChange={this.updateSlackChannelsHandler}
-          />
-          <UncontrolledPopover trigger="focus" placement="top" target={this.idForSlackPopover}>
-            <PopoverHeader>{t('slack_notification.popover_title')}</PopoverHeader>
-            <PopoverBody>{t('slack_notification.popover_desc')}</PopoverBody>
-          </UncontrolledPopover>
-        </div>
-      </div>
-    );
-  }
-
-}
-
-SlackNotification.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-
-  popUp: PropTypes.bool.isRequired,
-  isSlackEnabled: PropTypes.bool.isRequired,
-  slackChannels: PropTypes.string.isRequired,
-  onEnabledFlagChange: PropTypes.func,
-  onChannelChange: PropTypes.func,
-  id: PropTypes.string.isRequired,
-};
-
-export default withTranslation()(SlackNotification);

+ 67 - 0
packages/app/src/components/SlackNotification.tsx

@@ -0,0 +1,67 @@
+/* eslint-disable react/prop-types */
+import React, { FC } from 'react';
+import { useTranslation } from 'react-i18next';
+import { PopoverBody, PopoverHeader, UncontrolledPopover } from 'reactstrap';
+
+
+type SlackNotificationProps = {
+  id: string;
+  isSlackEnabled: boolean;
+  slackChannels: string;
+  onEnabledFlagChange?: (isSlackEnabled: boolean) => void;
+  onChannelChange?: (value: string) => void;
+};
+
+export const SlackNotification: FC<SlackNotificationProps> = ({
+  id, isSlackEnabled, slackChannels, onEnabledFlagChange, onChannelChange,
+}) => {
+  const { t } = useTranslation();
+  const idForSlackPopover = `${id}ForSlackPopover`;
+
+  const updateCheckboxHandler = (event: { target: { checked: boolean }; }) => {
+    const value = event.target.checked;
+    if (onEnabledFlagChange != null) {
+      onEnabledFlagChange(value);
+    }
+  };
+
+  const updateSlackChannelsHandler = (event: { target: { value: string } }) => {
+    const value = event.target.value;
+    if (onChannelChange != null) {
+      onChannelChange(value);
+    }
+  };
+
+
+  return (
+    <div className="grw-slack-notification w-100">
+      <div className="grw-input-group-slack-notification input-group extended-setting">
+        <label className="input-group-addon">
+          <div className="custom-control custom-switch custom-switch-lg custom-switch-slack">
+            <input
+              type="checkbox"
+              className="custom-control-input border-0"
+              id={id}
+              checked={isSlackEnabled}
+              onChange={updateCheckboxHandler}
+            />
+            <label className="custom-control-label align-center" htmlFor={id}></label>
+          </div>
+        </label>
+        <input
+          className="grw-form-control-slack-notification form-control align-top pl-0"
+          id={idForSlackPopover}
+          type="text"
+          value={slackChannels}
+          placeholder="Input channels"
+          onChange={updateSlackChannelsHandler}
+        />
+        <UncontrolledPopover trigger="focus" placement="top" target={idForSlackPopover}>
+          <PopoverHeader>{t('slack_notification.popover_title')}</PopoverHeader>
+          <PopoverBody>{t('slack_notification.popover_desc')}</PopoverBody>
+        </UncontrolledPopover>
+      </div>
+    </div>
+
+  );
+};

+ 9 - 0
packages/app/src/stores/editor.tsx

@@ -0,0 +1,9 @@
+import { SWRResponse } from 'swr';
+import { useStaticSWR } from './use-static-swr';
+
+export const useIsSlackEnabled = (isEnabled?: boolean): SWRResponse<boolean, Error> => {
+  const initialData = false;
+  return (
+    useStaticSWR('isSlackEnabled', isEnabled || null, { fallbackData: initialData })
+  );
+};