@patternfly/react-core#Wizard JavaScript Examples

The following examples show how to use @patternfly/react-core#Wizard. 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: EditRequestModal.js    From access-requests-frontend with Apache License 2.0 4 votes vote down vote up
EditRequestModal = ({ requestId, variant, onClose }) => {
  const isEdit = variant === 'edit';
  const [isLoading, setIsLoading] = React.useState(true);
  const [error, setError] = React.useState();
  const [user, setUser] = React.useState();
  const [targetAccount, setTargetAccount] = React.useState();
  const [targetOrg, setTargetOrg] = React.useState();
  const [start, setStart] = React.useState();
  const [end, setEnd] = React.useState();
  const [roles, setRoles] = React.useState([]);
  const [warnClose, setWarnClose] = React.useState(false);
  const [step, setStep] = React.useState(1);
  const dispatch = useDispatch();
  const isDirty = Boolean(targetAccount || start || end || roles.length > 0);

  // We need to be logged in (and see the username) which is an async request.
  // If we're editing we also need to fetch the roles
  React.useEffect(() => {
    const userPromise = window.insights.chrome.auth.getUser();
    const detailsPromise = isEdit
      ? apiInstance.get(
          `${API_BASE}/cross-account-requests/${requestId}/?query_by=user_id`,
          {
            headers: { Accept: 'application/json' },
          }
        )
      : new Promise((res) => res(true));

    Promise.all([userPromise, detailsPromise])
      .then(([user, details]) => {
        if (user && user.identity && user.identity.user) {
          setUser(user.identity.user);
        } else {
          throw Error("Couldn't get current user. Make sure you're logged in");
        }
        if (isEdit) {
          if (details.errors) {
            throw Error(details.errors.map((e) => e.detail).join('\n'));
          }
          if (details && details.target_account) {
            setTargetAccount(details.target_account);
            setStart(details.start_date);
            setEnd(details.end_date);
            setRoles(details.roles.map((role) => role.display_name));
            setTargetOrg(details.target_org);
          } else {
            throw Error(`Could not fetch details for request ${requestId}`);
          }
        }
        setIsLoading(false);
      })
      .catch((err) => {
        dispatch(
          addNotification({
            variant: 'danger',
            title: 'Could not load access request',
            description: err.message,
          })
        );
      });
  }, []);

  const onSave = () => {
    setIsLoading(true);
    // https://cloud.redhat.com/docs/api-docs/rbac#operations-CrossAccountRequest-createCrossAccountRequests
    const body = {
      target_account: targetAccount,
      start_date: start,
      end_date: end,
      target_org: targetOrg,
      roles,
    };
    apiInstance[isEdit ? 'put' : 'post'](
      `${API_BASE}/cross-account-requests/${isEdit ? `/${requestId}/` : ''}`,
      body,
      {
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
        },
      }
    )
      .then((res) => {
        if (res.errors && res.errors.length > 0) {
          throw Error(res.errors[0].detail);
        }
        dispatch(
          addNotification({
            variant: 'success',
            title: `${isEdit ? 'Edited' : 'Created'} access request`,
            description: res.request_id,
          })
        );
        onClose(true);
      })
      .catch((err) => {
        const isInvalidAccount = /Account .* does not exist/.test(err.message);
        setError({
          title: isInvalidAccount
            ? invalidAccountTitle
            : `Could not ${variant} access request`,
          description: isInvalidAccount
            ? 'Please return to Step 1: Request details and input a new account number for your request.'
            : err.message,
        });
        setIsLoading(false);
      });
  };

  const step1Complete = [targetAccount, start, end].every(Boolean);
  const step2Complete = roles.length > 0;
  const steps = [
    {
      id: 1,
      name: 'Request details',
      component: (
        <RequestDetailsForm
          user={user}
          targetAccount={targetAccount}
          setTargetAccount={setTargetAccount}
          targetOrg={targetOrg}
          setTargetOrg={setTargetOrg}
          start={start}
          setStart={setStart}
          end={end}
          setEnd={setEnd}
          disableAccount={isEdit}
          disableOrgId={isEdit}
          isLoading={isLoading}
          error={error}
        />
      ),
      enableNext: step1Complete,
    },
    {
      id: 2,
      name: 'Select roles',
      component: <MUARolesTable roles={roles} setRoles={setRoles} />,
      enableNext: step2Complete,
      canJumpTo: step1Complete,
    },
    {
      id: 3,
      name: 'Review details',
      component: (
        <ReviewStep
          targetAccount={targetAccount}
          start={start}
          end={end}
          roles={roles}
          isLoading={isLoading}
          error={error}
          setError={setError}
          onClose={() => onClose(false)}
        />
      ),
      canJumpTo: step1Complete && step2Complete,
      enableNext: !isLoading,
      nextButtonText: 'Finish',
    },
  ];

  const titleId = `${variant}-request`;
  const descriptionId = `${variant} request`;
  return (
    <React.Fragment>
      <Modal
        variant="large"
        style={{ height: '900px' }}
        showClose={false}
        hasNoBodyWrapper
        isOpen={!warnClose}
        aria-describedby={descriptionId}
        aria-labelledby={titleId}
      >
        <Wizard
          titleId={titleId}
          descriptionId={descriptionId}
          title={capitalize(variant) + ' request'}
          steps={steps}
          onClose={() => (isDirty ? setWarnClose(true) : onClose(false))}
          onSave={onSave}
          startAtStep={step}
          onNext={({ id }) => {
            setError();
            setStep(id);
          }}
          onBack={({ id }) => {
            setError();
            setStep(id);
          }}
          onGoToStep={({ id }) => {
            setError();
            setStep(id);
          }}
        />
      </Modal>
      {warnClose && (
        <Modal
          title="Exit request creation?"
          variant="small"
          titleIconVariant="warning"
          isOpen
          onClose={() => setWarnClose(false)}
          actions={[
            <Button
              key="confirm"
              variant="primary"
              onClick={() => onClose(false)}
            >
              Exit
            </Button>,
            <Button
              key="cancel"
              variant="link"
              onClick={() => setWarnClose(false)}
            >
              Stay
            </Button>,
          ]}
        >
          All inputs will be discarded.
        </Modal>
      )}
    </React.Fragment>
  );
}
Example #2
Source File: new-widget-wizard.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    const { widgetTypes, selectedType, selectedTypeId, stepIdReached, isTitleValid, areParamsFilled } = this.state;
    const steps = [
      {
        id: 1,
        name: 'Select type',
        enableNext: selectedType,
        component: (
          <Form>
            <Title headingLevel="h1" size="xl">Select a widget type</Title>
            {widgetTypes.map(widgetType => {
              return (
                <div key={widgetType.id}>
                  <Radio id={widgetType.id} value={widgetType.id} label={widgetType.title} description={widgetType.description} isChecked={selectedTypeId === widgetType.id} onChange={this.onSelectType}/>
                </div>
              );
            })}
          </Form>
        )
      },
      {
        id: 2,
        name: 'Set info',
        canJumpTo: stepIdReached >= 2,
        enableNext: isTitleValid,
        component: (
          <Form isHorizontal>
            <Title headingLevel="h1" size="xl">Set widget information</Title>
            <FormGroup label="Title" fieldId="widget-title" helperText="A title for the widget" validated={this.isTitleValid} helperTextInvalid="Please enter a title for this widget" helperTextInvalidIcon={<ExclamationCircleIcon/>} isRequired>
              <TextInput type="text" id="widget-title" name="widget-title" value={this.state.title} onChange={this.onTitleChange} validated={this.state.isTitleValid} isRequired />
            </FormGroup>
            <FormGroup label="Weight" fieldId="widget-weight" helperText="How widgets are ordered on the dashboard">
              <TextInput type="number" id="widget-weight" name="widget-weight" value={this.state.weight} onChange={this.onWeightChange} />
            </FormGroup>
          </Form>
        )
      },
      {
        id: 3,
        name: 'Set parameters',
        canJumpTo: stepIdReached >= 3,
        enableNext: areParamsFilled,
        component: (
          <Form isHorizontal>
            <Title headingLevel="h1" size="xl">Set widget parameters</Title>
            {!!selectedType && selectedType.params.map(param => {
              return (
                <React.Fragment key={param.name}>
                {(param.type === 'string' || param.type === 'integer' || param.type === 'float') &&
                  <FormGroup
                    label={param.name}
                    fieldId={param.name}
                    helperText={<Linkify componentDecorator={linkifyDecorator}>{param.description}</Linkify>}
                    isRequired={param.required}>
                    <TextInput
                      value={this.state.params[param.name]}
                      type={(param.type === 'integer' || param.type === 'float') ? 'number' : 'text'}
                      id={param.name}
                      aria-describedby={`${param.name}-helper`}
                      name={param.name}
                      onChange={this.onParamChange}
                      isRequired={param.required}
                    />
                  </FormGroup>
                }
                {param.type === 'boolean' &&
                  <FormGroup
                    label={param.name}
                    fieldId={param.name}
                    isRequired={param.required}
                    hasNoPaddingTop>
                    <Checkbox
                      isChecked={this.state.params[param.name]}
                      onChange={this.onParamChange}
                      id={param.name}
                      name={param.name}
                      label={param.description} />
                  </FormGroup>
                }
                {param.type === 'list' &&
                  <FormGroup
                    label={param.name}
                    fieldId={param.name}
                    helperText={`${param.description}. Place items on separate lines.`}>
                    isRequired={param.required}
                    <TextArea
                      id={param.name}
                      name={param.name}
                      isRequired={param.required}
                      value={this.state.params[param.name]}
                      onChange={this.onParamChange}
                      resizeOrientation='vertical' />
                  </FormGroup>
                }
                </React.Fragment>
              );
            })}
          </Form>
        )
      },
      {
        id: 4,
        name: 'Review details',
        canJumpTo: stepIdReached >= 4,
        nextButtonText: 'Finish',
        component: (
          <Stack hasGutter>
            <StackItem>
              <Title headingLevel="h1" size="xl">Review details</Title>
            </StackItem>
            <StackItem>
              <Grid hasGutter>
                <GridItem span="2">
                  <Title headingLevel="h4">Title</Title>
                </GridItem>
                <GridItem span="10">
                  <TextContent><Text>{this.state.title}</Text></TextContent>
                </GridItem>
                <GridItem span="2">
                  <Title headingLevel="h4">Weight</Title>
                </GridItem>
                <GridItem span="10">
                  <TextContent><Text>{this.state.weight}</Text></TextContent>
                </GridItem>
                <GridItem span="2">
                  <Title headingLevel="h4">Parameters</Title>
                </GridItem>
                <GridItem span="10">
                  <Table
                    cells={["Name", "Value"]}
                    variant="compact"
                    borders="compactBorderless"
                    rows={Object.entries(this.state.params).map(param => { return [param[0], param[1].toString()]; })}
                    aria-label="Parameters">
                    <TableHeader />
                    <TableBody />
                  </Table>
                </GridItem>
              </Grid>
            </StackItem>
          </Stack>
        )
      }
    ];
    return (
      <Modal
        isOpen={this.props.isOpen}
        variant={ModalVariant.large}
        showClose={false}
        onClose={this.onClose}
        hasNoBodyWrapper
        aria-describedby="add-widget-description"
        aria-labelledby="add-widget-title"
      >
        <Wizard
          titleId="add-widget-title"
          descriptionId="add-widget-description"
          title="Add Widget"
          description="Add a widget to the current dashboard"
          steps={steps}
          onNext={this.onNext}
          onSave={this.onSave}
          onClose={this.onClose}
          height={400}
        />
      </Modal>
    );
  }