redux-thunk#ThunkDispatch TypeScript Examples

The following examples show how to use redux-thunk#ThunkDispatch. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From che-dashboard-next with Eclipse Public License 2.0 6 votes vote down vote up
function subscribeToStatusChange(
  workspaceId: string,
  dispatch: ThunkDispatch<State, undefined, UpdateWorkspaceStatusAction | UpdateWorkspacesLogsAction | DeleteWorkspaceLogsAction>): void {
  const callback = message => {
    let status: string;
    if (message.error) {
      const workspacesLogs = new Map<string, string[]>();
      workspacesLogs.set(workspaceId, [`Error: Failed to run the workspace: "${message.error}"`]);
      dispatch({
        type: 'UPDATE_WORKSPACES_LOGS',
        workspacesLogs,
      });
      status = WorkspaceStatus[WorkspaceStatus.ERROR];
    } else {
      status = message.status;
    }
    if (WorkspaceStatus[status]) {
      dispatch({
        type: 'UPDATE_WORKSPACE_STATUS',
        workspaceId,
        status,
      });
    }
    if (WorkspaceStatus[WorkspaceStatus.STARTING] !== status) {
      unSubscribeToEnvironmentOutput(workspaceId);
    }
  };
  WorkspaceClient.jsonRpcMasterApi.subscribeWorkspaceStatus(workspaceId, callback);
  subscribedWorkspaceStatusCallbacks.set(workspaceId, callback);
}
Example #2
Source File: index.ts    From che-dashboard-next with Eclipse Public License 2.0 6 votes vote down vote up
function subscribeToEnvironmentOutput(workspaceId: string, dispatch: ThunkDispatch<State, undefined, UpdateWorkspacesLogsAction | DeleteWorkspaceLogsAction>): void {
  const callback: EnvironmentOutputMessageHandler = message => {
    if (message.runtimeId?.workspaceId === workspaceId && message.text) {
      const workspacesLogs = new Map<string, string[]>();
      workspacesLogs.set(workspaceId, [`${message.text}`]);
      dispatch({
        type: 'UPDATE_WORKSPACES_LOGS',
        workspacesLogs,
      });
    }
  };
  dispatch({
    type: 'DELETE_WORKSPACE_LOGS',
    workspaceId,
  });
  WorkspaceClient.jsonRpcMasterApi.subscribeEnvironmentOutput(workspaceId, callback);
  subscribedEnvironmentOutputCallbacks.set(workspaceId, callback);
}
Example #3
Source File: tour.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
setStep = async (
  dispatch: ThunkDispatch<ReduxStateTour, undefined, AllTourActions>,
  history: History,
  location: Location,
  guideId: string,
  guide: TourDefinitionGuide,
  onGuideCompleted: TourData['onGuideCompleted'],
  stepId?: string,
  step?: TourDefinitionGuideStep,
) => {
  dispatch({
    type: 'tourSetStep', payload: {
      activeStep: undefined,
    }
  });
  if (!!stepId && !!step) {
    if (!!step.openPath && location.pathname !== step.openPath) {
      await new Promise(resolve => setTimeout(resolve, 250));
      history.push(step.openPath);
    }
    await new Promise(resolve => setTimeout(resolve, step.showDelay !== undefined ? step.showDelay : 250));
    dispatch({
      type: 'tourSetStep', payload: {
        activeStep: { guideId, stepId },
      }
    });
  } else {
    if (guide.onComplete?.openPath) {
      await new Promise(resolve => setTimeout(resolve, 250));
      history.push(guide.onComplete.openPath);
    }
    onGuideCompleted?.(guideId, guide);
  }
}
Example #4
Source File: fetchTokens.ts    From multisig-react with MIT License 6 votes vote down vote up
fetchTokens = () => async (
  dispatch: ThunkDispatch<AppReduxState, undefined, AnyAction>,
  getState: () => AppReduxState,
): Promise<void> => {
  try {
    const currentSavedTokens = tokensSelector(getState())

    const {
      data: { results: tokenList },
    } = await fetchErc20AndErc721AssetsList()

    const erc20Tokens = tokenList.filter((token) => token.type.toLowerCase() === 'erc20')

    if (currentSavedTokens?.size === erc20Tokens.length) {
      return
    }

    const tokens = List(erc20Tokens.map((token) => makeToken(token)))

    dispatch(saveTokens(tokens))
  } catch (err) {
    console.error('Error fetching token list', err)
  }
}
Example #5
Source File: wallet.ts    From bob-extension with MIT License 6 votes vote down vote up
createWallet = (opt: {
  walletName: string;
  seedphrase: string;
  password: string;
  optIn: boolean;
}) => async (dispatch: ThunkDispatch<AppRootState, any, Action>) => {
  const {walletName, seedphrase, password, optIn} = opt;
  if (!walletName) throw new Error('Wallet name cannot be empty.');
  if (!seedphrase) throw new Error('Invalid seedphrase.');
  if (!password) throw new Error('Password cannot be empty.');

  await postMessage({
    type: MessageTypes.CREATE_NEW_WALLET,
    payload: {
      id: walletName,
      mnemonic: seedphrase,
      passphrase: password,
      optIn,
    },
  });
  await new Promise(r => setTimeout(r, 1000));
  await dispatch(fetchWallets());
  await dispatch(selectWallet(walletName));
  return;
}
Example #6
Source File: setSelectedCurrency.ts    From multisig-react with MIT License 5 votes vote down vote up
setSelectedCurrency = (safeAddress: string, selectedCurrency: string) => (
  dispatch: ThunkDispatch<AppReduxState, undefined, AnyAction>,
): void => {
  dispatch(setCurrentCurrency(safeAddress, selectedCurrency))
  dispatch(fetchCurrencyRate(safeAddress, selectedCurrency))
}
Example #7
Source File: wallet.ts    From bob-extension with MIT License 5 votes vote down vote up
lockWallet = () => async (dispatch: ThunkDispatch<AppRootState, any, Action>) => {
  await postMessage({ type: MessageTypes.LOCK_WALLET });
  await dispatch(fetchWalletState());
}
Example #8
Source File: wallet.ts    From bob-extension with MIT License 5 votes vote down vote up
unlockWallet = (password: string) => async (dispatch: ThunkDispatch<AppRootState, any, Action>) => {
  await postMessage({
    type: MessageTypes.UNLOCK_WALLET,
    payload: password,
  });
  await dispatch(fetchWalletState());
}
Example #9
Source File: wallet.ts    From bob-extension with MIT License 5 votes vote down vote up
selectWallet = (id: string) => async (dispatch: ThunkDispatch<AppRootState, any, Action>) => {
  await postMessage({
    type: MessageTypes.SELECT_WALLET,
    payload: id,
  });
  await dispatch(fetchWalletState());
}
Example #10
Source File: tour.tsx    From clearflask with Apache License 2.0 4 votes vote down vote up
TourChecklist = (props: {
}) => {
  const tourContext = useContext(TourContext);
  const classes = useStyles();
  const dispatch: ThunkDispatch<ReduxStateTour, undefined, AllTourActions> = useDispatch();
  const history = useHistory();
  const location = useLocation();

  if (!tourContext) return null;
  const { tour, onGuideCompleted, onGuideSkipped, onGuideUnSkipped } = tourContext;

  var singleGroupAlreadyExpanded = false;
  const groups = tour.groups.map(group => {
    var completedCount = 0;
    const guides = group.guideIds.map(guideId => {
      const guide = tour.guides[guideId];
      if (!guide) return null;
      if (guide.state !== TourDefinitionGuideState.Available) completedCount++;
      return (
        <HoverArea>
          {(hoverAreaProps, isHovering, isHoverDisabled) => (
            <div className={classes.guideContainer} {...hoverAreaProps}>
              <ListItem
                key={guideId}
                button
                className={classNames(
                  classes.guide,
                  guide.state !== TourDefinitionGuideState.Available && classes.areaCompleted,
                )}
                onClick={() => {
                  const initialStepEntry = Object.entries(guide.steps)[0];
                  if (!initialStepEntry) return;
                  setStep(dispatch, history, location, guideId, guide, onGuideCompleted, initialStepEntry[0], initialStepEntry[1]);
                }}
              >
                <ListItemIcon>
                  {guide.state === TourDefinitionGuideState.Completed && (
                    <CheckIcon fontSize='inherit' color='primary' className={classes.guideIcon} />
                  )}
                  {guide.state === TourDefinitionGuideState.Available && (
                    <StartIcon fontSize='inherit' className={classes.guideIcon} />
                  )}
                  {guide.state === TourDefinitionGuideState.Skipped && (
                    <SkipIcon fontSize='inherit' className={classes.guideIcon} />
                  )}
                </ListItemIcon>
                <Typography variant='body1'>{guide.title}</Typography>
                <div className={classes.flexGrow} />
              </ListItem>
              {!guide.disableSkip && (
                <div className={classes.listTrailingAction}>
                  <Fade in={(isHovering || isHoverDisabled)
                    && ((guide.state === TourDefinitionGuideState.Available && !!onGuideSkipped) || (guide.state === TourDefinitionGuideState.Skipped && !!onGuideUnSkipped))}>
                    <IconButton
                      aria-label='Skip'
                      onClick={e => {
                        if (guide.state === TourDefinitionGuideState.Available) {
                          onGuideSkipped?.(guideId, guide);
                        } else {
                          onGuideUnSkipped?.(guideId, guide);
                        }
                      }}
                    >
                      {guide.state === TourDefinitionGuideState.Available
                        ? (<SkipIcon fontSize='inherit' className={classes.skipIcon} />)
                        : (<UnSkipIcon fontSize='inherit' className={classes.skipIcon} />)}
                    </IconButton>
                  </Fade>
                </div>
              )}
            </div>
          )}
        </HoverArea>
      );
    }).filter(notEmpty);
    const completePerc = (completedCount / guides.length) * 100;
    var shouldDefaultExpand = false;
    if (!singleGroupAlreadyExpanded && completePerc < 100) {
      singleGroupAlreadyExpanded = true;
      shouldDefaultExpand = true;
    }
    return (
      <TourChecklistGroup
        key={group.title}
        title={group.title}
        guides={guides}
        completePerc={completePerc}
        defaultExpanded={shouldDefaultExpand}
      />
    );
  });

  return (
    <div className={classes.checklist}>
      <Typography variant='h4' className={classes.checklistHeader}>{tour.title}</Typography>
      {groups}
    </div>
  );
}
Example #11
Source File: tour.tsx    From clearflask with Apache License 2.0 4 votes vote down vote up
TourAnchor = React.forwardRef((props: {
  anchorId?: string;
  className?: string;
  children?: React.ReactNode | ((
    next: (() => void),
    isActive: boolean,
    // If your element is not listed, freely add it here,
    // The type system of RefObject is weird as it doesn't accept a generic type of PopperReferenceObject
    anchorRef: React.RefObject<PopperReferenceObject & HTMLElement & HTMLDivElement & HTMLInputElement & HTMLSpanElement & HTMLButtonElement & HTMLAnchorElement>,
  ) => React.ReactNode);
  disablePortal?: React.ComponentProps<typeof ClosablePopper>['disablePortal'];
  zIndex?: React.ComponentProps<typeof ClosablePopper>['zIndex'];
  placement?: React.ComponentProps<typeof ClosablePopper>['placement'];
  ClosablePopperProps?: Partial<Omit<React.ComponentProps<typeof ClosablePopper>, 'anchor' | 'anchorType'>>;
  DivProps?: Partial<React.HTMLAttributes<HTMLDivElement>>;
}, ref: React.Ref<TourAnchorHandle>) => {
  const { tour, onGuideCompleted } = useContext(TourContext) || {};
  const classes = useStyles();
  const anchorRef = useRef<any>(null);
  const dispatch: ThunkDispatch<ReduxStateTour, undefined, AllTourActions> = useDispatch();
  const history = useHistory();
  const location = useLocation();

  const activeGuideId = useSelector<ReduxStateTour, string | undefined>(state => state.tour.activeStep?.guideId, shallowEqual);
  const activeGuide = !!activeGuideId ? tour?.guides[activeGuideId] : undefined;
  const activeStepId = useSelector<ReduxStateTour, string | undefined>(state => state.tour.activeStep?.stepId, shallowEqual);
  const activeStep = !!activeStepId ? activeGuide?.steps[activeStepId] : undefined;
  const activeAnchorId = activeStep?.anchorId;
  const isActive = !!props.anchorId && !!activeStep && (activeStep?.anchorId === props.anchorId);
  var nextStepId = activeStep?.overrideNextStepId;
  if (isActive && !nextStepId && activeGuide) {
    const stepIds = Object.keys(activeGuide.steps);
    const activeIndex = stepIds.findIndex(stepId => stepId === activeStepId);
    if (activeIndex !== -1 && activeIndex < stepIds.length) {
      nextStepId = stepIds[activeIndex + 1];
    }
  }
  const nextStep = !!nextStepId ? activeGuide?.steps[nextStepId] : undefined;

  const next = () => {
    if (!isActive || !activeGuideId || !activeGuide || !onGuideCompleted) return;
    setStep(dispatch, history, location, activeGuideId, activeGuide, onGuideCompleted, nextStepId, nextStep);
  };
  const complete = () => {
    if (!isActive || !activeGuideId || !activeGuide || !onGuideCompleted) return;
    setStep(dispatch, history, location, activeGuideId, activeGuide, onGuideCompleted, undefined, undefined);
  };
  React.useImperativeHandle(ref, () => ({ next }),
    [activeAnchorId, activeGuideId, activeStep, location.pathname, nextStepId]); // eslint-disable-line react-hooks/exhaustive-deps

  var popper;
  if (isActive && !!activeStep && !!activeGuide) {
    const stepsTotal = Object.keys(activeGuide.steps).length;
    const stepIndex = Object.keys(activeGuide.steps).findIndex(stepId => stepId === activeStepId);
    popper = (
      <ClosablePopper
        anchorType='ref'
        anchor={anchorRef}
        open
        onClose={() => dispatch({ type: 'tourSetStep', payload: { activeStep: undefined } })}
        arrow
        closeButtonPosition='disable'
        paperClassName={classes.anchorPaper}
        {...props.ClosablePopperProps}
        disablePortal={props.disablePortal}
        placement={activeStep.placement || props.placement || props.ClosablePopperProps?.placement || 'bottom'}
        zIndex={activeStep.zIndex !== undefined ? activeStep.zIndex
          : (props.zIndex !== undefined ? props.zIndex : props.ClosablePopperProps?.zIndex)}
      >
        {!!activeStep.title && (
          <Typography variant='h6'>{activeStep.title}</Typography>
        )}
        {!!activeStep.description && (
          <Typography variant='body1' color='textSecondary'>{activeStep.description}</Typography>
        )}
        <div className={classes.actionArea}>
          {stepsTotal > 1 && stepIndex !== undefined && (
            <MobileStepper
              className={classes.stepper}
              variant='dots'
              position='static'
              steps={stepsTotal}
              activeStep={stepIndex}
              backButton={null}
              nextButton={null}
            />
          )}
          <div className={classes.flexGrow} />
          {!!activeStep.showButtonNext && (
            <Button color='primary' onClick={next}>
              {typeof activeStep.showButtonNext === 'string' ? activeStep.showButtonNext : (!!nextStepId ? 'Next' : 'Finish')}
            </Button>
          )}
          {!!activeStep.showButtonComplete && (
            <Button color='primary' onClick={complete}>
              {typeof activeStep.showButtonComplete === 'string' ? activeStep.showButtonComplete : 'Finish'}
            </Button>
          )}
        </div>
      </ClosablePopper>
    );
  }

  const scrollTo = isActive && !!activeStep?.scrollTo ? (
    <ScrollAnchor scrollOnMount />
  ) : null;

  var content = (
    <>
      {typeof props.children === 'function' ? props.children(next, isActive, anchorRef) : props.children}
      {scrollTo}
      {popper}
    </>
  );

  if (typeof props.children !== 'function') {
    content = (
      <span ref={anchorRef} className={props.className} {...props.DivProps}>
        {content}
      </span>
    );
  }

  return content;
})