Repository: hasura/graphql-engine
File: console/src/components/Services/Events/CronTriggers/PendingEvents/PendingEvents.tsx (TypeScript)

Code before:
import {
  FilterRenderProp,
  makeValueFilter,
} from '../../../../Common/FilterQuery/types';
import { stEventsTable } from '../utils';
import { ScheduledTrigger } from '../../types';
import { Dispatch } from '../../../../../types';
import EventsTable from '../../Common/Components/EventsTable';
import { makeOrderBy } from '../../../../Common/utils/v1QueryUtils';
import Endpoints from '../../../../../Endpoints';
import requestAction from '../../../../../utils/requestAction';
import {
  showSuccessNotification,
  showErrorNotification,
} from '../../../Common/Notification';

type Props = {
  currentTrigger?: ScheduledTrigger;
  dispatch: Dispatch;
};

const PendingEvents: React.FC<Props> = props => {
  const { dispatch, currentTrigger } = props;
  const triggerName = currentTrigger ? currentTrigger.name : '';

  const onCancelCronTrigger = (id: string, onSuccess: () => void) => {
    const url = Endpoints.query;
    const payload = {
      type: 'delete',
      args: {
        table: { name: 'hdb_cron_events', schema: 'hdb_catalog' },
        where: {
          id: { $eq: id },
        },
      },
    };
    const options = {
      method: 'POST',
      body: JSON.stringify(payload),
    };
    const successText = 'Successfully deleted cron event';
    const errorText = 'Error in cancelling event';

    dispatch(requestAction(url, options, successText, errorText, true, true))
      .then(() => {
        dispatch(showSuccessNotification(successText));
        onSuccess();
      })
      .catch(err => {
        dispatch(showErrorNotification(errorText, err.message, err));
      });

Review comment (refactor):
Ditto, this logic is duplicated. We could have a thunk in `serverIO` that takes `table name` as an argument. and in `PendingEvents` and `CronEvents` have some small handlers.

Code after:
import {
  FilterRenderProp,
  makeValueFilter,
} from '../../../../Common/FilterQuery/types';
import { stEventsTable } from '../utils';
import { ScheduledTrigger } from '../../types';
import { Dispatch } from '../../../../../types';
import EventsTable from '../../Common/Components/EventsTable';
import { makeOrderBy } from '../../../../Common/utils/v1QueryUtils';
import { cancelEvent } from '../../ServerIO';
import {
  getConfirmation,
  convertDateTimeToLocale,
} from '../../../../Common/utils/jsUtils';

type Props = {
  currentTrigger?: ScheduledTrigger;
  dispatch: Dispatch;
};

const PendingEvents: React.FC<Props> = props => {
  const { dispatch, currentTrigger } = props;
  const triggerName = currentTrigger ? currentTrigger.name : '';

  const onCancelCronTrigger = (
    id: string,
    scheduledAt: string,
    onSuccess: () => void
  ) => {
    const localeTime = convertDateTimeToLocale(scheduledAt);
    const shouldCancelEvent = getConfirmation(
      `This will delete the "${triggerName}" cron event "${id}" scheduled for "${localeTime}"`
    );
    if (shouldCancelEvent) {
      dispatch(cancelEvent('cron', 'hdb_cron_events', id, onSuccess));
    }
  };

  const renderRows: FilterRenderProp = (
    rows,
    count,
    filterState,
    setFilterState,
    runQuery
  ) => (
    <EventsTable
      rows={rows}
      count={count}
      filterState={filterState}
      setFilterState={setFilterState}
      runQuery={runQuery}