eschutho commented on a change in pull request #13761:
URL: https://github.com/apache/superset/pull/13761#discussion_r600118374



##########
File path: superset-frontend/src/common/hooks/apiResources/apiResources.ts
##########
@@ -67,6 +72,163 @@ const initialState: LoadingState = {
   error: null,
 };
 
+const RESOURCE_START = 'RESOURCE_START';
+const RESOURCE_SUCCESS = 'RESOURCE_SUCCESS';
+const RESOURCE_ERROR = 'RESOURCE_FETCH_ERROR';
+
+type FetchStart = {
+  type: typeof RESOURCE_START;
+  clientId: string;
+};
+
+type FetchSuccess<T = any> = {
+  type: typeof RESOURCE_SUCCESS;
+  clientId: string;
+  result: T;
+};
+
+type FetchError = {
+  type: typeof RESOURCE_ERROR;
+  clientId: string;
+  error: Error;
+};
+
+type ResourceAction = FetchStart | FetchSuccess | FetchError;
+
+export function resourcesReducer(
+  state: ResourcesState = initialResourcesState,
+  action: ResourceAction,
+): ResourcesState {
+  switch (action.type) {
+    case RESOURCE_START: {
+      return {
+        ...state,
+        [action.clientId]: {
+          status: ResourceStatus.LOADING,
+          result: null,
+          error: null,
+        },
+      };
+    }
+    case RESOURCE_SUCCESS: {
+      const { clientId, result } = action;
+      return {
+        ...state,
+        [clientId]: {
+          status: ResourceStatus.COMPLETE,
+          result,
+          error: null,
+        },
+      };
+    }
+    case RESOURCE_ERROR: {
+      const { clientId, error } = action as FetchError;
+      return {
+        ...state,
+        [clientId]: {
+          status: ResourceStatus.ERROR,
+          result: null,
+          error,
+        },
+      };
+    }
+    default:
+      return state;
+  }
+}
+
+type ReduxRootState = { apiResources: ResourcesState };
+const selectResource = <RESULT>(clientId: string) => (
+  state: ReduxRootState,
+): Resource<RESULT> | null => state.apiResources[clientId] ?? null;
+
+async function fetchData<RESULT>(
+  dispatch: Dispatch<ResourceAction>,
+  endpoint: string,
+) {
+  const clientId = uuidv1();
+
+  dispatch({
+    type: RESOURCE_START,
+    clientId,
+  });
+
+  const fetchResource = makeApi<{}, RESULT>({
+    method: 'GET',
+    endpoint,
+  });
+
+  try {
+    const result = await fetchResource({});
+    dispatch({
+      type: RESOURCE_SUCCESS,
+      clientId,
+      result,
+    });
+  } catch (error) {
+    dispatch({
+      type: RESOURCE_ERROR,
+      clientId,
+      error,
+    });
+  }
+}
+
+export function useApiFetch<RESULT>(endpoint: string): void {
+  const dispatch = useDispatch<Dispatch<ResourceAction>>();
+  const resource = useSelector(selectResource(endpoint));
+
+  useEffect(() => {
+    if (resource != null) {
+      // fetching already underway/complete, don't duplicate work.
+      return;
+    }
+
+    fetchData<RESULT>(dispatch, endpoint);
+  }, [endpoint, resource, dispatch]);
+}
+
+export function useApiFetchWithStore(endpoint: string) {
+  const dispatch = useDispatch<Dispatch<ResourceAction>>();
+  return async function callResource() {
+    const response = await fetchData(dispatch, endpoint);

Review comment:
       we could also return another function that has the useSelector here. 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to