@patternfly/react-core#Form JavaScript Examples

The following examples show how to use @patternfly/react-core#Form. 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: new-dashboard-modal.js    From ibutsu-server with MIT License 6 votes vote down vote up
render () {
    return (
      <Modal
        variant={ModalVariant.small}
        title="New Dashboard"
        isOpen={this.props.isOpen}
        onClose={this.onClose}
        actions={[
          <Button key="save" variant="primary" onClick={this.onSave}>Save</Button>,
          <Button key="cancel" variant="link" onClick={this.onClose}>Cancel</Button>
        ]}
      >
        <Form>
          <FormGroup label="Title" fieldId="dashboard-title" helperTextInvalid="A dashboard title is required" helperTextInvalidIcon={<ExclamationCircleIcon />} validated={this.state.isTitleValid} isRequired>

            <TextInput type="text" id="dashboard-title" name="dashboard-title" value={this.state.title} onChange={this.onTitleChange} validated={this.state.isTitleValid} isRequired />
          </FormGroup>
          <FormGroup label="Description" fieldId="dashboard-description">
            <TextInput type="text" id="dashboard-description" name="dashboard-description" value={this.state.description} onChange={this.onDescriptionChange} />
          </FormGroup>
        </Form>
      </Modal>
    );
  }
Example #2
Source File: ModalForm.js    From cockpit-wicked with GNU General Public License v2.0 5 votes vote down vote up
ModalForm = ({
    caption,
    title,
    isOpen = false,
    onSubmit,
    onSubmitDisable = false,
    onSubmitLabel = _("Apply"),
    onCancel,
    onCancelLabel = _("Cancel"),
    variant = ModalVariant.small,
    children
}) => {
    if (!isOpen) return;

    return (
        <Modal
            aria-label={title}
            variant={variant}
            isOpen={isOpen}
            showClose={false}
            header={
                <>
                    <Text component={TextVariants.small} className='modal-form-caption'>
                        {caption}
                    </Text>
                    <Title headingLevel="h1">
                        {title}
                    </Title>
                </>
            }
            footer={
                <ActionGroup>
                    <Button key="submit" onClick={onSubmit} isDisabled={onSubmitDisable}>
                        {onSubmitLabel}
                    </Button>

                    <Button key="cancel" variant="link" onClick={onCancel}>
                        {onCancelLabel}
                    </Button>
                </ActionGroup>
            }
        >

            <Form>
                {children}
            </Form>
        </Modal>
    );
}
Example #3
Source File: report-builder.js    From ibutsu-server with MIT License 5 votes vote down vote up
render() {
    document.title = 'Report Builder | Ibutsu';
    const { columns, rows, actions } = this.state;
    const reportTypes = this.state.reportTypes.map((reportType) => <FormSelectOption key={reportType.type} value={reportType.type} label={reportType.name} />);
    const pagination = {
      page: this.state.page,
      pageSize: this.state.pageSize,
      totalItems: this.state.totalItems
    };
    return (
      <React.Fragment>
        <PageSection variant={PageSectionVariants.light}>
          <TextContent>
            <Text component="h1">Report Builder</Text>
          </TextContent>
        </PageSection>
        <PageSection>
          <Card>
            <CardBody>
              <Form isHorizontal>
                <FormGroup isRequired label="Report Type" helperText="The type of report" fieldId="report-type">
                  <FormSelect id="report-type" value={this.state.reportType} onChange={this.onReportTypeChange}>
                    {reportTypes}
                  </FormSelect>
                </FormGroup>
                <FormGroup label="Filter" fieldId="report-filter">
                  <TextInput type="text" id="report-filter" value={this.state.reportFilter} onChange={this.onReportFilterChange} />
                  <ExpandableSection toggleText="Filter Help" onToggle={this.onHelpToggle} isExpanded={this.state.isHelpExpanded}>
                    <TextContent>
                      <p>The filter parameter takes a comma-separated list of filters to apply. <Linkify componentDecorator={linkifyDecorator}>https://docs.ibutsu-project.org/en/latest/user-guide/filter-help.html</Linkify></p>
                    </TextContent>
                  </ExpandableSection>
                </FormGroup>
                <FormGroup label="Source" helperText="The source of report" fieldId="report-source">
                  <TextInput type="text" id="report-source" value={this.state.reportSource} onChange={this.onReportSourceChange} />
                </FormGroup>
                <ActionGroup>
                  <Button variant="primary" onClick={this.onRunReportClick}>Run Report</Button>
                </ActionGroup>
              </Form>
            </CardBody>
            <CardFooter>
              <Text className="disclaimer" component="h4">
                * Note: reports can only show a maximum of 100,000 results.
              </Text>
            </CardFooter>
          </Card>
        </PageSection>
        <PageSection>
          <Card>
            <CardBody>
              <FilterTable
                columns={columns}
                rows={rows}
                actions={actions}
                pagination={pagination}
                isEmpty={this.state.isEmpty}
                isError={this.state.isError}
                onSetPage={this.setPage}
                onSetPageSize={this.setPageSize}
              />
            </CardBody>
          </Card>
        </PageSection>
      </React.Fragment>
    );
  }
Example #4
Source File: add-token-modal.js    From ibutsu-server with MIT License 5 votes vote down vote up
render () {
    return (
      <Modal
        variant={ModalVariant.small}
        title="Add Token"
        isOpen={this.props.isOpen}
        onClose={this.onClose}
        actions={[
          <Button key="save" variant="primary" onClick={this.onSave}>Save</Button>,
          <Button key="cancel" variant="link" onClick={this.onClose}>Cancel</Button>
        ]}
      >
        <Form>
          <FormGroup
            label="Name"
            fieldId="token-name"
            helperTextInvalid="A token name is required"
            helperTextInvalidIcon={<ExclamationCircleIcon />}
            validated={this.state.isNameValid ? ValidatedOptions.default : ValidatedOptions.error}
            isRequired
          >
            <TextInput
              type="text"
              id="token-name"
              name="token-name"
              value={this.state.name}
              onChange={this.onNameChange}
              validated={this.state.isNameValid ? ValidatedOptions.default : ValidatedOptions.error}
              isRequired
            />
          </FormGroup>
          <FormGroup
            label="Expiry"
            fieldId="token-expiry-date"
            helperTextInvalid="A valid epiry date is required"
            helperTextInvalidIcon={<ExclamationCircleIcon />}
            validated={this.state.isExpiryValid ? ValidatedOptions.default : ValidatedOptions.error}
            isRequired
          >
            <DatePicker
              onChange={this.onExpiryDateChange}
              value={this.state.expiryDate}
              inputProps={{
                id: "token-expiry-date",
                validated: this.state.isExpiryValid ? ValidatedOptions.default : ValidatedOptions.error
              }}
            />
          </FormGroup>
        </Form>
      </Modal>
    );
  }
Example #5
Source File: project-edit.js    From ibutsu-server with MIT License 5 votes vote down vote up
render() {
    const { project, users, owner } = this.state;
    return (
      <React.Fragment>
        <PageSection variant={PageSectionVariants.light}>
          <Title headingLevel="h1" size='2xl' className="pf-c-title">
            Projects / {project && project.title}
          </Title>
        </PageSection>
        <PageSection>
          {!project && <Alert variant="info" title="Loading..." />}
          {project &&
          <Card>
            <CardBody>
              <Form>
                <FormGroup label="Title" isRequired fieldId="projectTitle" helperText="The project's friendly name">
                  <TextInput
                    isRequired
                    type="text"
                    id="projectTitle"
                    name="projectTitle"
                    aria-describedby="The project's friendly name"
                    value={project.title}
                    onChange={this.onProjectTitleChanged}
                  />
                </FormGroup>
                <FormGroup label="Name" isRequired fieldId="projectName" helperText="The project's machine name">
                  <TextInput
                    isRequired
                    type="text"
                    id="projectName"
                    name="projectName"
                    aria-describedby="The project's machine name"
                    value={project.name}
                    onChange={this.onProjectNameChanged}
                  />
                </FormGroup>
                <FormGroup fieldId="owner" label="Owner" helperText="The user who owns the project">
                   <Select
                     variant={SelectVariant.typeahead}
                     typeAheadAriaLabel="Select user"
                     onToggle={this.onOwnerToggle}
                     onSelect={this.onOwnerSelect}
                     onClear={this.onOwnerClear}
                     onTypeaheadInputChanged={this.onOwnerChanged}
                     selections={owner}
                     isOpen={this.state.isOwnerOpen}
                     aria-labelledby="owner"
                     placeholderText="Select user"
                   >
                     {users.map(user => (
                       <SelectOption key={user.id} value={userToOption(user)} description={user.email} />
                     ))}
                   </Select>
                </FormGroup>
                <ActionGroup>
                  <Button
                    variant="primary"
                    ouiaId="admin-project-edit-save"
                    onClick={this.onSubmitClick}
                  >
                    Submit
                  </Button>
                  <Button
                    variant="secondary"
                    ouiaId="admin-project-edit-cancel"
                    component={(props: any) => <Link {...props} to="/admin/projects" />}
                  >
                    Cancel
                  </Button>
                </ActionGroup>
              </Form>
            </CardBody>
          </Card>
          }
        </PageSection>
      </React.Fragment>
    );
  }
