@patternfly/react-core#TextVariants JavaScript Examples

The following examples show how to use @patternfly/react-core#TextVariants. 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: LogNestedtable.js    From sed-frontend with Apache License 2.0 6 votes vote down vote up
LogNestedTable = ({ services, isInsights }) => {
  return (
    <Stack>
      <StackItem>
        <TextContent>
          <Text component={TextVariants.h3}>State pushed to systems</Text>
        </TextContent>
      </StackItem>
      <Table
        aria-label="Active services Table"
        className="sed-c-services__table"
        cells={columns}
        rows={[
          {
            noPadding: true,
            cells: [
              'Connected to Red Hat Insighsts',
              isInsights ? 'on' : 'off',
            ],
          },
          ...Object.entries(services).map(([key, value]) => [
            rowMapper[key],
            value === 'enabled' ? 'on' : 'off',
          ]),
        ]}
        variant="compact"
      >
        <TableHeader />
        <TableBody />
      </Table>
    </Stack>
  );
}
Example #2
Source File: Samples.js    From operate-first.github.io-old with GNU General Public License v3.0 6 votes vote down vote up
Samples = () => (
  <div className="samples">
    <TextContent>
      <Text component={TextVariants.h1}>Hello World</Text>
      <Text component={TextVariants.h2}>Second level</Text>
      <Text component={TextVariants.h3}>Third level</Text>
      <Text component={TextVariants.h4}>Fourth level</Text>
      <Text component={TextVariants.h5}>Fifth level</Text>
      <Text component={TextVariants.h6}>Sixth level</Text>
    </TextContent>
  </div>
)
Example #3
Source File: RoutingTab.js    From cockpit-wicked with GNU General Public License v2.0 6 votes vote down vote up
RoutingTab = () => {
    const dispatch = useNetworkDispatch();
    const { routes } = useNetworkState();

    useEffect(() => { fetchRoutes(dispatch) }, [dispatch]);

    const routesList = routes ? Object.values(routes) : [];

    const routesNotFound = () => (
        <EmptyState>
            <EmptyStateIcon icon={InfoCircleIcon} />
            <Title headingLevel="h4" size="lg">
                {_('No user-defined routes were found.')}
            </Title>
            <AddRoute />
        </EmptyState>
    );

    if (routesList.length === 0) {
        return routesNotFound();
    }

    return (
        <Card>
            <CardHeader>
                <CardActions>
                    <AddRoute />
                </CardActions>
                <CardTitle>
                    <Text component={TextVariants.h2}>{_("User-defined Routes")}</Text>
                </CardTitle>
            </CardHeader>
            <CardBody>
                <RoutesList routes={routesList} />
            </CardBody>
        </Card>
    );
}
Example #4
Source File: SignatureDescription.js    From malware-detection-frontend with Apache License 2.0 6 votes vote down vote up
SignatureDesctiprion = ({ signature }) => {
    const intl = useIntl();
    const [isCodeEditorEnabled] = useState(false);
    return (
        <Grid hasGutter>
            {isCodeEditorEnabled && (
                <GridItem span={6}>
                    <CodeEditor code={signature.rawRule} isReadOnly />
                </GridItem>
            )}
            <GridItem span={isCodeEditorEnabled && 6 || 12}> <Text className='ins-l-sigtable--title' component={TextVariants.h6}>
                {intl.formatMessage(messages.description)}
            </Text>{signature.metadata.description}
            </GridItem>
        </Grid>
    );
}
Example #5
Source File: SSHInputField.js    From edge-frontend with Apache License 2.0 6 votes vote down vote up
SSHInputField = (props) => {
  const { input: sshKeyInput, meta } = useFieldApi({
    name: 'credentials',
    ...props,
  });
  return (
    <FormGroup>
      <FormGroup
        label="SSH key"
        helperTextInvalid={meta.error}
        validated={meta.error && meta.touched ? 'error' : 'default'}
        isRequired
      >
        <TextArea
          className="pf-u-h-25vh"
          id="credentials"
          placeholder="Paste your public SSH key"
          {...sshKeyInput}
        />
      </FormGroup>
      <Fragment>
        <Text component={TextVariants.small}>
          <Text
            target="_blank"
            href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/assembly_using-secure-communications-between-two-systems-with-openssh_configuring-basic-system-settings#generating-ssh-key-pairs_assembly_using-secure-communications-between-two-systems-with-openssh"
            isVisitedLink
            component={TextVariants.a}
          >
            Learn more about SSH keys
            <ExternalLinkAltIcon className="pf-u-ml-sm" />
          </Text>
        </Text>
      </Fragment>
    </FormGroup>
  );
}
Example #6
Source File: ReviewSection.js    From edge-frontend with Apache License 2.0 6 votes vote down vote up
ReviewSection = ({ title, data, testid }) => {
  return (
    <Grid className="pf-u-pb-xl" data-testid={testid} hasGutter>
      <GridItem span={12}>
        <Text component={TextVariants.h2}>{title}</Text>
      </GridItem>
      {data.map(({ name, value }) => (
        <Grid key={name}>
          <GridItem span={3}>
            <TextListItem component={TextListItemVariants.dt}>
              {name}
            </TextListItem>
          </GridItem>
          <GridItem span={9}>
            <TextListItem component={TextListItemVariants.dd}>
              {value}
            </TextListItem>
          </GridItem>
        </Grid>
      ))}
    </Grid>
  );
}
Example #7
Source File: TableHeader.js    From edge-frontend with Apache License 2.0 6 votes vote down vote up
Header = () => {
  return (
    <TextContent style={{ padding: '15px', backgroundColor: 'white' }}>
      <Text component={TextVariants.h1}>Custom repositories</Text>
      <Text component={TextVariants.p}>
        Add custom repositories to build RHEL for Edge images with additional
        packages.{' '}
        {/*<Text
          style={{ display: 'inline' }}
          component={TextVariants.small}
          href="#"
        >
          <Text component={TextVariants.a} href="#">
            Learn more
            <ExternalLinkAltIcon size="sm" className="pf-u-ml-sm" />
          </Text>
        </Text>*/}
      </Text>
    </TextContent>
  );
}
Example #8
Source File: ImageOutputCheckbox.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
ImageOutputCheckbox = (props) => {
  const { getState } = useFormApi();
  const { input } = useFieldApi(props);
  const toggleCheckbox = useCallback(
    (checked, event) => {
      input.onChange(
        checked
          ? [...input.value, event.currentTarget.id]
          : input.value.filter((item) => item !== event.currentTarget.id)
      );
    },
    [input.onChange]
  );

  return (
    <FormGroup
      label="Output type"
      isHelperTextBeforeField
      hasNoPaddingTop
      isRequired
      isStack
    >
      {props.options.map(({ value, label }, index) => (
        <Fragment key={index}>
          <Checkbox
            label={label}
            id={value}
            isChecked={input.value.includes(value)}
            onChange={toggleCheckbox}
            isDisabled={value === 'rhel-edge-commit'}
          />
          <TextContent>
            {getState()?.initialValues?.isUpdate &&
            value === 'rhel-edge-installer' ? (
              <WarningInstallerHelperText />
            ) : (
              <HelperText className="pf-u-ml-lg pf-u-pb-sm">
                <HelperTextItem variant="indeterminate">
                  {outputHelperText[value]}
                </HelperTextItem>
              </HelperText>
            )}
          </TextContent>
          {value === 'rhel-edge-installer' && (
            <Fragment>
              <Text component={TextVariants.small}>
                <Text
                  target="_blank"
                  href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/composing_installing_and_managing_rhel_for_edge_images/index#edge-how-to-compose-and-deploy-a-rhel-for-edge-image_introducing-rhel-for-edge-images"
                  component={TextVariants.a}
                  isVisitedLink
                >
                  Learn more about image types.
                  <ExternalLinkAltIcon className="pf-u-ml-sm" />
                </Text>
              </Text>
            </Fragment>
          )}
        </Fragment>
      ))}
    </FormGroup>
  );
}
Example #9
Source File: DeleteActivationKeyConfirmationModal.js    From sed-frontend with Apache License 2.0 5 votes vote down vote up
DeleteActivationKeyConfirmationModal = (props) => {
  const { isOpen, handleModalToggle, name } = props;
  const { addSuccessNotification, addErrorNotification } = useNotifications();
  const { mutate, isLoading } = useDeleteActivationKey();
  const queryClient = useQueryClient();

  const deleteActivationKey = (name) => {
    mutate(name, {
      onSuccess: (_data, name) => {
        queryClient.setQueryData('activation_keys', (oldData) =>
          oldData.filter((entry) => entry.name != name)
        );
        addSuccessNotification(`Activation Key ${name} deleted`);
        handleModalToggle();
      },
      onError: () => {
        addErrorNotification('Something went wrong. Please try again');
        handleModalToggle();
      },
    });
    mutate;
  };
  const actions = [
    <Button
      key="confirm"
      variant="danger"
      onClick={() => deleteActivationKey(name)}
      data-testid="delete-activation-key-confirmation-modal-confirm-button"
    >
      Delete
    </Button>,
    <Button key="cancel" variant="link" onClick={handleModalToggle}>
      Cancel
    </Button>,
  ];

  const title = (
    <>
      <TextContent>
        <Text component={TextVariants.h2}>
          <ExclamationTriangleIcon size="md" color="#F0AB00" /> Delete
          Activation Key?
        </Text>
      </TextContent>
    </>
  );
  const content = () => {
    if (isLoading) {
      return <Loading />;
    } else {
      return (
        <TextContent>
          <Text component={TextVariants.p}>
            <b>{name}</b> will no longer be available for use. This operation
            cannot be undone.
          </Text>
        </TextContent>
      );
    }
  };

  return (
    <Modal
      title={title}
      isOpen={isOpen}
      onClose={handleModalToggle}
      variant={ModalVariant.small}
      actions={actions}
    >
      {content()}
    </Modal>
  );
}
Example #10
Source File: YourInformation.js    From user-preferences-frontend with Apache License 2.0 5 votes vote down vote up
YourInformation = () => {
  const env = insights.chrome.getEnvironment();
  const prefix = insights.chrome.isProd ? '' : `${env === 'ci' ? 'qa' : env}.`;

  const { isLoaded, currentUser } = useCurrentUser();

  return (
    <Card className="pref-email__info" ouiaId="user-pref-info-card">
      <CardHeader>
        <TextContent>
          <Text component={TextVariants.h2}>Your information</Text>
        </TextContent>
      </CardHeader>
      <CardBody>
        <DataList>
          <DataListItem>
            <DataListItemRow>
              <DataListItemCells
                className="pref-u-condensed"
                dataListCells={[
                  <DataListCell
                    isFilled={false}
                    className="pref-c-title pref-u-bold pref-u-condensed"
                    key="email-title"
                  >
                    Email address
                  </DataListCell>,
                  <DataListCell
                    isFilled
                    key="email-value"
                    className="pref-email__info-user-email pref-u-condensed"
                  >
                    {isLoaded ? (
                      <Fragment>
                        <span className="pf-u-mr-md">{currentUser.email}</span>
                        <a
                          rel="noopener noreferrer"
                          target="_blank"
                          href={`https://www.${prefix}redhat.com/wapps/ugc/protected/emailChange.html`}
                        >
                          Not correct?
                        </a>
                      </Fragment>
                    ) : (
                      <Skeleton size="lg" />
                    )}
                  </DataListCell>,
                ]}
              />
            </DataListItemRow>
          </DataListItem>
        </DataList>
      </CardBody>
    </Card>
  );
}
Example #11
Source File: InterfacesTab.js    From cockpit-wicked with GNU General Public License v2.0 5 votes vote down vote up
InterfacesTab = () => {
    const dispatch = useNetworkDispatch();
    const { interfaces, connections } = useNetworkState();

    useEffect(() => {
        fetchConnections(dispatch);
        fetchInterfaces(dispatch);
        listenToInterfacesChanges(dispatch);
    }, [dispatch]);

    const managedInterfacesList = interfaces ? Object.values(interfaces).filter((i) => i.managed || !i.virtual) : [];
    const unmanagedInterfacesList = interfaces ? Object.values(interfaces).filter((i) => !managedInterfacesList.includes(i)) : [];
    const connectionsList = connections ? Object.values(connections) : [];

    const renderUnmanagedInterfaces = () => {
        if (unmanagedInterfacesList.length === 0) return;

        return (
            <Card>
                <CardHeader>
                    <CardActions />
                    <CardTitle>
                        <Text component={TextVariants.h2}>{_("Unmanaged Interfaces")}</Text>
                    </CardTitle>
                </CardHeader>
                <CardBody>
                    <UnmanagedInterfacesList interfaces={unmanagedInterfacesList} />
                </CardBody>
            </Card>
        );
    };

    return (
        <>
            <Card>
                <CardHeader>
                    <CardActions>
                        <AddConnectionMenu />
                    </CardActions>
                    <CardTitle>
                        <Text component={TextVariants.h2}>{_("Interfaces")}</Text>
                    </CardTitle>
                </CardHeader>
                <CardBody>
                    <InterfacesList interfaces={managedInterfacesList} connections={connectionsList} />
                </CardBody>
            </Card>
            { renderUnmanagedInterfaces() }
        </>
    );
}
Example #12
Source File: ModalConfirm.js    From cockpit-wicked with GNU General Public License v2.0 5 votes vote down vote up
ModalConfirm = ({
    caption,
    title,
    isOpen = false,
    onConfirm,
    onConfirmDisable = false,
    onConfirmLabel = _("Confirm"),
    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="confirm" variant="danger" onClick={onConfirm}>
                        {onConfirmLabel}
                    </Button>

                    <Button key="cancel" variant="link" onClick={onCancel}>
                        {onCancelLabel}
                    </Button>
                </ActionGroup>
            }
        >
            {children}
        </Modal>
    );
}
Example #13
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 #14
Source File: Footer.js    From operate-first.github.io-old with GNU General Public License v3.0 5 votes vote down vote up
Footer = () => (
  <footer key="footer-2" className="ws-org-pfsite-l-footer-dark pf-m-no-fill">
    <Grid className="pf-u-py-xl-on-sm pf-u-py-0-on-md pf-u-align-items-center">
      <GridItem md={2} mdOffset={1}>
        <Text
          component={TextVariants.a}
          href="//www.redhat.com"
          target="top"
          aria-label="Visit Red Hat.com"
        >
          <img src={redhatLogo} alt="Red Hat logo" width="100px" />
        </Text>
      </GridItem>
      <GridItem md={3}>
        <span className="ws-org-pfsite-site-copyright">Operate First is a Red Hat Initiative.</span>
      </GridItem>
      <GridItem md={6}>
        <Text
          component={TextVariants.a}
          href="//www.redhat.com/en/about/privacy-policy"
          target="top"
          aria-label="Privacy statement"
        >
          Privacy statement
        </Text>
        <Text
          component={TextVariants.a}
          href="//www.redhat.com/en/about/terms-use"
          target="top"
          aria-label="Terms of use"
        >
          Terms of use
        </Text>
        <Text
          component={TextVariants.a}
          href="//www.redhat.com/en/about/all-policies-guidelines"
          target="top"
          aria-label="All policies and guidelines"
        >
          All policies and guidelines
        </Text>
        <Text
          component={TextVariants.a}
          href="//thenounproject.com/exgoya/"
          target="top"
          aria-label="Operate First Logo Creator"
        >
          Creator of Operate-First Logo
        </Text>
        <Text
          component={TextVariants.a}
          href="//www.openstack.org/legal/community-code-of-conduct/"
          target="top"
          aria-label="Code of Conduct"
        >
          Code of Conduct
        </Text>
      </GridItem>
    </Grid>
  </footer>
)
Example #15
Source File: WizardRepositoryTable.js    From edge-frontend with Apache License 2.0 4 votes vote down vote up
WizardRepositoryTable = ({ ...props }) => {
  const { change, getState } = useFormApi();
  const { input } = useFieldApi(props);
  const wizardState = getState()?.values?.[input.name];
  const isUpdateWizard = getState()?.values?.isUpdate;
  const imageID = getState()?.values?.imageID;

  const [selectedRepos, setSelectedRepos] = useState([]);
  const [response, fetchRepos] = useApi({
    api: ({ query }) =>
      getCustomRepositories({
        imageID: isUpdateWizard ? imageID.toString() : '',
        query,
      }),
    tableReload: true,
  });
  const { data, isLoading, hasError } = response;

  useEffect(() => {
    change(input.name, selectedRepos);
  }, [selectedRepos]);

  const getRepoIds = (checked) => {
    const checkedRepos = checked?.map((repo) => ({
      id: repo?.id,
      name: repo?.name,
      URL: repo?.URL,
    }));
    setSelectedRepos(checkedRepos);
  };

  useEffect(() => {
    change('validate-custom-repos', false);
  }, []);

  const buildRows = ({ data }) => {
    return data.map(({ ID, Name, URL }) => ({
      rowInfo: { id: ID, name: Name, URL: URL },
      cells: [
        {
          title: (
            <>
              <Text className="pf-u-mb-xs" component={TextVariants.p}>
                {Name}
              </Text>
              <Text
                component={TextVariants.a}
                href={URL}
                target="_blank"
                rel="noopener noreferrer"
              >
                {URL} <ExternalLinkAltIcon className="pf-u-ml-sm" />
              </Text>
            </>
          ),
        },
      ],
    }));
  };

  return (
    <>
      {isLoading !== true && !data?.count > 0 ? (
        <EmptyState
          icon="repository"
          title="No custom repositories available"
          body="Add custom repositories to build RHEL for Edge images with additional packages."
          primaryAction={{
            text: 'Custom repositories',
            href: paths['repositories'],
          }}
        />
      ) : (
        <GeneralTable
          apiFilterSort={true}
          isUseApi={true}
          loadTableData={fetchRepos}
          filters={filters}
          tableData={{
            count: data?.count,
            data,
            isLoading,
            hasError,
          }}
          columnNames={[{ title: 'Name', type: 'name', sort: false }]}
          rows={isLoading ? [] : buildRows(data)}
          defaultSort={{ index: 0, direction: 'desc' }}
          hasCheckbox={true}
          selectedItems={getRepoIds}
          initSelectedItems={wizardState}
        />
      )}
    </>
  );
}
Example #16
Source File: ActivationKeys.js    From sed-frontend with Apache License 2.0 4 votes vote down vote up
ActivationKeys = () => {
  const queryClient = useQueryClient();
  const user = queryClient.getQueryData('user');
  const { isLoading, error, data } = useActivationKeys();
  const [isOpen, setisOpen] = useState(false);
  const [currentKeyName, setCurrentKeyName] = useState('');

  const [isDeleteActivationKeyModalOpen, setIsDeleteActivationKeyModalOpen] =
    useState(false);
  const [isEditActivationKeyModalOpen, setIsEditActivationKeyModalOpen] =
    useState(false);
  const handleModalToggle = () => {
    setisOpen(!isOpen);
  };

  const actions = (activationKeyName) => {
    return [
      {
        title: 'Edit',
        onClick: () => handleEditActivationKeyModalToggle(activationKeyName),
      },
      {
        title: 'Delete',
        onClick: () => handleDeleteActivationKeyModalToggle(activationKeyName),
      },
    ];
  };
  let pageContent;
  if (isLoading) {
    pageContent = <Loading />;
  } else if (!isLoading && !error && !data.length) {
    pageContent = (
      <NoActivationKeysFound handleModalToggle={handleModalToggle} />
    );
  } else if (!isLoading && !error && data.length) {
    pageContent = (
      <>
        <ActionGroup>
          <CreateActivationKeyButton onClick={handleModalToggle} />
        </ActionGroup>
        <ActivationKeysTable actions={actions} />
      </>
    );
  }

  const setKeyName = (modalOpen, name) => {
    let currentName = modalOpen ? '' : name;
    setCurrentKeyName(currentName);
  };

  const handleDeleteActivationKeyModalToggle = (name) => {
    setKeyName(isDeleteActivationKeyModalOpen, name);
    setIsDeleteActivationKeyModalOpen(!isDeleteActivationKeyModalOpen);
  };

  const handleEditActivationKeyModalToggle = (name) => {
    setKeyName(isEditActivationKeyModalOpen, name);
    setIsEditActivationKeyModalOpen(!isEditActivationKeyModalOpen);
  };

  const Page = () => {
    return (
      <React.Fragment>
        <PageHeader>
          <Split hasGutter className="page-title">
            <SplitItem isFilled>
              <Flex>
                <FlexItem spacer={{ default: 'spacerSm' }}>
                  <PageHeaderTitle title="Activation Keys" />
                </FlexItem>
                <FlexItem>
                  <ActivationKeysDocsPopover orgId={user.orgId} />
                </FlexItem>
              </Flex>
            </SplitItem>
          </Split>
          <TextContent>
            <Text component={TextVariants.p}>
              Organization ID: {user.orgId}
            </Text>
          </TextContent>
        </PageHeader>
        <Main>
          <PageSection variant={PageSectionVariants.light}>
            {pageContent}
          </PageSection>
        </Main>
        <CreateActivationKeyModal
          isOpen={isOpen}
          handleModalToggle={handleModalToggle}
        />
        <EditActivationKeyModal
          isOpen={isEditActivationKeyModalOpen}
          handleModalToggle={handleEditActivationKeyModalToggle}
          activationKeyName={currentKeyName}
        />
        <DeleteActivationKeyConfirmationModal
          handleModalToggle={handleDeleteActivationKeyModalToggle}
          isOpen={isDeleteActivationKeyModalOpen}
          name={currentKeyName}
        />
      </React.Fragment>
    );
  };

  if (user.rbacPermissions.canReadActivationKeys) {
    return <Page />;
  } else {
    return <NoAccessView />;
  }
}
Example #17
Source File: UpdateImageModal.js    From edge-frontend with Apache License 2.0 4 votes vote down vote up
UpdateImageModal = ({ updateCveModal, setUpdateCveModal, setReload }) => {
  const dispatch = useDispatch();

  const { getRegistry } = useContext(RegistryContext);
  const { data } = useSelector(
    ({ imageDetailReducer }) => ({
      data: imageDetailReducer?.data || null,
    }),
    shallowEqual
  );

  useEffect(() => {
    const registered = getRegistry().register({
      imageDetailReducer,
    });
    updateCveModal?.imageId &&
      loadImageDetail(dispatch, updateCveModal?.imageId);
    return () => registered();
  }, [dispatch]);

  const handleUpdateModal = () => {
    const payload = {
      Id: data?.image?.ID,
      description: data?.image?.Description,
      name: data?.image?.Name,
      version: data?.image?.Version + 1,
      architecture: 'x86_64',
      credentials: data?.image?.Installer.SshKey,
      username: data?.image?.Installer.Username,
      imageType: data?.image?.OutputTypes,
      'selected-packages': data?.image?.Packages?.map((pack) => ({
        name: pack.Name,
      })),
      release: data?.image?.Distribution,
    };
    handleClose();
    setReload(true);
    createNewImage(dispatch, payload, (resp) => {
      dispatch({
        ...addNotification({
          variant: 'info',
          title: 'Update image',
          description: `${resp.value.Name} image was added to the queue.`,
        }),
        meta: {
          polling: {
            id: `FETCH_IMAGE_${resp.value.ID}_BUILD_STATUS`,
            fetcher: () => getEdgeImageStatus(resp.value.ID),
            condition: (resp) => {
              switch (resp.Status) {
                case 'BUILDING':
                  return [true, ''];
                case 'ERROR':
                  return [false, 'failure'];
                default:
                  return [false, 'success'];
              }
            },
            onEvent: {
              failure: [
                (dispatch) =>
                  dispatch(
                    addNotification({
                      variant: 'danger',
                      title: 'Image build failed',
                      description: `${resp.value.Name} image build is completed unsuccessfully`,
                    })
                  ),
              ],
              success: [
                (dispatch) =>
                  dispatch(
                    addNotification({
                      variant: 'success',
                      title: 'Image is ready',
                      description: `${resp.value.Name} image build is completed`,
                    })
                  ),
                (dispatch) => loadEdgeImageSets(dispatch),
              ],
            },
          },
        },
      });
      loadEdgeImageSets(dispatch);
      dispatch(
        addImageToPoll({ name: data?.image?.Name, id: data?.image?.ID })
      );
    });
  };

  const handleClose = () => {
    setUpdateCveModal((prevState) => ({ ...prevState, isOpen: false }));
  };

  return data ? (
    <Modal
      variant="medium"
      title={`Update image: ${data?.image?.Name}`}
      description="Review the information and click Create image to start the build process"
      isOpen={updateCveModal.isOpen}
      onClose={handleClose}
      //onSubmit={handleUpdateModal}
      actions={[
        <Button key="confirm" variant="primary" onClick={handleUpdateModal}>
          Create Image
        </Button>,
        <Button key="cancel" variant="link" onClick={handleClose}>
          Cancel
        </Button>,
      ]}
    >
      <TextContent>
        <TextListItem component={TextVariants.h3}>
          <Text component={'b'}>Details</Text>
        </TextListItem>
        <TextList component={TextListVariants.dl}>
          <TextListItem component={TextListItemVariants.dt}>Name</TextListItem>
          <TextListItem component={TextListItemVariants.dd}>
            {data?.image?.Name}
          </TextListItem>
          <TextListItem component={TextListItemVariants.dt}>
            Version
          </TextListItem>
          <TextListItem component={TextListItemVariants.dd}>
            {data?.image?.Version + 1}
          </TextListItem>
          <TextListItem component={TextListItemVariants.dt}>
            Description
          </TextListItem>
          <TextListItem component={TextListItemVariants.dd}>
            {data?.image?.Description}
          </TextListItem>
        </TextList>
        <TextListItem component={TextVariants.h3}>
          <Text component={'b'}>Output</Text>
        </TextListItem>
        <TextList component={TextListVariants.dl}>
          <TextListItem component={TextListItemVariants.dt}>
            Release
          </TextListItem>
          <TextListItem component={TextListItemVariants.dd}>
            {releaseMapper[data?.image?.Distribution]}
          </TextListItem>
          <TextListItem component={TextListItemVariants.dt}>
            Output type
          </TextListItem>
          <TextListItem component={TextListItemVariants.dd}>
            {imageTypeMapper[data?.image?.ImageType]}
          </TextListItem>
        </TextList>
        <TextListItem component={TextVariants.h3}>
          <Text component={'b'}>Packages</Text>
        </TextListItem>
        <TextList component={TextListVariants.dl}>
          <TextListItem component={TextListItemVariants.dt}>
            Updated
          </TextListItem>
          <TextListItem
            className="pf-u-pl-lg"
            component={TextListItemVariants.dd}
          >
            {updateCveModal?.cveCount}
          </TextListItem>
        </TextList>
      </TextContent>
    </Modal>
  ) : (
    <Backdrop>
      <Bullseye>
        <Spinner isSVG diameter="100px" />
      </Bullseye>
    </Backdrop>
  );
}
Example #18
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 #19
Source File: Email.js    From user-preferences-frontend with Apache License 2.0 4 votes vote down vote up
Email = () => {
  const dispatch = useDispatch();

  const [emailConfig, setEmailConfig] = useState({});
  const isLoaded = useLoaded(async () => {
    await insights.chrome.auth.getUser();
    register(emailPreferences);
    setEmailConfig(await calculateEmailConfig(config, dispatch));
  });

  const store = useSelector(({ emailPreferences }) => emailPreferences);

  const saveValues = async ({ unsubscribe, ...values }) => {
    const promises = Object.entries(emailConfig)
      .filter(([, { isVisible }]) => isVisible === true)
      .map(([application, { localFile, schema, url, apiName }]) => {
        if (
          !localFile &&
          !schema &&
          store?.[application]?.schema &&
          Object.keys(store?.[application]?.schema).length > 0
        ) {
          const action = saveEmailValues({ application, values, url, apiName });
          dispatch(action);

          return {
            promise: action.payload,
            meta: action.meta,
          };
        }
      })
      .filter(Boolean);

    const { success, error } = await distributeSuccessError(promises);
    dispatchMessages(dispatch, success, error);
  };

  const calculateSection = (key, schema) => {
    return getSection(key, schema, store?.[key], (isVisible) => {
      const { ...config } = emailConfig;
      if (isVisible === false) {
        delete config[key];
      } else {
        config[key] = {
          ...config[key],
          isVisible,
        };
      }

      setEmailConfig(config);
    });
  };

  return (
    <React.Fragment>
      <PageHeader>
        <PageHeaderTitle title="Email preferences" />
      </PageHeader>
      <Main className="pref-email">
        <Stack hasGutter>
          <StackItem>
            <YourInformation />
          </StackItem>
          <StackItem>
            <Card ouiaId="user-pref-email-subscriptions-card">
              <CardHeader className="pf-u-pb-0">
                <TextContent>
                  <Text component={TextVariants.h2}>Email subscriptions</Text>
                  <Text component={TextVariants.p}>
                    Select the emails you want to receive.
                  </Text>
                </TextContent>
              </CardHeader>
              <CardBody className="pref-email_form">
                {isLoaded ? (
                  <FormRender
                    componentMapper={{
                      ...componentMapper,
                      [DESCRIPTIVE_CHECKBOX]: DescriptiveCheckbox,
                      [LOADER]: Loader,
                      [DATA_LIST]: DataListLayout,
                    }}
                    FormTemplate={(props) => (
                      <FormTemplate {...props} FormButtons={FormButtons} />
                    )}
                    schema={{
                      fields: [
                        {
                          name: 'email-preferences',
                          component: DATA_LIST,
                          sections: Object.entries(emailConfig).map(
                            ([key, schema]) => calculateSection(key, schema)
                          ),
                        },
                      ],
                    }}
                    onSubmit={saveValues}
                  />
                ) : (
                  <Bullseye>
                    <Spinner />
                  </Bullseye>
                )}
              </CardBody>
            </Card>
          </StackItem>
        </Stack>
      </Main>
    </React.Fragment>
  );
}
Example #20
Source File: RepositoryTable.js    From edge-frontend with Apache License 2.0 4 votes vote down vote up
RepositoryTable = ({
  data,
  count,
  isLoading,
  hasError,
  fetchRepos,
  openModal,
}) => {
  const actionResolver = (rowData) => {
    if (!rowData.rowInfo) {
      return [];
    }
    const { id, repoName, repoBaseURL } = rowData.rowInfo;
    return [
      {
        title: 'Edit',
        onClick: () =>
          openModal({
            type: 'edit',
            id: id,
            name: repoName,
            baseURL: repoBaseURL,
          }),
      },
      {
        title: 'Remove',
        onClick: () =>
          openModal({
            type: 'remove',
            id: id,
            name: repoName,
            baseURL: repoBaseURL,
          }),
      },
    ];
  };

  const buildRows = data.map(({ ID, Name, URL }) => {
    return {
      rowInfo: {
        id: ID,
        repoName: Name,
        repoBaseURL: URL,
      },
      cells: [
        {
          title: (
            <>
              <Text className="pf-u-mb-xs" component={TextVariants.p}>
                <Tooltip content={<div>{Name}</div>}>
                  <span>{truncateString(Name, 20)}</span>
                </Tooltip>
              </Text>
              <Text
                component={TextVariants.a}
                href={URL}
                target="_blank"
                rel="noopener noreferrer"
              >
                {URL} <ExternalLinkAltIcon className="pf-u-ml-sm" />
              </Text>
            </>
          ),
        },
      ],
    };
  });

  return (
    <>
      <GeneralTable
        apiFilterSort={true}
        isUseApi={true}
        loadTableData={fetchRepos}
        filters={filters}
        tableData={{
          count,
          data,
          isLoading,
          hasError,
        }}
        columnNames={[{ title: 'Name', type: 'name', sort: true }]}
        rows={buildRows}
        actionResolver={actionResolver}
        areActionsDisabled={() => false}
        defaultSort={{ index: 0, direction: 'asc' }}
        toolbarButtons={[
          {
            title: 'Add repository',
            click: () => openModal({ type: 'add' }),
          },
        ]}
      />
    </>
  );
}
Example #21
Source File: ImageDetailTab.js    From edge-frontend with Apache License 2.0 4 votes vote down vote up
ImageDetailTab = ({ imageData, imageVersion }) => {
  const [data, setData] = useState({});

  useEffect(() => {
    imageVersion
      ? setData(imageVersion)
      : setData(imageData?.data?.Data?.images?.[0]);
  }, [imageData, imageVersion]);

  const createSkeleton = (rows) =>
    [...Array(rows * 2)].map((_, key) => <Skeleton width="180px" key={key} />);

  const dateFormat = () => <DateFormat date={data?.image?.['CreatedAt']} />;

  const detailsMapper = {
    Version: 'Version',
    Created: () => dateFormat(),
    'Type(s)': () =>
      data?.image?.['OutputTypes']?.map((outputType, index) => (
        <div key={index}>{outputType}</div>
      )),
    Release: () => distributionMapper?.[data?.image?.['Distribution']],
    //Size: 'Size',
    Description: 'Description',
  };

  const userInfoMapper = {
    Username: () => data?.image?.Installer?.Username,
    'SSH key': () => data?.image?.Installer?.SshKey,
  };
  const renderAdditionalPackageLink = () => {
    return (
      <Link
        to={`${paths['manage-images']}/${data?.image?.ImageSetID}/versions/${data?.image?.ID}/packages/additional`}
      >
        {data?.additional_packages}
      </Link>
    );
  };

  const renderTotalPackageLink = () => {
    return (
      <Link
        to={`${paths['manage-images']}/${data?.image?.ImageSetID}/versions/${data?.image?.ID}/packages/all`}
      >
        {data?.packages}
      </Link>
    );
  };

  const packageMapper = {
    'Total additional packages': renderAdditionalPackageLink,
    'Total packages': renderTotalPackageLink,
  };

  const packageDiffMapper = {
    Added: () => data?.update_added,
    Removed: () => data?.update_removed,
    Updated: () => data?.update_updated,
  };

  if (data?.image?.Installer?.Checksum) {
    detailsMapper['SHA-256 checksum'] = () => data?.image?.Installer?.Checksum;
  }

  if (data?.image?.Commit?.OSTreeCommit) {
    detailsMapper['Ostree commit hash'] = () =>
      data?.image?.Commit?.OSTreeCommit;
  }

  const buildTextList = (labelsToValueMapper) =>
    data
      ? Object.entries(labelsToValueMapper).map(([label, value], index) => {
          return (
            <Fragment key={index}>
              <TextListItem
                className="details-label"
                component={TextListItemVariants.dt}
              >
                {label}
              </TextListItem>
              {label === 'SHA-256 checksum' ||
              label === 'Ostree commit hash' ||
              (label === 'SSH key' && value()) ? (
                <TextListItem component={TextListItemVariants.dd}>
                  <ClipboardCopy
                    hoverTip="Copy"
                    clickTip="Copied"
                    variant="expansion"
                    className="pf-u-text-break-word"
                    id={`${label
                      .replace(/\s+/g, '-')
                      .toLowerCase()}-clipboard-copy`}
                  >
                    {typeof value === 'function'
                      ? value() || 'Unavailable'
                      : data?.image?.[value] || 'Unavailable'}
                  </ClipboardCopy>
                </TextListItem>
              ) : (
                <TextListItem
                  className="pf-u-text-break-word"
                  component={TextListItemVariants.dd}
                >
                  {typeof value === 'function'
                    ? value() === 0
                      ? 0
                      : value() || 'Unavailable'
                    : data?.image?.[value] || 'Unavailable'}
                </TextListItem>
              )}
            </Fragment>
          );
        })
      : null;

  return (
    <TextContent className="pf-u-ml-lg pf-u-mt-md">
      <Grid span={12}>
        <GridItem span={5}>
          <Text component={TextVariants.h2}>
            {imageVersion ? 'Details' : 'Most recent image'}
          </Text>
          <TextList component={TextListVariants.dl}>
            {buildTextList(detailsMapper) || createSkeleton(6)}
          </TextList>
          <Text component={TextVariants.h2}>User information </Text>
          <TextList component={TextListVariants.dl}>
            {buildTextList(userInfoMapper) || createSkeleton(2)}
          </TextList>
        </GridItem>
        <GridItem span={1} />
        <GridItem span={6}>
          <Text component={TextVariants.h2}>Packages </Text>
          <TextList component={TextListVariants.dl}>
            {buildTextList(packageMapper) || createSkeleton(3)}
          </TextList>
          <Text component={TextVariants.h2}>Changes from previous version</Text>
          <TextList component={TextListVariants.dl}>
            {buildTextList(packageDiffMapper) || createSkeleton(3)}
          </TextList>
        </GridItem>
      </Grid>
    </TextContent>
  );
}