Sfoglia il codice sorgente

Improved interfaces & fixed client

Taichi Masuyama 3 anni fa
parent
commit
fc1f7d58c2

+ 86 - 78
packages/app/src/components/Page/FixPageGrantAlert.tsx

@@ -8,13 +8,14 @@ import {
 import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { PageGrant } from '~/interfaces/page';
-import { useCurrentPageId } from '~/stores/context';
-import { IResApplicableGrant, useSWRxApplicableGrant, useSWRxIsGrantNormalized } from '~/stores/page';
+import { IRecordApplicableGrant } from '~/interfaces/page-grant';
+import { useCurrentPageId, useHasParent } from '~/stores/context';
+import { useSWRxApplicableGrant, useSWRxIsGrantNormalized } from '~/stores/page';
 
 type ModalProps = {
   isOpen: boolean
   pageId: string
-  dataApplicableGrant: IResApplicableGrant
+  dataApplicableGrant: IRecordApplicableGrant
   close(): void
 }
 
@@ -31,7 +32,7 @@ const FixPageGrantModal = (props: ModalProps): JSX.Element => {
   // Alert message state
   const [shouldShowModalAlert, setShowModalAlert] = useState<boolean>(false);
 
-  const applicableGroups = dataApplicableGrant.data.find(d => d.grant === PageGrant.GRANT_USER_GROUP)?.applicableGroups;
+  const applicableGroups = dataApplicableGrant[PageGrant.GRANT_USER_GROUP]?.applicableGroups;
 
   // Reset state when opened
   useEffect(() => {
@@ -63,8 +64,8 @@ const FixPageGrantModal = (props: ModalProps): JSX.Element => {
     toastSuccess();
   };
 
-  const renderModalBody = () => {
-    const isGrantAvailable = dataApplicableGrant.data.length > 0;
+  const renderModalBodyAndFooter = () => {
+    const isGrantAvailable = Object.keys(dataApplicableGrant || {}).length > 0;
 
     if (!isGrantAvailable) {
       return (
@@ -75,79 +76,86 @@ const FixPageGrantModal = (props: ModalProps): JSX.Element => {
     }
 
     return (
-      <ModalBody>
-        <div className="form-group grw-scrollable-modal-body">
-          <p className="mb-2">
-            You need to fix the grant of this page. Select new grant from below.
-          </p>
-          <div className="ml-2">
-            <div className="custom-control custom-radio mb-3">
-              <input
-                className="custom-control-input"
-                name="grantUser"
-                id="grantUser"
-                type="radio"
-                checked={selectedGrant === PageGrant.GRANT_OWNER}
-                onChange={() => setSelectedGrant(PageGrant.GRANT_OWNER)}
-              />
-              <label className="custom-control-label" htmlFor="grantUser">
-                { t('fix_page_grant.modal.radio_btn.only_me') }
-              </label>
-            </div>
-            <div className="custom-control custom-radio d-flex mb-3">
-              <input
-                className="custom-control-input"
-                name="grantUserGroup"
-                id="grantUserGroup"
-                type="radio"
-                checked={selectedGrant === PageGrant.GRANT_USER_GROUP}
-                onChange={() => setSelectedGrant(PageGrant.GRANT_USER_GROUP)}
-              />
-              <label className="custom-control-label" htmlFor="grantUserGroup">
-                { t('fix_page_grant.modal.radio_btn.grant_group') }
-              </label>
-              <div className="dropdown ml-2">
-                <div className="d-flex">
-                  <button
-                    type="button"
-                    className="btn btn-secondary dropdown-toggle text-right w-100 border-0 shadow-none"
-                    data-toggle="dropdown"
-                    disabled={selectedGrant !== PageGrant.GRANT_USER_GROUP} // disable when its radio input is not selected
-                  >
-                    <span className="float-left">
+      <>
+        <ModalBody>
+          <div className="form-group grw-scrollable-modal-body">
+            <p className="mb-2">
+              You need to fix the grant of this page. Select new grant from below.
+            </p>
+            <div className="ml-2">
+              <div className="custom-control custom-radio mb-3">
+                <input
+                  className="custom-control-input"
+                  name="grantUser"
+                  id="grantUser"
+                  type="radio"
+                  checked={selectedGrant === PageGrant.GRANT_OWNER}
+                  onChange={() => setSelectedGrant(PageGrant.GRANT_OWNER)}
+                />
+                <label className="custom-control-label" htmlFor="grantUser">
+                  { t('fix_page_grant.modal.radio_btn.only_me') }
+                </label>
+              </div>
+              <div className="custom-control custom-radio d-flex mb-3">
+                <input
+                  className="custom-control-input"
+                  name="grantUserGroup"
+                  id="grantUserGroup"
+                  type="radio"
+                  checked={selectedGrant === PageGrant.GRANT_USER_GROUP}
+                  onChange={() => setSelectedGrant(PageGrant.GRANT_USER_GROUP)}
+                />
+                <label className="custom-control-label" htmlFor="grantUserGroup">
+                  { t('fix_page_grant.modal.radio_btn.grant_group') }
+                </label>
+                <div className="dropdown ml-2">
+                  <div className="d-flex">
+                    <button
+                      type="button"
+                      className="btn btn-secondary dropdown-toggle text-right w-100 border-0 shadow-none"
+                      data-toggle="dropdown"
+                      disabled={selectedGrant !== PageGrant.GRANT_USER_GROUP} // disable when its radio input is not selected
+                    >
+                      <span className="float-left">
+                        {
+                          selectedGroupName == null
+                            ? t('fix_page_grant.modal.select_group_default_text')
+                            : selectedGroupName
+                        }
+                      </span>
+                    </button>
+                    <div className="dropdown-menu">
                       {
-                        selectedGroupName == null
-                          ? t('fix_page_grant.modal.select_group_default_text')
-                          : selectedGroupName
+                        applicableGroups != null && applicableGroups.map(g => (
+                          <button
+                            className="dropdown-item"
+                            type="button"
+                            onClick={() => setSelectedGroupName(g.name)}
+                          >
+                            {g.name}
+                          </button>
+                        ))
                       }
-                    </span>
-                  </button>
-                  <div className="dropdown-menu">
-                    {
-                      applicableGroups != null && applicableGroups.map(g => (
-                        <button
-                          className="dropdown-item"
-                          type="button"
-                          onClick={() => setSelectedGroupName(g.name)}
-                        >
-                          {g.name}
-                        </button>
-                      ))
-                    }
+                    </div>
                   </div>
                 </div>
               </div>
+              {
+                shouldShowModalAlert && (
+                  <p className="alert alert-warning">
+                    {t('fix_page_grant.modal.alert_message')}
+                  </p>
+                )
+              }
             </div>
-            {
-              shouldShowModalAlert && (
-                <p className="alert alert-warning">
-                  {t('fix_page_grant.modal.alert_message')}
-                </p>
-              )
-            }
           </div>
-        </div>
-      </ModalBody>
+        </ModalBody>
+        <ModalFooter>
+          <button type="button" className="btn btn-primary" onClick={submit}>
+            { t('fix_page_grant.modal.button_label') }
+          </button>
+        </ModalFooter>
+      </>
     );
   };
 
@@ -156,12 +164,7 @@ const FixPageGrantModal = (props: ModalProps): JSX.Element => {
       <ModalHeader tag="h4" toggle={close} className="bg-primary text-light">
         { t('fix_page_grant.modal.title') }
       </ModalHeader>
-      {renderModalBody()}
-      <ModalFooter>
-        <button type="button" className="btn btn-primary" onClick={submit}>
-          { t('fix_page_grant.modal.button_label') }
-        </button>
-      </ModalFooter>
+      {renderModalBodyAndFooter()}
     </Modal>
   );
 };
@@ -172,9 +175,14 @@ const FixPageGrantAlert = (): JSX.Element => {
   const [isOpen, setOpen] = useState<boolean>(false);
 
   const { data: pageId } = useCurrentPageId();
+  const { data: hasParent } = useHasParent();
   const { data: dataIsGrantNormalized } = useSWRxIsGrantNormalized(pageId);
   const { data: dataApplicableGrant } = useSWRxApplicableGrant(pageId);
 
+  // Dependencies
+  if (!hasParent) {
+    return <></>;
+  }
   if (dataIsGrantNormalized?.isGrantNormalized == null || dataIsGrantNormalized.isGrantNormalized) {
     return <></>;
   }

+ 11 - 0
packages/app/src/interfaces/page-grant.ts

@@ -0,0 +1,11 @@
+import { PageGrant } from './page';
+
+export type IDataApplicableGroup = {
+  applicableGroups?: {_id: string, name: string}[] // TODO: Typescriptize model
+}
+
+export type IDataApplicableGrant = null | IDataApplicableGroup;
+export type IRecordApplicableGrant = Record<PageGrant, IDataApplicableGrant>
+export type IResApplicableGrant = {
+  data?: IRecordApplicableGrant
+}

+ 4 - 10
packages/app/src/stores/page.tsx

@@ -1,12 +1,13 @@
 import useSWR, { SWRResponse } from 'swr';
-import useSWRInfinite, { SWRInfiniteResponse } from 'swr/infinite';
 import useSWRImmutable from 'swr/immutable';
+import useSWRInfinite, { SWRInfiniteResponse } from 'swr/infinite';
 
 import { apiv3Get } from '~/client/util/apiv3-client';
 import { HasObjectId } from '~/interfaces/has-object-id';
 import {
-  IPageInfo, IPageHasId, IPageInfoForOperation, IPageInfoForListing, IDataWithMeta, PageGrant,
+  IPageInfo, IPageHasId, IPageInfoForOperation, IPageInfoForListing, IDataWithMeta,
 } from '~/interfaces/page';
+import { IRecordApplicableGrant } from '~/interfaces/page-grant';
 import { IPagingResult } from '~/interfaces/paging-result';
 
 import { apiGet } from '../client/util/apiv1-client';
@@ -161,16 +162,9 @@ export const useSWRxIsGrantNormalized = (
   );
 };
 
-export type IApplicableGrant = {
-  grant: PageGrant
-  applicableGroups?: {_id: string, name: string}[] // TODO: Typescriptize model
-}
-export type IResApplicableGrant = {
-  data: IApplicableGrant[]
-}
 export const useSWRxApplicableGrant = (
     pageId: string | null | undefined,
-): SWRResponse<IResApplicableGrant, Error> => {
+): SWRResponse<IRecordApplicableGrant, Error> => {
 
   return useSWRImmutable(
     pageId != null ? ['/page/applicable-grant', pageId] : null,