Example #6
Source File: forgot-password.js    From ibutsu-server with MIT License 5 votes vote down vote up
render() {
    const signUpForAccountMessage = (
      <LoginMainFooterBandItem>
        Need an account? <NavLink to="/sign-up">Sign up.</NavLink>
      </LoginMainFooterBandItem>
    );
    const forgotCredentials = (
      <LoginMainFooterBandItem>
        Already registered? <NavLink to="/login">Log in.</NavLink>
      </LoginMainFooterBandItem>
    );

    const backgroundImages = {
      lg: '/images/pfbg_1200.jpg',
      sm: '/images/pfbg_768.jpg',
      sm2x: '/images/[email protected]',
      xs: '/images/pfbg_576.jpg',
      xs2x: '/images/[email protected]'
    };

    return (
      <LoginPage
        footerListVariants="inline"
        brandImgSrc="/images/ibutsu-wordart-164.png"
        brandImgAlt="Ibutsu"
        backgroundImgSrc={backgroundImages}
        backgroundImgAlt="Background image"
        textContent="Ibutsu is an open source test result aggregation. Collect and display your test results, view artifacts, and monitor tests."
        loginTitle="Recover your account"
        loginSubtitle="Please type in your e-mail address and a reset link will be sent to it."
        signUpForAccountMessage={signUpForAccountMessage}
        forgotCredentials={forgotCredentials}
      >
        <Form>
          {this.state.showAlert &&
          <FormAlert>
            <Alert variant={this.state.alertType} title={this.state.alertText} aria-live="polite" isInline/>
          </FormAlert>
          }
          <FormGroup
            label="Email address"
            isRequired
            fieldId="email"
            validated={this.state.isValidEmail ? 'default' : 'error'}
            helperText="The e-mail address you signed up with"
          >
            <TextInput
              isRequired
              type="email"
              id="email"
              name="email"
              validated={this.state.isValidEmail ? 'default' : 'error'}
              aria-describedby="email-helper"
              value={this.state.emailValue}
              onChange={this.onEmailChange}
            />
          </FormGroup>
          <ActionGroup>
            <Button variant="primary" isBlock onClick={this.onRecoverAccountClick}>Recover account</Button>
          </ActionGroup>
        </Form>
      </LoginPage>
    );
  }
Example #7
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>
    );
  }
Example #8
Source File: WirelessForm.js    From cockpit-wicked with GNU General Public License v2.0 4 votes vote down vote up
WirelessForm = ({ isOpen, onClose, iface, connection }) => {
    const { wireless } = connection || {};
    const isEditing = !!connection;
    const [essid, setEssid] = useState(wireless?.essid);
    const [mode, setMode] = useState(wireless?.mode || wirelessModes.MANAGED);
    const [authMode, setAuthMode] = useState(wireless?.authMode || wirelessAuthModes.WEP_OPEN);
    const [password, setPassword] = useState(wireless?.password || "");
    const dispatch = useNetworkDispatch();

    const addOrUpdateConnection = () => {
        if (isEditing) {
            updateConnection(
                dispatch, connection,
                { wireless: { essid, mode, authMode, password } }
            );
        } else {
            addConnection(
                dispatch, { name: iface.name, type: interfaceType.WIRELESS, wireless: { essid, mode, authMode, password } }
            );
        }
        onClose();
    };

    return (
        <Modal
            variant={ModalVariant.small}
            title={isEditing ? _("Edit WiFi settings") : _("Add WiFi settings")}
            isOpen={isOpen}
            onClose={onClose}
            actions={[
                <Button key="confirm" variant="primary" onClick={addOrUpdateConnection}>
                    {isEditing ? _("Change") : _("Add")}
                </Button>,
                <Button key="cancel" variant="link" onClick={onClose}>
                    {_("Cancel")}
                </Button>
            ]}
        >
            <Form>
                <FormGroup
                    label={_("Mode")}
                    isRequired
                    fieldId="wireless-mode"
                >
                    <FormSelect value={mode} onChange={setMode} id="wireless-mode">
                        {modeOptions.map((option, index) => (
                            <FormSelectOption key={index} {...option} />
                        ))}
                    </FormSelect>
                </FormGroup>

                <FormGroup
                    label={_("ESSID")}
                    isRequired
                    fieldId="essid"
                >
                    <WirelessEssidSelect essid={essid} setEssid={setEssid} iface={iface} />
                </FormGroup>
                <FormGroup
                    label={_("Auth Mode")}
                    isRequired
                    fieldId="wireless-auth-mode"
                >
                    <FormSelect value={authMode} onChange={setAuthMode} id="wireless-auth-mode">
                        {authModeOptions.map((option, index) => (
                            <FormSelectOption key={index} {...option} />
                        ))}
                    </FormSelect>
                </FormGroup>
                { (authMode === "psk") &&
                    <FormGroup
                        label={_("Password")}
                        isRequired
                        fieldId="password"
                    >
                        <TextInput
                            isRequired
                            id="password"
                            value={password}
                            onChange={setPassword}
                            type='password'
                        />
                    </FormGroup>}
            </Form>
        </Modal>
    );
}
Example #9
Source File: sign-up.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    const loginMessage = (
      <LoginMainFooterBandItem>
        Already registered? <NavLink to="/login">Log in.</NavLink>
      </LoginMainFooterBandItem>
    );
    const forgotCredentials = (
      <LoginMainFooterBandItem>
        <NavLink to="/forgot-password">Forgot username or password?</NavLink>
      </LoginMainFooterBandItem>
    );

    const backgroundImages = {
      lg: '/images/pfbg_1200.jpg',
      sm: '/images/pfbg_768.jpg',
      sm2x: '/images/[email protected]',
      xs: '/images/pfbg_576.jpg',
      xs2x: '/images/[email protected]'
    };

    return (
      <LoginPage
        footerListVariants="inline"
        brandImgSrc="/images/ibutsu-wordart-164.png"
        brandImgAlt="Ibutsu"
        backgroundImgSrc={backgroundImages}
        backgroundImgAlt="Background image"
        textContent="Ibutsu is an open source test result aggregation. Collect and display your test results, view artifacts, and monitor tests."
        loginTitle="Register a new account"
        loginSubtitle="Please type in your e-mail address and a secure password"
        signUpForAccountMessage={loginMessage}
        forgotCredentials={forgotCredentials}
      >
        <Form>
          {this.state.showAlert &&
          <FormAlert>
            <Alert variant={this.state.alertType} title={this.state.alertText} aria-live="polite" isInline/>
          </FormAlert>
          }
          <FormGroup
            label="Email address"
            isRequired
            fieldId="email"
            validated={this.state.isValidEmail ? 'default' : 'error'}
            helperText="The e-mail address you want to use to log in"
          >
            <TextInput
              isRequired
              type="email"
              id="email"
              name="email"
              validated={this.state.isValidEmail ? 'default' : 'error'}
              aria-describedby="email-helper"
              value={this.state.emailValue}
              onChange={this.onEmailChange}
            />
          </FormGroup>
          <FormGroup
            label="Password"
            isRequired
            fieldId="password"
            validated={this.state.isValidPassword ? 'default' : 'error'}
          >
            <InputGroup>
              {!this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="password"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange} />
              }
              {this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="text"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange} />}
              <Button variant="control" aria-label="Show password" onClick={this.onPasswordVisibleClick}>
                {!this.state.isPasswordVisible && <EyeIcon/>}
                {this.state.isPasswordVisible && <EyeSlashIcon/>}
              </Button>
            </InputGroup>
            <PasswordErrorBoundary>
              <Suspense fallback={""}>
                <PasswordStrengthBar password={this.state.passwordValue}/>
              </Suspense>
            </PasswordErrorBoundary>
          </FormGroup>
          <FormGroup
            label="Confirm password"
            isRequired
            fieldId="confirm-password"
            helperText={this.state.confirmPasswordHelpText}
            helperTextInvalid="Passwords do not match"
            validated={this.state.confirmPasswordValidation}
          >
            <InputGroup>
              {!this.state.isConfirmPasswordVisible && <TextInput isRequired type="password" id="confirm-password" name="confirm-password" aria-describedby="confirm-password-helper" value={this.state.confirmPasswordValue} onChange={this.onConfirmPasswordChange} validated={this.state.confirmPasswordValidation} />}
              {this.state.isConfirmPasswordVisible && <TextInput isRequired type="text" id="confirm-password" name="confirm-password" aria-describedby="confirm-password-helper" value={this.state.confirmPasswordValue} onChange={this.onConfirmPasswordChange} validated={this.state.confirmPasswordValidation} />}
              <Button variant="control" aria-label="Show password" onClick={this.onConfirmPasswordVisibleClick}>
                {!this.state.isConfirmPasswordVisible && <EyeIcon/>}
                {this.state.isConfirmPasswordVisible && <EyeSlashIcon/>}
              </Button>
            </InputGroup>
          </FormGroup>
          <ActionGroup>
            <Button variant="primary" isBlock onClick={this.onRegisterButtonClick}>Register</Button>
          </ActionGroup>
        </Form>
      </LoginPage>
    );
  }
