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

Merge pull request #6493 from weseek/support/sharelink-ts-fc-swr

Support/sharelink ts fc swr
Yohei Shiina 3 лет назад
Родитель
Сommit
b4a9f6d402

+ 0 - 130
packages/app/src/components/ShareLink/ShareLink.jsx

@@ -1,130 +0,0 @@
-import React from 'react';
-
-import PropTypes from 'prop-types';
-import { useTranslation } from 'next-i18next';
-
-
-import PageContainer from '~/client/services/PageContainer';
-import { toastSuccess, toastError } from '~/client/util/apiNotification';
-import { apiv3Delete, apiv3Get } from '~/client/util/apiv3-client';
-
-import { withUnstatedContainers } from '../UnstatedUtils';
-
-import ShareLinkForm from './ShareLinkForm';
-import ShareLinkList from './ShareLinkList';
-
-class ShareLink extends React.Component {
-
-  constructor() {
-    super();
-    this.state = {
-      shareLinks: [],
-      isOpenShareLinkForm: false,
-    };
-
-    this.toggleShareLinkFormHandler = this.toggleShareLinkFormHandler.bind(this);
-    this.deleteAllLinksButtonHandler = this.deleteAllLinksButtonHandler.bind(this);
-    this.deleteLinkById = this.deleteLinkById.bind(this);
-  }
-
-  componentDidMount() {
-    this.retrieveShareLinks();
-  }
-
-  async retrieveShareLinks() {
-    const { pageContainer } = this.props;
-    const { pageId } = pageContainer.state;
-
-    try {
-      const res = await apiv3Get('/share-links/', { relatedPage: pageId });
-      const { shareLinksResult } = res.data;
-      this.setState({ shareLinks: shareLinksResult });
-    }
-    catch (err) {
-      toastError(err);
-    }
-
-  }
-
-  toggleShareLinkFormHandler() {
-    this.setState({ isOpenShareLinkForm: !this.state.isOpenShareLinkForm });
-    this.retrieveShareLinks();
-  }
-
-  async deleteAllLinksButtonHandler() {
-    const { t, pageContainer } = this.props;
-    const { pageId } = pageContainer.state;
-
-    try {
-      const res = await apiv3Delete('/share-links/', { relatedPage: pageId });
-      const count = res.data.n;
-      toastSuccess(t('toaster.remove_share_link', { count }));
-    }
-    catch (err) {
-      toastError(err);
-    }
-
-    this.retrieveShareLinks();
-  }
-
-  async deleteLinkById(shareLinkId) {
-    const { t } = this.props;
-
-    try {
-      const res = await apiv3Delete(`/share-links/${shareLinkId}`);
-      const { deletedShareLink } = res.data;
-      toastSuccess(t('toaster.remove_share_link_success', { shareLinkId: deletedShareLink._id }));
-    }
-    catch (err) {
-      toastError(err);
-    }
-
-    this.retrieveShareLinks();
-  }
-
-  render() {
-    const { t } = this.props;
-
-    return (
-      <div className="container p-0" data-testid="share-link-management">
-        <h3 className="grw-modal-head d-flex pb-2">
-          { t('share_links.share_link_list') }
-          <button className="btn btn-danger ml-auto " type="button" onClick={this.deleteAllLinksButtonHandler}>{t('delete_all')}</button>
-        </h3>
-
-        <div>
-          <ShareLinkList
-            shareLinks={this.state.shareLinks}
-            onClickDeleteButton={this.deleteLinkById}
-          />
-          <button
-            className="btn btn-outline-secondary d-block mx-auto px-5"
-            type="button"
-            onClick={this.toggleShareLinkFormHandler}
-          >
-            {this.state.isOpenShareLinkForm ? t('Close') : t('New')}
-          </button>
-          {this.state.isOpenShareLinkForm && <ShareLinkForm onCloseForm={this.toggleShareLinkFormHandler} />}
-        </div>
-      </div>
-    );
-  }
-
-}
-
-ShareLink.propTypes = {
-  t: PropTypes.func.isRequired, //  i18next
-  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
-};
-
-const ShareLinkWrapperFC = (props) => {
-  const { t } = useTranslation();
-  return <ShareLink t={t} {...props} />;
-};
-
-/**
- * Wrapper component for using unstated
- */
-const ShareLinkWrapper = withUnstatedContainers(ShareLinkWrapperFC, [PageContainer]);
-
-export default ShareLinkWrapper;

