formik#FormikConfig TypeScript Examples

The following examples show how to use formik#FormikConfig. 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: useResetPasswordFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 7 votes vote down vote up
function useResetPasswordFormik(
  onSubmit: (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => void | Promise<any>,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #2
Source File: useSignInFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
function useSigninFormik(
  onSubmit: (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => void | Promise<any>,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #3
Source File: useSignUpFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
function useSignUpFormik(
  onSubmit: (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => void | Promise<any>,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #4
Source File: HostDiscovery.tsx    From assisted-ui-lib with Apache License 2.0 6 votes vote down vote up
HostDiscovery: React.FC<{ cluster: Cluster }> = ({ cluster }) => {
  const dispatch = useDispatch();
  const { addAlert, clearAlerts } = useAlerts();
  const initialValues = React.useMemo(
    () => getHostDiscoveryInitialValues(cluster),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [], // just once, Formik does not reinitialize
  );

  const handleSubmit: FormikConfig<HostDiscoveryValues>['onSubmit'] = async (values) => {
    clearAlerts();

    const params: V2ClusterUpdateParams = {};
    HostDiscoveryService.setPlatform(params, values.usePlatformIntegration);
    HostDiscoveryService.setOLMOperators(params, values, cluster.monitoredOperators);
    HostDiscoveryService.setSchedulableMasters(params, values, cluster);

    try {
      const { data } = await ClustersAPI.update(cluster.id, params);
      dispatch(updateCluster(data));
    } catch (e) {
      handleApiError(e, () =>
        addAlert({ title: 'Failed to update the cluster', message: getErrorMessage(e) }),
      );
    }
  };

  return (
    <Formik initialValues={initialValues} onSubmit={handleSubmit}>
      <HostDiscoveryForm cluster={cluster} />
    </Formik>
  );
}
Example #5
Source File: useForm.ts    From frontend with MIT License 6 votes vote down vote up
export default function useForm<Values>({
  validateOnChange = true,
  validateOnBlur = false,
  ...formikProps
}: FormikConfig<Values>): FormikType<Values> {
  const formik = useFormik<Values>({
    validateOnChange,
    validateOnBlur,
    ...formikProps,
  })

  return { formik }
}
Example #6
Source File: index.tsx    From youtube-2020-june-material-ui-themes with MIT License 5 votes vote down vote up
export function FormikStepper({
  children,
  ...props
}: FormikConfig<FormikValues>) {
  const childrenArray = React.Children.toArray(children) as React.ReactElement<
    FormikStepProps
  >[];
  const [step, setStep] = useState(0);
  const currentChild = childrenArray[step];
  const [completed, setCompleted] = useState(false);

  function isLastStep() {
    return step === childrenArray.length - 1;
  }

  return (
    <Formik
      {...props}
      validationSchema={currentChild.props.validationSchema}
      onSubmit={async (values, helpers) => {
        if (isLastStep()) {
          await props.onSubmit(values, helpers);
          setCompleted(true);
        } else {
          setStep(s => s + 1);
        }
      }}
    >
      {({ isSubmitting }) => (
        <Form autoComplete="off">
          <Stepper alternativeLabel activeStep={step}>
            {childrenArray.map((child, index) => (
              <Step
                key={child.props.label}
                completed={step > index || completed}
              >
                <StepLabel>{child.props.label}</StepLabel>
              </Step>
            ))}
          </Stepper>

          {currentChild}

          <Grid container spacing={2}>
            {step > 0 ? (
              <Grid item>
                <Button
                  disabled={isSubmitting}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(s => s - 1)}
                >
                  Back
                </Button>
              </Grid>
            ) : null}
            <Grid item xs={12}>
              <Button
                startIcon={
                  isSubmitting ? <CircularProgress size="1rem" /> : null
                }
                disabled={isSubmitting}
                type="submit"
                fullWidth
              >
                {isSubmitting ? "Submitting" : isLastStep() ? "Submit" : "NeXt"}
              </Button>
            </Grid>
          </Grid>
        </Form>
      )}
    </Formik>
  );
}
Example #7
Source File: index.tsx    From youtube-2020-june-multi-step-form-formik with MIT License 5 votes vote down vote up
export function FormikStepper({ children, ...props }: FormikConfig<FormikValues>) {
  const childrenArray = React.Children.toArray(children) as React.ReactElement<FormikStepProps>[];
  const [step, setStep] = useState(0);
  const currentChild = childrenArray[step];
  const [completed, setCompleted] = useState(false);

  function isLastStep() {
    return step === childrenArray.length - 1;
  }

  return (
    <Formik
      {...props}
      validationSchema={currentChild.props.validationSchema}
      onSubmit={async (values, helpers) => {
        if (isLastStep()) {
          await props.onSubmit(values, helpers);
          setCompleted(true);
        } else {
          setStep((s) => s + 1);

          // the next line was not covered in the youtube video
          //
          // If you have multiple fields on the same step
          // we will see they show the validation error all at the same time after the first step!
          //
          // If you want to keep that behaviour, then, comment the next line :)
          // If you want the second/third/fourth/etc steps with the same behaviour
          //    as the first step regarding validation errors, then the next line is for you! =)
          //
          // In the example of the video, it doesn't make any difference, because we only
          //    have one field with validation in the second step :)
          helpers.setTouched({});
        }
      }}
    >
      {({ isSubmitting }) => (
        <Form autoComplete="off">
          <Stepper alternativeLabel activeStep={step}>
            {childrenArray.map((child, index) => (
              <Step key={child.props.label} completed={step > index || completed}>
                <StepLabel>{child.props.label}</StepLabel>
              </Step>
            ))}
          </Stepper>

          {currentChild}

          <Grid container spacing={2}>
            {step > 0 ? (
              <Grid item>
                <Button
                  disabled={isSubmitting}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep((s) => s - 1)}
                >
                  Back
                </Button>
              </Grid>
            ) : null}
            <Grid item>
              <Button
                startIcon={isSubmitting ? <CircularProgress size="1rem" /> : null}
                disabled={isSubmitting}
                variant="contained"
                color="primary"
                type="submit"
              >
                {isSubmitting ? 'Submitting' : isLastStep() ? 'Submit' : 'Next'}
              </Button>
            </Grid>
          </Grid>
        </Form>
      )}
    </Formik>
  );
}
Example #8
Source File: useCommentCreateFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
export function useCommentCreateFormik(
  postId: string,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();
  const [create] = useCommentCreateMutation({
    onCompleted: () => {
      formik.handleReset(null);
    },
  });

  const onSubmit = async (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => {
    return create({
      variables: {
        data: {
          postId,
          text: values.text,
          payload: {},
        },
      },
      refetchQueries: [CommentsDocument, CommentStatDocument],
    });
  };

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #9
Source File: ClusterDeploymentHostSelectionStep.tsx    From assisted-ui-lib with Apache License 2.0 5 votes vote down vote up
ClusterDeploymentHostSelectionStep: React.FC<ClusterDeploymentHostSelectionStepProps> = ({
  onSaveHostsSelection,
  ...rest
}) => {
  const { addAlert } = useAlerts();

  const { agents, clusterDeployment, agentClusterInstall } = rest;

  const [initialValues, validationSchema] = useHostsSelectionFormik({
    agents,
    clusterDeployment,
    agentClusterInstall,
  });

  const handleSubmit: FormikConfig<ClusterDeploymentHostsSelectionValues>['onSubmit'] = async (
    values,
    { setSubmitting },
  ) => {
    try {
      await onSaveHostsSelection(values);
    } catch (error) {
      addAlert({
        title: 'Failed to save host selection.',
        message: error.message as string,
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      <HostSelectionForm {...rest} />
    </Formik>
  );
}
Example #10
Source File: StaticIpForm.tsx    From assisted-ui-lib with Apache License 2.0 5 votes vote down vote up
StaticIpForm = <StaticIpFormValues extends object>({
  infraEnv,
  updateInfraEnv,
  getInitialValues,
  getUpdateParams,
  validationSchema,
  onFormStateChange,
  getEmptyValues,
  children,
  showEmptyValues,
}: PropsWithChildren<StaticIpFormProps<StaticIpFormValues>>) => {
  const { clearAlerts, addAlert } = useAlerts();
  const { captureException } = useErrorMonitor();
  const [initialValues, setInitialValues] = React.useState<StaticIpFormValues | undefined>();
  React.useEffect(() => {
    if (showEmptyValues) {
      //after view changed the formik should be rendered with empty values
      setInitialValues(getEmptyValues());
    } else {
      setInitialValues(getInitialValues(infraEnv));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleSubmit: FormikConfig<StaticIpFormValues>['onSubmit'] = async (values) => {
    clearAlerts();
    try {
      const staticNetworkConfig = getUpdateParams(infraEnv, values);
      await updateInfraEnv({
        staticNetworkConfig: staticNetworkConfig,
      });
    } catch (error) {
      captureException(error);
      addAlert({ title: getErrorMessage(error) });
    }
  };
  if (!initialValues) {
    return null;
  }
  const validate = (values: StaticIpFormValues) => {
    try {
      validationSchema.validateSync(values, { abortEarly: false, context: { values: values } });
      return {};
    } catch (error) {
      return yupToFormErrors(error);
    }
  };
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      validate={validate}
      validateOnMount
      enableReinitialize
    >
      <Form>
        {children}
        <AutosaveWithParentUpdate<StaticIpFormValues>
          onFormStateChange={onFormStateChange}
          getEmptyValues={getEmptyValues}
        />
      </Form>
    </Formik>
  );
}
Example #11
Source File: BMCForm.tsx    From assisted-ui-lib with Apache License 2.0 4 votes vote down vote up
BMCForm: React.FC<BMCFormProps> = ({
  onCreateBMH,
  onClose,
  hasDHCP,
  infraEnv,
  bmh,
  nmState,
  secret,
  isEdit,
  usedHostnames,
}) => {
  const [error, setError] = React.useState();

  const handleSubmit: FormikConfig<AddBmcValues>['onSubmit'] = async (values) => {
    try {
      setError(undefined);
      const nmState = values.nmState ? getNMState(values, infraEnv) : undefined;
      await onCreateBMH(values, nmState);
      onClose();
    } catch (e) {
      setError(e.message);
    }
  };

  const { initValues, validationSchema } = React.useMemo(() => {
    const initValues = getInitValues(bmh, nmState, secret, isEdit);
    const validationSchema = getValidationSchema(usedHostnames, initValues.hostname);
    return { initValues, validationSchema };
  }, [usedHostnames, bmh, nmState, secret, isEdit]);
  return (
    <Formik
      initialValues={initValues}
      isInitialValid={false}
      validate={getRichTextValidation(validationSchema)}
      onSubmit={handleSubmit}
    >
      {({ isSubmitting, isValid, submitForm }: FormikProps<AddBmcValues>) => (
        <>
          <ModalBoxBody>
            <Form id="add-bmc-form">
              <InputField
                label="Name"
                name="name"
                placeholder="Enter the name for the Host"
                isRequired
                isDisabled={isEdit}
              />
              <RichInputField
                label="Hostname"
                name="hostname"
                placeholder="Enter the hostname for the Host"
                richValidationMessages={HOSTNAME_VALIDATION_MESSAGES}
                isRequired
              />
              <InputField
                label="Baseboard Management Controller Address"
                name="bmcAddress"
                placeholder="Enter an address"
                isRequired
              />
              <InputField
                label="Boot NIC MAC Address"
                name="bootMACAddress"
                placeholder="Enter an address"
                description="The MAC address of the host's network connected NIC that wll be used to provision the host."
              />
              <InputField
                label="Username"
                name="username"
                placeholder="Enter a username for the BMC"
                isRequired
              />
              <InputField
                type={TextInputTypes.password}
                label="Password"
                name="password"
                placeholder="Enter a password for the BMC"
                isRequired
              />
              {!hasDHCP && (
                <>
                  <CodeField
                    label="NMState"
                    name="nmState"
                    language={Language.yaml}
                    description="Upload a YAML file in NMstate format that includes your network configuration (static IPs, bonds, etc.)."
                  />
                  <MacMapping />
                </>
              )}
            </Form>
            {error && (
              <Alert
                title="Failed to add host"
                variant={AlertVariant.danger}
                isInline
                actionClose={<AlertActionCloseButton onClose={() => setError(undefined)} />}
              >
                {error}
              </Alert>
            )}
          </ModalBoxBody>
          <ModalBoxFooter>
            <Button onClick={submitForm} isDisabled={isSubmitting || !isValid}>
              {isEdit ? 'Submit' : 'Create'}
            </Button>
            <Button onClick={onClose} variant={ButtonVariant.secondary}>
              Cancel
            </Button>
          </ModalBoxFooter>
        </>
      )}
    </Formik>
  );
}
Example #12
Source File: ScaleUpModal.tsx    From assisted-ui-lib with Apache License 2.0 4 votes vote down vote up
ScaleUpModal: React.FC<ScaleUpModalProps> = ({
  isOpen,
  onClose,
  addHostsToCluster,
  clusterDeployment,
  agents,
  onChangeHostname,
}) => {
  const [editAgent, setEditAgent] = React.useState<AgentK8sResource | undefined>();
  const [error, setError] = React.useState<string | undefined>();

  const getInitialValues = (): ScaleUpFormValues => {
    const agentSelector = getAgentSelectorFieldsFromAnnotations(
      clusterDeployment?.metadata?.annotations,
    );

    const autoSelectHosts = agentSelector.autoSelect;
    return {
      autoSelectHosts,
      hostCount: 1,
      agentLabels: agentSelector.labels,
      locations: agentSelector.locations,
      selectedHostIds: [],
      autoSelectedHostIds: [],
    };
  };

  const validationSchema = React.useMemo(() => getValidationSchema(agents.length), [agents.length]);

  const handleSubmit: FormikConfig<ScaleUpFormValues>['onSubmit'] = async (values) => {
    const { autoSelectHosts, autoSelectedHostIds, selectedHostIds } = values;
    try {
      setError(undefined);
      const agentsToAdd = getAgentsToAdd(
        autoSelectHosts ? autoSelectedHostIds : selectedHostIds,
        agents,
      );
      await addHostsToCluster(agentsToAdd);
      onClose();
    } catch (e) {
      setError(e.message);
    }
  };

  const clusterAgents = agents.filter(
    (a) =>
      a.spec.clusterDeploymentName?.name === clusterDeployment.metadata?.name &&
      a.spec.clusterDeploymentName?.namespace === clusterDeployment.metadata?.namespace,
  );

  return (
    <>
      <Modal
        aria-label="Add worker host dialog"
        title="Add worker hosts"
        isOpen={isOpen}
        onClose={onClose}
        hasNoBodyWrapper
        id="scale-up-modal"
      >
        <Formik
          initialValues={getInitialValues()}
          validationSchema={validationSchema}
          onSubmit={handleSubmit}
          validateOnMount
        >
          {({ isSubmitting, isValid, submitForm }: FormikProps<ScaleUpFormValues>) => {
            return (
              <>
                <ModalBoxBody>
                  <Stack hasGutter>
                    <StackItem>
                      <ScaleUpForm agents={agents} onEditHost={setEditAgent} />
                    </StackItem>
                    {error && (
                      <StackItem>
                        <Alert
                          title="Failed to add hosts to the cluster"
                          variant={AlertVariant.danger}
                          actionClose={
                            <AlertActionCloseButton onClose={() => setError(undefined)} />
                          }
                          isInline
                        >
                          {error}
                        </Alert>
                      </StackItem>
                    )}
                  </Stack>
                </ModalBoxBody>
                <ModalBoxFooter>
                  <Button onClick={submitForm} isDisabled={isSubmitting || !isValid}>
                    Submit
                  </Button>
                  <Button onClick={onClose} variant={ButtonVariant.secondary}>
                    Cancel
                  </Button>
                </ModalBoxFooter>
              </>
            );
          }}
        </Formik>
      </Modal>
      {editAgent && (
        <EditAgentModal
          agent={editAgent}
          isOpen
          onClose={() => setEditAgent(undefined)}
          onSave={onChangeHostname}
          usedHostnames={getAgentsHostsNames(clusterAgents)}
        />
      )}
    </>
  );
}
Example #13
Source File: NetworkConfigurationForm.tsx    From assisted-ui-lib with Apache License 2.0 4 votes vote down vote up
NetworkConfigurationPage: React.FC<{
  cluster: Cluster;
}> = ({ cluster }) => {
  const { infraEnv, error: infraEnvError, isLoading } = useInfraEnv(cluster.id);
  const defaultNetworkSettings = useDefaultConfiguration([
    'clusterNetworkCidr',
    'serviceNetworkCidr',
    'clusterNetworkHostPrefix',
  ]);

  const defaultNetworkValues: Pick<
    NetworkConfigurationValues,
    'serviceNetworks' | 'clusterNetworks'
  > = {
    serviceNetworks: [
      {
        cidr: defaultNetworkSettings.serviceNetworkCidr,
        clusterId: cluster.id,
      },
    ],
    clusterNetworks: [
      {
        cidr: defaultNetworkSettings.clusterNetworkCidr,
        hostPrefix: defaultNetworkSettings.clusterNetworkHostPrefix,
        clusterId: cluster.id,
      },
    ],
  };

  const { addAlert, clearAlerts, alerts } = useAlerts();
  const dispatch = useDispatch();
  const hostSubnets = React.useMemo(() => getHostSubnets(cluster), [cluster]);
  const initialValues = React.useMemo(
    () => getNetworkInitialValues(cluster, defaultNetworkValues),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [], // just once, Formik does not reinitialize
  );

  const initialTouched = React.useMemo(() => mapValues(initialValues, () => true), [initialValues]);

  const memoizedValidationSchema = React.useMemo(
    () => getNetworkConfigurationValidationSchema(initialValues, hostSubnets),
    [hostSubnets, initialValues],
  );

  React.useEffect(() => {
    if (infraEnvError) {
      const title = `Failed to retrieve infra env (clusterId: ${cluster.id})`;
      //TODO(brotman) add handling of existing errors to alerts context
      if (alerts.find((alert) => alert.title === title)) {
        return;
      }
      captureException(infraEnvError, title);
      addAlert({
        title,
        message: infraEnvError.message,
      });
    }
    //shouldn't respond to cluster polling. shouldn't respond to alerts changes so remove alert wouldn't trigger adding it back
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [infraEnvError]);

  const handleSubmit: FormikConfig<NetworkConfigurationValues>['onSubmit'] = async (values) => {
    clearAlerts();
    // update the cluster configuration
    try {
      const isMultiNodeCluster = !isSNO(cluster);
      const isUserManagedNetworking = values.managedNetworkingType === 'userManaged';

      const params: V2ClusterUpdateParams = {
        apiVip: values.apiVip,
        ingressVip: values.ingressVip,
        sshPublicKey: values.sshPublicKey,
        vipDhcpAllocation: values.vipDhcpAllocation,
        networkType: values.networkType,
        machineNetworks: values.machineNetworks,
        clusterNetworks: values.clusterNetworks,
        serviceNetworks: values.serviceNetworks,
        userManagedNetworking: isUserManagedNetworking,
      };

      if (params.userManagedNetworking) {
        delete params.apiVip;
        delete params.ingressVip;
        if (isMultiNodeCluster) {
          delete params.machineNetworks;
        }
      } else {
        // cluster-managed can't be chosen in SNO, so this must be a multi-node cluster
        if (values.vipDhcpAllocation) {
          delete params.apiVip;
          delete params.ingressVip;
        } else if (values.stackType === IPV4_STACK) {
          delete params.machineNetworks;
        }
      }

      const { data } = await ClustersAPI.update(cluster.id, params);
      dispatch(updateClusterBase(data));
    } catch (e) {
      handleApiError(e, () =>
        addAlert({ title: 'Failed to update the cluster', message: getErrorMessage(e) }),
      );
    }
  };

  if (isLoading) {
    return <LoadingState />;
  }

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={memoizedValidationSchema}
      onSubmit={handleSubmit}
      initialTouched={initialTouched}
      validateOnMount
    >
      <NetworkConfigurationForm
        cluster={cluster}
        hostSubnets={hostSubnets}
        defaultNetworkSettings={defaultNetworkValues}
        infraEnv={infraEnv}
      />
    </Formik>
  );
}