Example #10
Source File: reset-password.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    const loginMessage = (
      <LoginMainFooterBandItem>
        Already registered? <NavLink to="/login">Log in.</NavLink>
      </LoginMainFooterBandItem>
    );
    const forgotCredentials = (
      <LoginMainFooterBandItem>
        <NavLink to="/forgot-password">Forgot username or password?</NavLink>
      </LoginMainFooterBandItem>
    );

    const backgroundImages = {
      lg: '/images/pfbg_1200.jpg',
      sm: '/images/pfbg_768.jpg',
      sm2x: '/images/[email protected]',
      xs: '/images/pfbg_576.jpg',
      xs2x: '/images/[email protected]'
    };

    return (
      <LoginPage
        footerListVariants="inline"
        brandImgSrc="/images/ibutsu-wordart-164.png"
        brandImgAlt="Ibutsu"
        backgroundImgSrc={backgroundImages}
        backgroundImgAlt="Background image"
        textContent="Ibutsu is an open source test result aggregation. Collect and display your test results, view artifacts, and monitor tests."
        loginTitle="Reset your password"
        loginSubtitle="Please type in a secure password"
        signUpForAccountMessage={loginMessage}
        forgotCredentials={forgotCredentials}
      >
        <Form>
          {this.state.showAlert &&
          <FormAlert>
            <Alert variant={this.state.alertType} title={this.state.alertText} aria-live="polite" isInline/>
          </FormAlert>
          }
          <FormGroup
            label="Password"
            isRequired
            fieldId="password"
            validated={this.state.isValidPassword ? 'default' : 'error'}
          >
            <InputGroup>
              {!this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="password"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange} />
              }
              {this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="text"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange} />}
              <Button variant="control" aria-label="Show password" onClick={this.onPasswordVisibleClick}>
                {!this.state.isPasswordVisible && <EyeIcon/>}
                {this.state.isPasswordVisible && <EyeSlashIcon/>}
              </Button>
            </InputGroup>
            <PasswordErrorBoundary>
              <Suspense fallback={""}>
                <PasswordStrengthBar password={this.state.passwordValue}/>
              </Suspense>
            </PasswordErrorBoundary>
          </FormGroup>
          <FormGroup
            label="Confirm password"
            isRequired
            fieldId="confirm-password"
            helperText={this.state.confirmPasswordHelpText}
            helperTextInvalid="Passwords do not match"
            validated={this.state.confirmPasswordValidation}
          >
            <InputGroup>
              {!this.state.isConfirmPasswordVisible && <TextInput isRequired type="password" id="confirm-password" name="confirm-password" aria-describedby="confirm-password-helper" value={this.state.confirmPasswordValue} onChange={this.onConfirmPasswordChange} validated={this.state.confirmPasswordValidation} />}
              {this.state.isConfirmPasswordVisible && <TextInput isRequired type="text" id="confirm-password" name="confirm-password" aria-describedby="confirm-password-helper" value={this.state.confirmPasswordValue} onChange={this.onConfirmPasswordChange} validated={this.state.confirmPasswordValidation} />}
              <Button variant="control" aria-label="Show password" onClick={this.onConfirmPasswordVisibleClick}>
                {!this.state.isConfirmPasswordVisible && <EyeIcon/>}
                {this.state.isConfirmPasswordVisible && <EyeSlashIcon/>}
              </Button>
            </InputGroup>
          </FormGroup>
          <ActionGroup>
            <Button variant="primary" isBlock onClick={this.onResetButtonClick}>Reset Password</Button>
          </ActionGroup>
        </Form>
      </LoginPage>
    );
  }
Example #11
Source File: user-edit.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    const { user, projects, userProjects } = this.state;
    return (
      <React.Fragment>
        <PageSection variant={PageSectionVariants.light}>
          <Title headingLevel="h1" size='2xl' className="pf-c-title">
            Users / {user && user.name} {' '}
            {user && user.is_superadmin &&
              <Label className="super-admin-label" variant="outline" color="blue">Administrator</Label>
            }
          </Title>
        </PageSection>
        <PageSection>
          {!user && <Alert variant="info" title="Loading..." />}
          {user &&
          <Card>
            <CardBody>
              <Form>
                <FormGroup label="Name" isRequired fieldId="userName" helperText="The user's name">
                  <TextInput
                    isRequired
                    type="text"
                    id="userName"
                    name="userName"
                    aria-describedby="The user's name"
                    value={user.name}
                    onChange={this.onUserNameChanged}
                  />
                </FormGroup>
                <FormGroup label="E-mail" isRequired fieldId="userEmail" helperText="The user's e-mail address">
                  <TextInput
                    isRequired
                    type="email"
                    id="userEmail"
                    name="userEmail"
                    aria-describedby="The user's e-mail address"
                    value={user.email}
                    onChange={this.onUserEmailChanged}
                  />
                </FormGroup>
                <FormGroup fieldId="userStatus" label="User status">
                  <Checkbox
                    label="Is active"
                    id="userIsActive"
                    name="userIsActive"
                    aria-label="User is active"
                    isChecked={user.is_active}
                    onChange={this.onIsActiveToggle}
                  />
                  <Checkbox
                    label="Is administrator"
                    id="userIsAdmin"
                    name="userIsAdmin"
                    aria-label="User is administrator"
                    isChecked={user.is_superadmin}
                    onChange={this.onIsAdminToggle}
                  />
                </FormGroup>
                <FormGroup fieldId="userProjects" label="Projects" helperText="The projects to which a user has access">
                   <Select
                     variant={SelectVariant.typeaheadMulti}
                     typeAheadAriaLabel="Select one or more projects"
                     onToggle={this.onProjectsToggle}
                     onSelect={this.onProjectsSelect}
                     onClear={this.onProjectsClear}
                     selections={userProjects}
                     isOpen={this.state.isProjectsOpen}
                     aria-labelledby="userProjects"
                     placeholderText="Select one or more projects"
                   >
                     {projects.map(project => (
                       <SelectOption key={project.id} value={projectToOption(project)} description={project.name} />
                     ))}
                   </Select>
                </FormGroup>
                <ActionGroup>
                  <Button variant="primary" onClick={this.onSubmitClick}>Submit</Button>
                  <Button variant="secondary" onClick={this.props.history.goBack}>Cancel</Button>
                </ActionGroup>
              </Form>
            </CardBody>
          </Card>
          }
        </PageSection>
      </React.Fragment>
    );
  }