+ 76 - 0
packages/app/src/components/ShareLink/ShareLink.tsx

@@ -0,0 +1,76 @@
+import React, {
+  useState, useCallback,
+} from 'react';
+
+import { useTranslation } from 'react-i18next';
+
+import { toastSuccess, toastError } from '~/client/util/apiNotification';
+import { apiv3Delete } from '~/client/util/apiv3-client';
+import { useCurrentPageId } from '~/stores/context';
+import { useSWRxSharelink } from '~/stores/share-link';
+
+import ShareLinkForm from './ShareLinkForm';
+import ShareLinkList from './ShareLinkList';
+
+const ShareLink = (): JSX.Element => {
+  const { t } = useTranslation();
+  const [isOpenShareLinkForm, setIsOpenShareLinkForm] = useState<boolean>(false);
+
+  const { data: currentPageId } = useCurrentPageId();
+
+  const { data: currentShareLinks, mutate } = useSWRxSharelink(currentPageId);
+
+  const toggleShareLinkFormHandler = useCallback(() => {
+    setIsOpenShareLinkForm(prev => !prev);
+    mutate();
+  }, [mutate]);
+
+  const deleteAllLinksButtonHandler = useCallback(async() => {
+    try {
+      const res = await apiv3Delete('/share-links/', { relatedPage: currentPageId });
+      const count = res.data.n;
+      toastSuccess(t('toaster.remove_share_link', { count }));
+      mutate();
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, [mutate, currentPageId, t]);
+
+  const deleteLinkById = useCallback(async(shareLinkId) => {
+    try {
+      const res = await apiv3Delete(`/share-links/${shareLinkId}`);
+      const { deletedShareLink } = res.data;
+      toastSuccess(t('toaster.remove_share_link_success', { shareLinkId: deletedShareLink._id }));
+      mutate();
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, [mutate, t]);
+
+  return (
+    <div className="container p-0" data-testid="share-link-management">
+      <h3 className="grw-modal-head d-flex pb-2">
+        { t('share_links.share_link_list') }
+        <button className="btn btn-danger ml-auto " type="button" onClick={deleteAllLinksButtonHandler}>{t('delete_all')}</button>
+      </h3>
+      <div>
+        <ShareLinkList
+          shareLinks={currentShareLinks == null ? [] : currentShareLinks}
+          onClickDeleteButton={deleteLinkById}
+        />
+        <button
+          className="btn btn-outline-secondary d-block mx-auto px-5"
+          type="button"
+          onClick={toggleShareLinkFormHandler}
+        >
+          {isOpenShareLinkForm ? t('Close') : t('New')}
+        </button>
+        {isOpenShareLinkForm && <ShareLinkForm onCloseForm={toggleShareLinkFormHandler} />}
+      </div>
+    </div>
+  );
+};
+
+export default ShareLink;

+ 4 - 0
packages/app/src/interfaces/share-link.ts

@@ -0,0 +1,4 @@
+// Todo: specify more detailed Type
+export type IResShareLinkList = {
+  shareLinksResult: any[],
+};

+ 14 - 0
packages/app/src/stores/share-link.tsx

@@ -0,0 +1,14 @@
+import { Nullable } from '@growi/core';
+import useSWR, { SWRResponse } from 'swr';
+
+import { apiv3Get } from '~/client/util/apiv3-client';
+import { IResShareLinkList } from '~/interfaces/share-link';
+
+const fetchShareLinks = async(endpoint, pageId) => {
+  const res = await apiv3Get<IResShareLinkList>(endpoint, { relatedPage: pageId });
+  return res.data.shareLinksResult;
+};
+
+export const useSWRxSharelink = (currentPageId: Nullable<string>): SWRResponse<IResShareLinkList['shareLinksResult'], Error> => {
+  return useSWR(currentPageId == null ? null : ['/share-links/', currentPageId], (endpoint => fetchShareLinks(endpoint, currentPageId)));
+};