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

impl useSWRxMyUserGroupRelations

Yuki Takei 4 лет назад
Родитель
Сommit
9b4dd2f6c8

+ 20 - 16
packages/app/src/components/SavePageControls/GrantSelector.tsx

@@ -10,9 +10,10 @@ import {
 
 
 import AppContainer from '~/client/services/AppContainer';
-import { apiGet } from '~/client/util/apiv1-client';
+import { isNotRef } from '~/interfaces/common';
 import { IUserGroupHasId } from '~/interfaces/user';
 import { useCurrentUser } from '~/stores/context';
+import { useSWRxMyUserGroupRelations } from '~/stores/user-group';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 
@@ -58,26 +59,15 @@ const GrantSelector = (props: Props): JSX.Element => {
   } = props;
 
 
-  const [userRelatedGroups, setUserRelatedGroups] = useState<IUserGroupHasId[]>([]);
   const [isSelectGroupModalShown, setIsSelectGroupModalShown] = useState(false);
 
   const { data: currentUser } = useCurrentUser();
-
-  /**
-   * Retrieve user-group-relations data from backend
-   */
-  const retrieveUserGroupRelations = async() => {
-    const res = await apiGet('/me/user-group-relations') as any;
-    const userRelatedGroups = res.userGroupRelations.map((relation) => {
-      return relation.relatedGroup;
-    });
-    setUserRelatedGroups(userRelatedGroups);
-  };
+  const { data: myUserGroupRelations, mutate: mutateMyUserGroupRelations } = useSWRxMyUserGroupRelations();
 
   const showSelectGroupModal = useCallback(() => {
-    retrieveUserGroupRelations();
+    mutateMyUserGroupRelations();
     setIsSelectGroupModalShown(true);
-  }, []);
+  }, [mutateMyUserGroupRelations]);
 
   /**
    * change event handler for grant selector
@@ -170,6 +160,20 @@ const GrantSelector = (props: Props): JSX.Element => {
       return <></>;
     }
 
+    // show spinner
+    if (myUserGroupRelations === undefined) {
+      return <i className="fa fa-lg fa-spinner fa-pulse mx-auto text-muted"></i>;
+    }
+
+    // extract IUserGroupHasId
+    const userRelatedGroups: IUserGroupHasId[] = myUserGroupRelations
+      .map((relation) => {
+        // relation.relatedGroup should be populated by server
+        return isNotRef(relation.relatedGroup) ? relation.relatedGroup : undefined;
+      })
+      // exclude undefined elements
+      .filter((elem): elem is IUserGroupHasId => elem != null);
+
     const generateGroupListItems = () => {
       return userRelatedGroups.map((group) => {
         return (
@@ -210,7 +214,7 @@ const GrantSelector = (props: Props): JSX.Element => {
         </ModalBody>
       </Modal>
     );
-  }, [currentUser, groupListItemClickHandler, isSelectGroupModalShown, t, userRelatedGroups]);
+  }, [currentUser, groupListItemClickHandler, isSelectGroupModalShown, myUserGroupRelations, t]);
 
   return (
     <React.Fragment>

+ 4 - 0
packages/app/src/interfaces/common.ts

@@ -9,3 +9,7 @@ import { HasObjectId } from './has-object-id';
 export type Ref<T> = string | T & HasObjectId;
 
 export type Nullable<T> = T | null | undefined;
+
+export const isNotRef = <T>(ref: string | T & HasObjectId): ref is T & HasObjectId => {
+  return !(typeof ref === 'string');
+};

+ 14 - 2
packages/app/src/stores/user-group.tsx

@@ -1,8 +1,8 @@
-import { SWRResponse } from 'swr';
+import useSWR, { SWRResponse } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
+import { apiGet } from '~/client/util/apiv1-client';
 import { apiv3Get } from '~/client/util/apiv3-client';
-
 import { IPageHasId } from '~/interfaces/page';
 import { IUserGroupHasId, IUserGroupRelationHasId } from '~/interfaces/user';
 import {
@@ -10,6 +10,18 @@ import {
   UserGroupPagesResult, SelectableParentUserGroupsResult, SelectableUserChildGroupsResult, AncestorUserGroupsResult,
 } from '~/interfaces/user-group-response';
 
+
+type MyUserGroupRelationsResult = {
+  userGroupRelations: IUserGroupRelationHasId[],
+}
+
+export const useSWRxMyUserGroupRelations = (): SWRResponse<IUserGroupRelationHasId[], Error> => {
+  return useSWR(
+    '/me/user-group-relations',
+    endpoint => apiGet(endpoint).then(result => (result as MyUserGroupRelationsResult).userGroupRelations),
+  );
+};
+
 export const useSWRxUserGroup = (groupId: string | undefined): SWRResponse<IUserGroupHasId, Error> => {
   return useSWRImmutable(
     groupId != null ? [`/user-groups/${groupId}`] : null,