Example #12
Source File: login.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    const socialMediaLoginContent = (
      <React.Fragment>
        {this.state.externalLogins.keycloak &&
        <LoginMainFooterLinksItem onClick={this.onKeycloakLogin} href="#" linkComponentProps={{ 'aria-label': `Login with ${this.getKeycloakName()}`, 'title': `Login with ${this.getKeycloakName()}` }}>
            {this.getKeycloakIcon()}
          </LoginMainFooterLinksItem>
        }
        {this.state.externalLogins.google &&
          <GoogleLogin
            clientId={this.state.externalLogins.google.client_id}
            scope={this.state.externalLogins.google.scope}
            redirectUri={this.state.externalLogins.google.redirect_uri}
            onSuccess={this.onGoogleLogin}
            onFailure={(response) => console.error(response)}
            render={renderProps => (
              <LoginMainFooterLinksItem onClick={renderProps.onClick} href="#" linkComponentProps={{ 'aria-label': 'Login with Google', 'title': 'Login with Google' }}>
                <GoogleIcon size="lg" />
              </LoginMainFooterLinksItem>
            )}
          />
        }
        {this.state.externalLogins.github &&
          <OAuth2Login
            isCrossOrigin={true}
            authorizationUrl={this.state.externalLogins.github.authorization_url}
            responseType="code"
            clientId={this.state.externalLogins.github.client_id}
            redirectUri={this.state.externalLogins.github.redirect_uri}
            scope={this.state.externalLogins.github.scope}
            onSuccess={this.onOAuth2Success}
            onFailure={(response) => console.error(response)}
            render={renderProps => (
              <LoginMainFooterLinksItem onClick={renderProps.onClick} href="#" linkComponentProps={{ 'aria-label': 'Login with GitHub', 'title': 'Login with GitHub' }}>
                <GithubIcon size="lg" />
              </LoginMainFooterLinksItem>
            )}
          />
        }
        {this.state.externalLogins.facebook &&
          <FacebookLogin
            appId={this.state.externalLogins.facebook.app_id}
            onSuccess={this.onFacebookLogin}
            onFail={(response) => console.error(response)}
            // useRedirect={true}
            dialogParams={{redirect_uri: this.state.externalLogins.facebook.redirect_uri, response_type: 'code'}}
            render={(renderProps) => (
              <LoginMainFooterLinksItem onClick={renderProps.onClick} href="#" linkComponentProps={{ 'aria-label': 'Login with Facebook' }}>
                <FacebookIcon size="lg" />
              </LoginMainFooterLinksItem>
            )}
          />
        }
        {this.state.externalLogins.gitlab &&
            <OAuth2Login
              isCrossOrigin={true}
              authorizationUrl={this.state.externalLogins.gitlab.authorization_url}
              responseType="code"
              clientId={this.state.externalLogins.gitlab.client_id}
              redirectUri={this.state.externalLogins.gitlab.redirect_uri}
              scope={this.state.externalLogins.gitlab.scope}
              onSuccess={this.onOAuth2Success}
              onFailure={(response) => console.error(response)}
              render={renderProps => (
                <LoginMainFooterLinksItem onClick={renderProps.onClick} href="#" linkComponentProps={{ 'aria-label': 'Login with GitLab', 'title': 'Login with GitLab' }}>
                  <GitlabIcon size="lg" />
                </LoginMainFooterLinksItem>
              )}
            />
        }
      </React.Fragment>
    );

    const signUpForAccountMessage = (
      <LoginMainFooterBandItem>
        Need an account? <NavLink to="/sign-up">Sign up.</NavLink>
      </LoginMainFooterBandItem>
    );
    const forgotCredentials = (
      <LoginMainFooterBandItem>
        <NavLink to="/forgot-password">Forgot username or password?</NavLink>
      </LoginMainFooterBandItem>
    );
    const loginWithUserDescription = 'Please use your e-mail address and password, or login via one of the icons below the Log In button.';
    const loginWithoutUserDescription = 'Log in via one of the icons below.';

    const backgroundImages = {
      lg: '/images/pfbg_1200.jpg',
      sm: '/images/pfbg_768.jpg',
      sm2x: '/images/[email protected]',
      xs: '/images/pfbg_576.jpg',
      xs2x: '/images/[email protected]'
    };

    return (
      <LoginPage
        footerListVariants="inline"
        brandImgSrc="/images/ibutsu-wordart-164.png"
        brandImgAlt="Ibutsu"
        backgroundImgSrc={backgroundImages}
        backgroundImgAlt="Background image"
        textContent="Ibutsu is an open source test result aggregation tool. Collect and display your test results, view artifacts, and monitor tests."
        loginTitle="Log in to your account"
        loginSubtitle={this.state.loginSupport.user ? loginWithUserDescription : loginWithoutUserDescription}
        socialMediaLoginContent={socialMediaLoginContent}
        signUpForAccountMessage={this.state.loginSupport.user ? signUpForAccountMessage : ''}
        forgotCredentials={this.state.loginSupport.user ? forgotCredentials : ''}
      >
        {this.state.loginSupport.user &&
        <Form>
          <FormAlert>
          {this.state.alert && this.state.alert.message &&
            <Alert
              variant={this.state.alert.status || 'info'}
              title={this.state.alert.message}
              aria-live="polite"
              isInline
            />
          }
          </FormAlert>
          <FormGroup
            label="Email address"
            isRequired
            fieldId="email"
            validated={this.state.isValidEmail ? 'default' : 'error'}
          >
            <TextInput
              isRequired
              type="email"
              id="email"
              name="email"
              validated={this.state.isValidEmail ? 'default' : 'error'}
              aria-describedby="email-helper"
              value={this.state.emailValue}
              onChange={this.onEmailChange}
              onKeyPress={this.onEnterKeyPress}
            />
          </FormGroup>
          <FormGroup
            label="Password"
            isRequired
            fieldId="password"
            validated={this.state.isValidPassword ? 'default' : 'error'}
          >
            <InputGroup>
              {!this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="password"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange}
                onKeyPress={this.onEnterKeyPress} />
              }
              {this.state.isPasswordVisible &&
              <TextInput
                isRequired
                type="text"
                id="password"
                name="password"
                validated={this.state.isValidPassword ? 'default' : 'error'}
                aria-describedby="password-helper"
                value={this.state.passwordValue}
                onChange={this.onPasswordChange}
                onKeyPress={this.onEnterKeyPress} />
              }
              <Button variant="control" aria-label="Show password" onClick={this.onPasswordVisibleClick}>
                {!this.state.isPasswordVisible && <EyeIcon/>}
                {this.state.isPasswordVisible && <EyeSlashIcon/>}
              </Button>
            </InputGroup>
          </FormGroup>
          <ActionGroup>
            <Button
              variant="primary"
              isBlock
              isLoading={this.state.isLoggingIn}
              isDisabled={this.state.isLoggingIn}
              onClick={this.onLoginButtonClick}
            >
              {this.state.isLoggingIn ? 'Logging in...' : 'Log In'}
            </Button>
          </ActionGroup>
        </Form>
        }
      </LoginPage>
    );
  }
Example #13
Source File: EditRequestModal.js    From access-requests-frontend with Apache License 2.0 4 votes vote down vote up
RequestDetailsForm = ({
  user = {},
  targetAccount,
  setTargetAccount,
  targetOrg,
  setTargetOrg,
  start,
  setStart,
  end,
  setEnd,
  disableAccount,
  disableOrgId,
  isLoading,
  error,
}) => {
  let [startDate, setStartDate] = React.useState();
  const [validatedAccount, setValidatedAccount] = React.useState(
    error ? 'error' : 'default'
  );

  const [validatedOrgId, setValidatedOrgId] = React.useState(
    error ? 'error' : 'default'
  );

  // https://github.com/RedHatInsights/insights-rbac/blob/master/rbac/api/cross_access/model.py#L49
  const startValidator = (date) => {
    if (isValidDate(date)) {
      if (date < today) {
        setEnd('');
        return 'Start date must be today or later';
      }
      if (date > maxStartDate) {
        setEnd('');
        return 'Start date must be within 60 days of today';
      }
    }

    return '';
  };

  const endValidator = (date) => {
    if (isValidDate(startDate)) {
      if (startDate > date) {
        return 'End date must be after from date';
      }
    }

    const maxToDate = new Date(startDate);
    maxToDate.setFullYear(maxToDate.getFullYear() + 1);
    if (date > maxToDate) {
      return 'Access duration may not be longer than one year';
    }

    return '';
  };

  const onStartChange = (str, date) => {
    setStartDate(new Date(date));
    setStart(str);
    if (isValidDate(date) && !startValidator(date)) {
      date.setDate(date.getDate() + 7);
      setEnd(dateFormat(date));
    } else {
      setEnd('');
    }
  };

  const onEndChange = (str, date) => {
    if (endValidator(date)) {
      setEnd('');
    } else {
      setEnd(str);
    }
  };

  return (
    <Form onSubmit={(ev) => ev.preventDefault()} isDisabled={isLoading}>
      <Title headingLevel="h2">Request details</Title>
      <Split hasGutter>
        <SplitItem isFilled>
          <FormGroup label="First name" labelIcon={getLabelIcon('first name')}>
            <TextInput id="first-name" value={user.first_name} isDisabled />
          </FormGroup>
        </SplitItem>
        <SplitItem isFilled>
          <FormGroup label="Last name" labelIcon={getLabelIcon('last name')}>
            <TextInput id="last-name" value={user.last_name} isDisabled />
          </FormGroup>
        </SplitItem>
      </Split>
      <FormGroup
        label="Account number"
        isRequired
        labelIcon={getLabelIcon('account number')}
        helperText="Enter the account number you would like access to"
        helperTextInvalid="Please enter a valid account number"
        validated={validatedAccount}
      >
        <TextInput
          id="account-number"
          value={targetAccount}
          onChange={(val) => {
            setTargetAccount(val);
            setValidatedAccount('default');
          }}
          isRequired
          placeholder="Example, 8675309"
          validated={validatedAccount}
          isDisabled={disableAccount}
        />
      </FormGroup>
      <FormGroup
        label="Organization id"
        isRequired
        labelIcon={getLabelIcon('organization id')}
        helperText="Enter the organization id you would like access to"
        helperTextInvalid="Please enter a valid organization id"
        validated={validatedOrgId}
      >
        <TextInput
          id="org-id"
          value={targetOrg}
          onChange={(val) => {
            setTargetOrg(val);
            setValidatedOrgId('default');
          }}
          isRequired
          placeholder="Example, 1234567"
          validated={validatedOrgId}
          isDisabled={disableOrgId}
        />
      </FormGroup>
      <FormGroup
        label="Access duration"
        isRequired
        labelIcon={getLabelIcon('access duration')}
      >
        <Split>
          <SplitItem>
            <DatePicker
              width="300px"
              aria-label="Start date"
              value={start}
              dateFormat={dateFormat}
              dateParse={dateParse}
              placeholder="mm/dd/yyyy"
              onChange={onStartChange}
              validators={[startValidator]}
            />
          </SplitItem>
          <SplitItem style={{ padding: '6px 12px 0 12px' }}>to</SplitItem>
          <SplitItem>
            <DatePicker
              width="300px"
              aria-label="End date"
              value={end}
              dateFormat={dateFormat}
              dateParse={dateParse}
              placeholder="mm/dd/yyyy"
              onChange={onEndChange}
              validators={[endValidator]}
              rangeStart={start}
            />
          </SplitItem>
        </Split>
      </FormGroup>
    </Form>
  );
}
Example #14
Source File: requestCertificate.jsx    From cockpit-certificates with GNU Lesser General Public License v2.1 4 votes vote down vote up
RequestCertificateModal = ({ onClose, hostname, cas, addAlert, mode }) => {
    const [_userChangedNickname, setUserChangedNickname] = useState(false);
    const [ca, _setCa] = useState(cas[Object.keys(cas)[0]] ? cas[Object.keys(cas)[0]].nickname.v : undefined);
    const [storage, setStorage] = useState(mode === "request" ? "nssdb" : "file");
    const [nickname, _setNickname] = useState(makeNickName(hostname, ca));
    const [certFile, setCertFile] = useState("");
    const [keyFile, setKeyFile] = useState("");
    const [subjectName, setSubjectName] = useState("");
    const [dnsName, _setDnsName] = useState("");
    const [principalName, setPricipalName] = useState("");
    const [signingParameters, setSigningParameters] = useState("");
    const [errorName, setErrorName] = useState();
    const [errorMessage, setErrorMessage] = useState();

    const setCa = value => {
        if (!_userChangedNickname)
            _setNickname(makeNickName(hostname, value));

        _setCa(value);
    };

    const setNickname = value => {
        setUserChangedNickname(true);
        _setNickname(value);
    };

    const setDnsName = value => {
        value = value.replace(/\s/g, ',');
        while (value.includes(",,"))
            value = value.replace(",,", ',');
        _setDnsName(value);
    };

    const onRequest = () => {
        const casKeys = Object.keys(cas);
        let caPath;
        casKeys.forEach(key => {
            if (cas[key].nickname.v === ca)
                caPath = key;
        });

        const parameter = {
            "cert-storage": cockpit.variant("s", storage),
            "key-storage": cockpit.variant("s", storage),
            ca: cockpit.variant("s", caPath),
        };

        if (storage === "nssdb") {
            parameter["cert-database"] = cockpit.variant("s", NSSDB_PATH);
            parameter["cert-nickname"] = cockpit.variant("s", nickname);
            parameter["key-database"] = cockpit.variant("s", NSSDB_PATH);
            parameter["key-nickname"] = cockpit.variant("s", nickname);
        } else { // file
            parameter["cert-file"] = cockpit.variant("s", certFile);
            parameter["key-file"] = cockpit.variant("s", keyFile);
        }

        if (signingParameters) {
            let subjectNameParam;
            if (subjectName && !subjectName.includes("="))
                subjectNameParam = "CN=" + subjectName;
            let dnsNamesParam = dnsName.split(',');
            dnsNamesParam = dnsNamesParam.filter(Boolean); // Removes empty string entries

            if (subjectName)
                parameter["template-subject"] = cockpit.variant("s", subjectNameParam);
            if (principalName)
                parameter["template-principal"] = cockpit.variant("as", [principalName]);
            if (dnsName)
                parameter["template-hostname"] = cockpit.variant("as", dnsNamesParam);
        }

        addRequest(parameter)
                .then(onClose)
                .catch(error => {
                    setErrorName(error.name);
                    setErrorMessage(error.message);
                });
    };

    const body = (
        <Form isHorizontal>
            <CAsRow ca={ca} setCa={setCa} cas={Object.values(cas)} />

            <StorageRow storage={storage} setStorage={setStorage} />
            {storage === "nssdb" &&
                <NicknameRow nickname={nickname} setNickname={setNickname} />}

            {storage === "file" && <>
                <CertFileRow setCertFile={setCertFile} mode={mode} />
                <KeyFileRow setKeyFile={setKeyFile} mode={mode} />
            </>}

            <SetSigningParametersRow signingParameters={signingParameters} setSigningParameters={setSigningParameters} />
            {signingParameters && <>
                <SubjectNameRow subjectName={subjectName} setSubjectName={setSubjectName} />
                <DNSNameRow dnsName={dnsName} setDnsName={setDnsName} />
                <PrincipalNameRow principalName={principalName} setPricipalName={setPricipalName} />
            </>}
        </Form>
    );

    return (
        <Modal id="request-certificate-dialog" onClose={onClose}
               position="top" variant="medium"
               isOpen
               title={mode === "request" ? _("Request certificate") : _("Import certificate")}
               footer={<>
                   {errorName && <ModalError dialogError={errorName} dialogErrorDetail={errorMessage} />}
                   <Button variant="primary"
                       onClick={onRequest}>
                       {mode === "request" ? _("Request") : _("Import")}
                   </Button>
                   <Button variant="link" className="btn-cancel" onClick={onClose}>
                       {_("Cancel")}
                   </Button>
               </>}>
            {body}
        </Modal>
    );
}
Example #15
Source File: requestCertificate.jsx    From cockpit-certificates with GNU Lesser General Public License v2.1 4 votes vote down vote up
ResubmitCertificateModal = ({ onClose, cas, addAlert, cert, certPath, mode }) => {
    const [ca, setCa] = useState(getCAName(cas, cert));
    const [subjectName, setSubjectName] = useState(cert.subject && cert.subject.v);
    const [dnsName, _setDnsName] = useState(cert.hostname && cert.hostname.v.join(','));
    const [principalName, setPricipalName] = useState(cert.principal && cert.principal.v.join(','));
    const [errorName, setErrorName] = useState("");
    const [errorMessage, setErrorMessage] = useState("");

    const setDnsName = (value) => {
        let newValue = value.replace(/\s/g, ',');
        while (newValue.includes(",,"))
            newValue = value.replace(",,", ',');

        _setDnsName(newValue);
    };

    const onResubmit = () => {
        const casKeys = Object.keys(cas);
        let caPath;
        casKeys.forEach(key => {
            if (cas[key].nickname.v === ca)
                caPath = key;
        });

        let subjectNameParam = subjectName;
        if (subjectNameParam && !subjectNameParam.includes("="))
            subjectNameParam = "CN=" + subjectNameParam;
        let dnsNameParam;
        if (dnsName) {
            dnsNameParam = dnsName.split(',');
            dnsNameParam = dnsNameParam.filter(Boolean); // Removes empty string entries
        }

        const parameter = { ca: cockpit.variant("s", caPath) };
        parameter["template-subject"] = cockpit.variant("s", subjectNameParam || "");
        parameter["template-principal"] = cockpit.variant("as", [principalName || ""]);
        parameter["template-hostname"] = cockpit.variant("as", dnsNameParam || [""]);

        modifyRequest(certPath, parameter)
                .then(() => resubmitRequest(certPath))
                .then(onClose)
                .catch(error => {
                    setErrorName(error.name);
                    setErrorMessage(error.message);
                });
    };

    const body = (
        <Form isHorizontal>
            {cert["cert-storage"].v === "NSSDB" && <>
                <FormGroup label={_("Database path")} hasNoPaddingTop>
                    <span id="database-path-row">{ cert["cert-database"].v }</span>
                </FormGroup>
                <FormGroup label={_("Nickname")} hasNoPaddingTop>
                    <span id="nickname-row">{ cert["cert-nickname"].v }</span>
                </FormGroup>
            </>}

            {cert["cert-storage"].v === "FILE" && <>
                <FormGroup label={_("Certificate file")} hasNoPaddingTop>
                    <span id="cert-file-row">{ cert["cert-file"].v }</span>
                </FormGroup>
                <FormGroup label={_("Key file")} hasNoPaddingTop>
                    <span id="key-file-row">{ cert["key-file"].v }</span>
                </FormGroup>
            </>}

            <CAsRow ca={ca} setCa={setCa} cas={Object.values(cas)} />

            <SubjectNameRow subjectName={subjectName} setSubjectName={setSubjectName} />
            <DNSNameRow dnsName={dnsName} setDnsName={setDnsName} />
            <PrincipalNameRow principalName={principalName} setPricipalName={setPricipalName} />
        </Form>
    );

    return (
        <Modal id="resubmit-certificate-dialog"
               position="top" variant="medium"
               onClose={onClose}
               isOpen
               title={_("Resubmit Certificate")}
               footer={<>
                   {errorName && <ModalError dialogError={errorName} dialogErrorDetail={errorMessage} />}
                   <Button variant="primary" onClick={onResubmit}>
                       {_("Resubmit")}
                   </Button>
                   <Button variant="link" className="btn-cancel" onClick={onClose}>
                       {_("Cancel")}
                   </Button>
               </>}>
            {body}
        </Modal>
    );
}
Example #16
Source File: certificateActions.jsx    From cockpit-certificates with GNU Lesser General Public License v2.1 4 votes vote down vote up
RemoveModal = ({ onClose, certs, cert, certPath, addAlert, appOnValueChanged, idPrefix }) => {
    const [deleteFiles, setDeleteFiles] = useState(false);

    const onRemoveResponse = () => {
        delete certs[certPath];

        appOnValueChanged("certs, certs");
        onClose();
    };

    const onRemove = () => {
        if (deleteFiles) {
            cockpit.file(cert["key-file"].v, { superuser: "try" }).replace(null) // delete key file
                    .then(() => cockpit.file(cert["cert-file"].v, { superuser: "try" }).replace(null)) // delete cert file
                    .then(() => removeRequest(certPath))
                    // There is no dbus signal for cert removal, so we have to update UI manually
                    .then(() => onRemoveResponse())
                    .catch(error => {
                        addAlert(_("Error: ") + (error.name || error.problem), error.message);
                        onClose();
                    });
        } else {
            removeRequest(certPath)
                    // There is no dbus signal for cert removal, so we have to update UI manually
                    .then(() => onRemoveResponse())
                    .catch(error => {
                        addAlert(_("Error: ") + error.name, error.message);
                        onClose();
                    });
        }
    };

    const title = _("Remove certificate: ") + (cert["cert-storage"].v === "FILE" ? cert.nickname.v : cert["cert-nickname"].v);

    const fileCertBody = (
        <Form isHorizontal>
            <FormGroup label={_("Certificate file")} hasNoPaddingTop>
                <samp id={idPrefix + "cert-file"}>
                    {cert["cert-file"].v}
                </samp>
            </FormGroup>

            <FormGroup label={_("Key file")}>
                <samp id={idPrefix + "key-file"} hasNoPaddingTop>
                    {cert["key-file"].v}
                </samp>
            </FormGroup>
        </Form>
    );

    const nssdbCertBody = (
        <Form isHorizontal>
            <FormGroup label={_("NSSDB path")} hasNoPaddingTop>
                <samp id={idPrefix + "cert-database"}>
                    {cert["cert-database"].v}
                </samp>
            </FormGroup>

            <FormGroup label={_("Nickname")} hasNoPaddingTop>
                <samp id={idPrefix + "cert-nickname"}>
                    {cert["cert-nickname"].v}
                </samp>
            </FormGroup>
        </Form>
    );

    const body = (<>
        { cert["cert-storage"].v === "FILE" ? fileCertBody : nssdbCertBody }
        { cert["key-file"] && cert["cert-file"] && cert["key-file"].v && cert["cert-file"].v && (
            <Checkbox id={idPrefix + "-delete-files"}
                      className="checkbox-delete-files"
                      isChecked={deleteFiles}
                      label={_("Also delete certificate and key files")}
                      onChange={e => setDeleteFiles(!deleteFiles)} />
        )}
    </>);

    return (
        <Modal id={idPrefix + "-remove-dialog"}
               position="top" variant="medium"
               onClose={onClose}
               isOpen
               title={title}
               footer={<>
                   <Button variant="danger" onClick={onRemove}>
                       { deleteFiles ? _("Remove and delete") : _("Remove") }
                   </Button>
                   <Button variant="link" className="btn-cancel" onClick={onClose}>
                       {_("Cancel")}
                   </Button>
               </>}>
            {body}
        </Modal>
    );
}
Example #17
Source File: ActivationKeyForm.js    From sed-frontend with Apache License 2.0 4 votes vote down vote up
ActivationKeyForm = (props) => {
  const { handleModalToggle, submitForm, isSuccess, isError, activationKey } =
    props;
  const { addSuccessNotification, addErrorNotification } = useNotifications();
  const { isLoading, error, data } = useSystemPurposeAttributes();
  const [name, setName] = useState('');
  const [role, setRole] = useState('');
  const [serviceLevel, setServiceLevel] = useState('');
  const [usage, setUsage] = useState('');
  const [validated, setValidated] = useState('default');
  const nameRegex = '^[a-zA-Z0-9-_]*$';
  const validationText =
    'Provide a name to be used when registering the activation key. Your activation key name must be unique, may contain only numbers, letters, underscores, and hyphens, and less than 256 characters.';

  const handleSubmit = (event) => {
    event.preventDefault();
    if (validated === 'success' || activationKey) {
      submitForm(name, role, serviceLevel, usage);
    } else {
      setValidated('error');
    }
  };

  const validateName = (value) => {
    if (value.length === 0 || value.length > 255) {
      setValidated('error');
    } else if (!value.match(nameRegex)) {
      setValidated('error');
    } else {
      setValidated('success');
      setName(value);
    }
  };

  useEffect(() => {
    if (activationKey) {
      setRole(activationKey.role);
      setUsage(activationKey.usage);
      setServiceLevel(activationKey.serviceLevel);
    }
  }, [activationKey]);

  const createButtonDisabled = () => {
    if (activationKey) {
      return (
        activationKey.role === role &&
        activationKey.serviceLevel === serviceLevel &&
        activationKey.usage === usage
      );
    } else {
      return (
        validated === 'error' || name.length === 0 || !name.match(nameRegex)
      );
    }
  };

  if (isSuccess) {
    const successMessage = activationKey
      ? `Activation key ${activationKey.name} updated successfully.`
      : 'Activation key created successfully.';
    addSuccessNotification(successMessage, {
      timeout: false,
    });
    handleModalToggle();
  } else if (isError) {
    const errorMessage = activationKey
      ? `Error updating activation key ${activationKey.name}.`
      : 'Activation Key was not created, please try again.';
    addErrorNotification(errorMessage, {
      timeout: 8000,
    });
    handleModalToggle();
  }

  return (
    <Form id="activation-key-form" onSubmit={handleSubmit}>
      {!activationKey && (
        <FormGroup label="Name" isRequired helperText={validationText}>
          <TextInput
            id="activation-key-name"
            label="Name"
            isRequired
            type="text"
            validated={validated}
            onChange={validateName}
            name="name"
          />
        </FormGroup>
      )}
      {activationKey && (
        <FormGroup label="Name">
          {' '}
          <TextContent>{activationKey.name}</TextContent>
        </FormGroup>
      )}
      {!isLoading && !error && (
        <ActivationKeysFormSelect
          data={data.roles}
          value={role}
          onSelect={setRole}
          label="Role"
          name="role"
          placeholderValue="Select role"
          disableDefaultValues={activationKey ? true : false}
          popover={
            <Popover
              bodyContent={
                <TextContent>
                  <Text component={TextVariants.p}>
                    Role is used to categorize systems by the workload on the
                    system
                  </Text>
                  <Text component={TextVariants.p}>
                    Subscription Watch can help you filter and report by these
                    items.
                  </Text>
                  <Text component={TextVariants.p}>
                    Only roles available to your account are shown.
                  </Text>
                </TextContent>
              }
            >
              <HelpIcon />
            </Popover>
          }
          helperText="Select the required role from the list. The list only contains roles available to the activation key."
        />
      )}
      {!isLoading && !error && (
        <ActivationKeysFormSelect
          data={data.serviceLevel}
          value={serviceLevel}
          onSelect={setServiceLevel}
          label="Service Level Agreement (SLA)"
          name="serviceLevel"
          placeholderValue="Select a service level agreement"
          disableDefaultValues={activationKey ? true : false}
          popover={
            <Popover
              bodyContent={
                <TextContent>
                  <Text component={TextVariants.p}>
                    Service Level Agreement (SLA) determines the level of
                    support for systems registered with this activation key.
                  </Text>
                </TextContent>
              }
            >
              <HelpIcon />
            </Popover>
          }
          helperText="Select the required service level from the list. The list only contains service levels available to the activation key."
        />
      )}
      {!isLoading && !error && (
        <ActivationKeysFormSelect
          data={data.usage}
          value={usage}
          onSelect={setUsage}
          label="Usage"
          name="usage"
          placeholderValue="Select usage"
          disableDefaultValues={activationKey ? true : false}
          popover={
            <Popover
              bodyContent={
                <TextContent>
                  <Text component={TextVariants.p}>
                    Usage is used to categorize systems by how they are meant to
                    be used, and therefore supported.
                  </Text>
                  <Text component={TextVariants.p}>
                    Subscription Watch can help you filter and report by these
                    items.
                  </Text>
                </TextContent>
              }
            >
              <HelpIcon />
            </Popover>
          }
          helperText="Select the required usage from the list. The list only contains usages available to the activation key."
        />
      )}
      <ActionGroup>
        <Button
          key="create"
          id="submit-activation-key-button"
          variant="primary"
          type="submit"
          isDisabled={createButtonDisabled()}
          data-testid="activation-key-submit-button"
        >
          {activationKey ? 'Save changes' : 'Create'}
        </Button>

        <Button
          key="cancel"
          id="cancel-activation-key-button"
          variant="link"
          onClick={handleModalToggle}
        >
          Cancel
        </Button>
      </ActionGroup>
    </Form>
  );
}
Example #18
Source File: DisableRule.js    From ocp-advisor-frontend with Apache License 2.0 4 votes vote down vote up
DisableRule = ({
  isModalOpen,
  handleModalToggle,
  rule,
  afterFn,
  host,
  hosts,
}) => {
  const intl = useIntl();
  const [justification, setJustificaton] = useState('');
  const [singleHost, setSingleHost] = useState(!!host);
  const [multipleHosts, setMultipleHosts] = useState(hosts.length > 0);
  const [setAck] = useSetAckMutation();
  const dispatch = useDispatch();
  const notify = (data) => dispatch(addNotification(data));

  const bulkHostActions = async () => {
    // disable for a group of hosts (clusters)
    try {
      const requests = hosts.map((h) =>
        disableRuleForCluster({
          uuid: h.id,
          recId: rule.rule_id,
          justification,
        })
      );
      await Promise.all(requests);
      notify({
        variant: 'success',
        dismissable: true,
        timeout: true,
        title: intl.formatMessage(messages.recSuccessfullyDisabledForCluster),
      });
      afterFn && afterFn();
    } catch (error) {
      notify({
        variant: 'danger',
        dismissable: true,
        title: intl.formatMessage(messages.error),
        description: `${error}`,
      });
    }
  };

  const disableRule = async () => {
    try {
      if (singleHost) {
        // disable the rec for this single cluster
        await disableRuleForCluster({
          uuid: host,
          recId: rule.rule_id,
          justification,
        });
        notify({
          variant: 'success',
          timeout: true,
          dismissable: true,
          title: intl.formatMessage(messages.recSuccessfullyDisabledForCluster),
        });
      } else if (multipleHosts) {
        bulkHostActions();
      } else {
        // disable the whole rec
        await setAck({
          rule_id: rule.rule_id,
          justification,
        }).unwrap();
        notify({
          variant: 'success',
          timeout: true,
          dismissable: true,
          title: intl.formatMessage(messages.recSuccessfullyDisabled),
        });
      }
      setJustificaton('');
      afterFn && afterFn();
    } catch (error) {
      notify({
        variant: 'danger',
        dismissable: true,
        title: intl.formatMessage(messages.error),
        description: `${error}`,
      });
    }

    handleModalToggle(false);
  };

  return (
    <Modal
      variant="small"
      title={intl.formatMessage(messages.disableRule)}
      isOpen={isModalOpen}
      onClose={() => {
        handleModalToggle();
        setJustificaton('');
      }}
      actions={[
        <Button
          key="confirm"
          variant="primary"
          onClick={() => disableRule()}
          ouiaId="confirm"
        >
          {intl.formatMessage(messages.save)}
        </Button>,
        <Button
          key="cancel"
          variant="link"
          onClick={() => {
            handleModalToggle(false);
            setJustificaton('');
          }}
          ouiaId="cancel"
        >
          {intl.formatMessage(messages.cancel)}
        </Button>,
      ]}
      ouiaId="recommendation-disable"
    >
      {intl.formatMessage(messages.disableRuleBody)}
      <Form>
        <FormGroup fieldId="blank-form" />
        {(host || hosts.length > 0) && (
          <FormGroup fieldId="disable-rule-one-system">
            <Checkbox
              isChecked={singleHost || multipleHosts}
              onChange={() => {
                host
                  ? setSingleHost(!singleHost)
                  : setMultipleHosts(!multipleHosts);
              }}
              label={
                host
                  ? intl.formatMessage(messages.disableRuleSingleCluster)
                  : intl.formatMessage(messages.disableRuleForClusters)
              }
              id="disable-rule-one-system"
              name="disable-rule-one-system"
              ouiaId="disable-recommendation-one-cluster"
            />
          </FormGroup>
        )}
        <FormGroup
          label={intl.formatMessage(messages.justificationNote)}
          fieldId="disable-rule-justification"
        >
          <TextInput
            type="text"
            id="disable-rule-justification"
            aria-describedby="disable-rule-justification"
            value={justification}
            onChange={(text) => setJustificaton(text)}
            onKeyDown={(e) =>
              e.key === 'Enter' && (e.preventDefault(), disableRule())
            }
          />
        </FormGroup>
      </Form>
    </Modal>
  );
}
Example #19
Source File: Details.js    From content-preview with Apache License 2.0 4 votes vote down vote up
Details = ({
    match,
    fetchContentDetails,
    details,
    fetchContentDetailsHits,
    contentDetailsHits
}) => {
    const [selectedListItem, setSelectedListItem] = useState(0);
    const capitalize = (string) => string[0].toUpperCase() + string.substring(1);
    const [expanded, setExpanded] = useState(true);
    const pyFilter = (data) => {
        const keysToInclude = Object.keys(data).filter(
            (key) => !key.includes('__')
        );
        const arrayObj = keysToInclude.map((key) => ({ [key]: data[key] }));

        return Object.assign({}, ...arrayObj);
    };

    const selectedPyData =
    selectedListItem >= 1 && pyFilter(contentDetailsHits[selectedListItem - 1]);
    const detailHref = `https://access.redhat.com/node/${details.node_id}`;
    const [freeStyle, setFreeStyle] = useState('');
    const [freeStyleValidated, setFreeStyleValidated] = useState('default');
    const [validFreeStyle, setValidFreeStyle] = useState('');
    const [helperText, setHelperText] = useState('Please enter valid JSON');
    const [kbaDetailsData, setLbaDetailsData] = useState({});
    const [kbaLoading, setKbaLoading] = useState(true);

    const freeStyleChange = (input) => {
        let isValid;
        const parser = (input) => {
            try {
                return JSON.parse(input);
            } catch (error) {
                return false;
            }
        };

        if (input.length > 0) {
            const validInput = parser(input);
            if (validInput) {
                isValid = 'success';
                setValidFreeStyle(validInput);
                setHelperText('Valid JSON! ?');
            } else {
                isValid = 'error';
                setValidFreeStyle('');
            }
        } else {
            isValid = 'default';
            setValidFreeStyle('');
            setHelperText('Please enter valid JSON');
        }

        setFreeStyleValidated(isValid);
        setFreeStyle(input);
    };

    const severityLabelColor = (severity) =>
        severity === 'ERROR'
            ? 'red'
            : severity === 'WARN'
                ? 'orange'
                : severity === 'INFO'
                    ? 'purple'
                    : 'blue';

    const fetchKbaDetails = async (kbaId) => {
        try {
            const kbaDetailsFetch = (
                await API.get(
                    `https://access.redhat.com/hydra/rest/search/kcs?q=id:(${kbaId})&fl=view_uri,id,publishedTitle&rows=1&redhat_client=$ADVISOR`,
                    {},
                    { credentials: 'include' }
                )
            ).data.response.docs;
            setLbaDetailsData(kbaDetailsFetch[0]);
            setKbaLoading(false);
        } catch (error) {
            console.error(error, 'KBA fetch failed.');
        }
    };

    const ruleDescription = (data, isGeneric) =>
        typeof data === 'string' &&
    Boolean(data) && (
            <span className={isGeneric && 'genericOverride'}>
                <Markdown rehypePlugins={[rehypeRaw, rehypeSanitize]}>{data}</Markdown>
            </span>
        );

    useEffect(() => {
        const detailName = { name: match.params.recDetail };
        fetchContentDetails(detailName);
        fetchContentDetailsHits(detailName);
        fetchKbaDetails(details.node_id);
    }, [
        fetchContentDetails,
        match.params.recDetail,
        fetchContentDetailsHits,
        details.node_id
    ]);

    return (
        <Page
            breadcrumb={
                <Breadcrumb>
                    <BreadcrumbItem>
                        <Link to="/preview">Content Preview</Link>
                    </BreadcrumbItem>
                    <BreadcrumbHeading to="#">{`${match.params.recDetail}`}</BreadcrumbHeading>
                </Breadcrumb>
            }
        >
            <PageHeader>
                <Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
                    <PageHeaderTitle
                        title={
                            <>
                                {details.rule_id || 'loading...'}{' '}
                                {details.status !== undefined && (
                                    <Label color={details.status === 'active' ? 'green' : 'red'}>
                                        {capitalize(details.status)}
                                    </Label>
                                )}{' '}
                            </>
                        }
                    />
                    <Toolbar>
                        <HostSelector />
                    </Toolbar>
                </Flex>
            </PageHeader>
            <PageSection>
                <Grid hasGutter>
                    <GridItem span={6}>
                        <Stack hasGutter>
                            <Card>
                                <CardBody>
                                    <ExpandableSection
                                        toggleText={details.description}
                                        onToggle={() => setExpanded(!expanded)}
                                        isExpanded={expanded}
                                    >
                                        <Stack hasGutter>
                                            <StackItem>
                                                <p>
                                                    {`Publish Date: ${details.publish_date} | `}
                                                    {details.node_id ? (
                                                        <a href={detailHref}>{detailHref}</a>
                                                    ) : (
                                                        <Label variant="outline" color="gray">
                                                            No node_id present
                                                        </Label>
                                                    )}
                                                </p>
                                                {(details.reboot_required ||
                                                    details.category ||
                                                    details.severity) && (
                                                    <LabelGroup>
                                                        {details.reboot_required && (
                                                            <Label variant="outline" color="gray">
                                                                Reboot required
                                                            </Label>
                                                        )}
                                                        {details.category && (
                                                            <Label variant="outline" color="gray">
                                                                {details.category}
                                                            </Label>
                                                        )}
                                                        {details.severity && (
                                                            <Label
                                                                variant="outline"
                                                                color={severityLabelColor(details.severity)}
                                                            >
                                                                {details.severity}
                                                            </Label>
                                                        )}
                                                    </LabelGroup>
                                                )}
                                            </StackItem>
                                            <StackItem>
                                                <Stack hasGutter>
                                                    <StackItem>
                                                        <strong>Name:</strong>
                                                        {ruleDescription(details.name)}
                                                    </StackItem>
                                                    <StackItem>
                                                        <strong>Summary:</strong>
                                                        {ruleDescription(details.summary)}
                                                    </StackItem>
                                                    <StackItem>
                                                        <strong>Generic:</strong>
                                                        {ruleDescription(details.generic, true)}
                                                    </StackItem>
                                                </Stack>
                                            </StackItem>
                                            <StackItem>
                                                <Form>
                                                    <FormGroup
                                                        label="Free Style JSON input:"
                                                        type="string"
                                                        helperText={helperText}
                                                        helperTextInvalid="Not valid JSON"
                                                        fieldId="selection"
                                                        validated={freeStyleValidated}
                                                    >
                                                        <TextArea
                                                            value={freeStyle}
                                                            onChange={freeStyleChange}
                                                            isRequired
                                                            validated={freeStyleValidated}
                                                            aria-label="free style JSON input"
                                                        />
                                                    </FormGroup>
                                                </Form>
                                            </StackItem>
                                        </Stack>
                                    </ExpandableSection>
                                </CardBody>
                            </Card>
                            <DataList
                                className="pyDataList"
                                aria-label="selectable data list example"
                                selectedDataListItemId={selectedListItem}
                                onSelectDataListItem={(id) =>
                                    id !== selectedListItem
                                        ? setSelectedListItem(id)
                                        : setSelectedListItem(0)
                                }
                            >
                                {contentDetailsHits.map((item, key) => (
                                    <DataListItem
                                        aria-labelledby="selectable-action-item1"
                                        key={key + 1}
                                        id={key + 1}
                                    >
                                        <DataListItemRow className="overFlow">
                                            <DataListItemCells
                                                dataListCells={[
                                                    <DataListCell key="primary content">
                                                        <Split hasGutter>
                                                            <SplitItem>
                                                                <b>{item.__name}</b>
                                                            </SplitItem>
                                                            <SplitItem>
                                                                <Label color="blue">{item.__source}</Label>
                                                            </SplitItem>
                                                        </Split>
                                                        <h5>{item.__date}</h5>
                                                        <pre>{JSON.stringify(pyFilter(item), null, 2)}</pre>
                                                    </DataListCell>
                                                ]}
                                            />
                                        </DataListItemRow>
                                    </DataListItem>
                                ))}
                            </DataList>
                        </Stack>
                    </GridItem>
                    <GridItem span={6}>
                        <ReportDetails
                            report={{
                                ...details,
                                rule: details,
                                ...(selectedPyData && { details: selectedPyData }),
                                ...(validFreeStyle && { details: validFreeStyle }),
                                resolution: details.resolution
                            }}
                            kbaDetail={kbaDetailsData}
                            kbaLoading={kbaLoading}
                        />
                    </GridItem>
                </Grid>
            </PageSection>
        </Page>
    );
}