@patternfly/react-core#Spinner JavaScript Examples

The following examples show how to use @patternfly/react-core#Spinner. 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: utilities.js    From ibutsu-server with MIT License 7 votes vote down vote up
export function getSpinnerRow(columnCount) {
  return {
    heightAuto: true,
    cells: [
      {
        props: {colSpan: columnCount},
        title: <Bullseye><center><Spinner size="xl"/></center></Bullseye>
      }
    ]
  };
}
Example #2
Source File: StatusBar.js    From cockpit-wicked with GNU General Public License v2.0 6 votes vote down vote up
StatusBar = ({
    showSpinner = false,
    children
}) => {
    return (
        <PageSection className="content-header-extra">
            <Split hasGutter id="state" className="content-header-extra--state">
                { showSpinner && <SplitItem><Spinner size="md" /></SplitItem> }
                <SplitItem isFilled>{children}</SplitItem>
            </Split>
        </PageSection>
    );
}
Example #3
Source File: Routes.js    From dbaas-ui with Apache License 2.0 6 votes vote down vote up
Routes = () => (
  <Suspense
    fallback={
      <Bullseye>
        <Spinner />
      </Bullseye>
    }
  >
    <Switch>
      <Route path="/">
        <HomePage />
      </Route>
      <Route>
        <OopsPage />
      </Route>
    </Switch>
  </Suspense>
)
Example #4
Source File: AvailableImagesTile.js    From edge-frontend with Apache License 2.0 6 votes vote down vote up
AvailableImageTile = ({ onNewImageClick }) => {
  const { isLoading, hasError, data } = useSelector(
    ({ imagesReducer }) => ({
      isLoading:
        imagesReducer?.isLoading !== undefined
          ? imagesReducer?.isLoading
          : true,
      hasError: imagesReducer?.hasError || false,
      data: imagesReducer?.data || null,
    }),
    shallowEqual
  );

  return (
    <AvailableImageTileBase>
      <CardBody>
        {isLoading ? (
          <Bullseye>
            <Spinner />
          </Bullseye>
        ) : hasError ? (
          data
        ) : (
          <Button variant="link" style={{ paddingLeft: 0 }}>
            {data.meta.count} images
          </Button>
        )}
      </CardBody>
      <CardFooter>
        <Button variant="primary" onClick={() => onNewImageClick()}>
          Create new image
        </Button>
      </CardFooter>
    </AvailableImageTileBase>
  );
}
Example #5
Source File: Routes.js    From tasks-frontend with Apache License 2.0 6 votes vote down vote up
Routes = () => (
  <Suspense
    fallback={
      <Bullseye>
        <Spinner />
      </Bullseye>
    }
  >
    <Switch>
      <Route exact path="/" render={() => <TasksPage tab={0} />} />
      {/*<Redirect exact from="/" to={'/available'} />*/}
      <Route exact path="/available" render={() => <TasksPage tab={0} />} />
      <Route exact path="/executed" render={() => <TasksPage tab={1} />} />
      <Route
        exact
        path="/executed/:id"
        //render={() => <CompletedTaskDetails />}
        component={CompletedTaskDetails}
      />
      {/* Finally, catch all unmatched routes */}
      <Route>
        <Redirect to="/" />
      </Route>
    </Switch>
  </Suspense>
)
Example #6
Source File: Routes.js    From sed-frontend with Apache License 2.0 6 votes vote down vote up
Routes = () => (
  <Suspense
    fallback={
      <Bullseye>
        <Spinner />
      </Bullseye>
    }
  >
    <Authentication>
      <Switch>
        <Route path={paths.activationKeys} component={ActivationKeys} />
        <Route path={paths.connector} component={Dashboard} />
      </Switch>
    </Authentication>
  </Suspense>
)
Example #7
Source File: Routes.js    From ocp-advisor-frontend with Apache License 2.0 6 votes vote down vote up
Routes = () => (
  <Suspense
    fallback={
      <Bullseye>
        <Spinner />
      </Bullseye>
    }
  >
    <Switch>
      {paths.map((path) => (
        <Route key={path.title} path={path.path} component={path.component} />
      ))}
      <Redirect exact from="/" to="/recommendations" />
      {/* Finally, catch all unmatched routes */}
      <Route
        path="*"
        component={() => (
          <EmptyState>
            <EmptyStateBody>
              <InvalidObject />
            </EmptyStateBody>
          </EmptyState>
        )}
      />
    </Switch>
  </Suspense>
)
Example #8
Source File: ImageCreator.js    From edge-frontend with Apache License 2.0 6 votes vote down vote up
AsyncCreateImageWizard = (props) => (
  <AsyncComponent
    appName="image-builder"
    scope="image_builder"
    module="./ImageCreator"
    fallback={<Spinner />}
    {...props}
  />
)
Example #9
Source File: Loading.js    From sed-frontend with Apache License 2.0 5 votes vote down vote up
Loading = () => {
  return (
    <Bullseye>
      <Spinner />
    </Bullseye>
  );
}
Example #10
Source File: Routes.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
Routes = () => {
  return (
    <Suspense
      fallback={
        <Bullseye>
          <Spinner size="xl" />
        </Bullseye>
      }
    >
      <Switch>
        <Route exact path={paths.groups} component={Groups} />
        <Route exact path={paths['groups-detail']} component={GroupsDetail} />
        {/* <Route path={paths['device-detail']} component={DeviceDetail} /> */}
        {/* <Route path={paths.canaries} component={Canaries} /> */}
        <Route exact path={paths['fleet-management']} component={Groups} />
        <Route
          exact
          path={paths['fleet-management-detail']}
          component={GroupsDetail}
        />
        <Route exact path={paths['inventory']} component={Inventory} />
        <Route path={paths['inventory-detail']} component={DeviceDetail} />
        <Route
          path={paths['manage-images-detail-version']}
          component={ImageDetail}
        />
        <Route path={paths['manage-images-detail']} component={ImageDetail} />
        <Route path={paths['manage-images']} component={Images} />

        {useFeatureFlags('fleet-management.custom-repos') && (
          <Route exact path={paths['repositories']} component={Repositories} />
        )}
        <Route
          exact
          path={paths['learning-resources']}
          component={LearningResources}
        />
        <Route>
          <Redirect to={paths['fleet-management']} />
        </Route>
      </Switch>
    </Suspense>
  );
}
Example #11
Source File: DeviceSummaryTile.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
DeviceSummaryTile = () => {
  const { isLoading, hasError, data } = useSelector(
    ({ deviceSummaryReducer }) => ({
      isLoading:
        deviceSummaryReducer?.isLoading !== undefined
          ? deviceSummaryReducer?.isLoading
          : true,
      hasError: deviceSummaryReducer?.hasError || false,
      data: deviceSummaryReducer?.data || null,
    }),
    shallowEqual
  );

  if (isLoading) {
    return (
      <Card className="tiles-card">
        <CardTitle>Device summary information</CardTitle>
        <CardBody>
          <Bullseye>
            <Spinner />
          </Bullseye>
        </CardBody>
      </Card>
    );
  }
  if (hasError) {
    return (
      <Card className="tiles-card">
        <CardTitle>Device summary information</CardTitle>
        <CardBody>{data}</CardBody>
      </Card>
    );
  }
  return (
    <DeviceSummaryTileBase
      orphaned={data['orphaned']}
      active={data['active']}
      noReports={data['noReports']}
      neverReported={data['neverReported']}
    />
  );
}
Example #12
Source File: ImageCreator.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
CreateImageWizard = ({
  schema,
  onSubmit,
  onClose,
  customComponentMapper,
  initialValues,
  defaultArch,
}) => {
  return schema ? (
    <FormRenderer
      schema={schema}
      className="image-builder"
      subscription={{ values: true }}
      FormTemplate={(props) => (
        <Pf4FormTemplate {...props} showFormControls={false} />
      )}
      onSubmit={(formValues) => onSubmit(formValues)}
      initialValues={initialValues}
      componentMapper={{
        ...componentMapper,
        // wizard: WrappedWizard,
        'registration-creds': {
          component: RegistrationCreds,
        },
        'image-output-checkbox': {
          component: ImageOutputCheckbox,
        },
        'ssh-input-field': {
          component: SSHInputField,
        },
        review: Review,
        'package-selector': {
          component: Packages,
          defaultArch,
        },
        'custom-repo-table': {
          component: WizardRepositoryTable,
        },
        'custom-package-text-area': {
          component: CustomPackageTextArea,
        },
        ...customComponentMapper,
      }}
      validate={(values) => {
        const errors = {};
        if (
          values['validate-custom-repos'] &&
          values['custom-packages']?.length > 0 &&
          values['third-party-repositories']?.length === 0
        ) {
          errors['custom-packages'] = 'No custom repositories linked';
        }
        return errors;
      }}
      validatorMapper={{
        ...validatorTypes,
        registrationCredsValidator,
        reservedUsernameValidator,
      }}
      onCancel={onClose}
    />
  ) : (
    <Spinner />
  );
}
Example #13
Source File: SysTable.js    From malware-detection-frontend with Apache License 2.0 5 votes vote down vote up
SysTable = () => {
    const inventory = useRef(null);
    const intl = useIntl();
    const { getRegistry } = useContext(RegistryContext);
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch({ type: 'INVENTORY_INIT' });
        dispatch({ type: 'RESET_PAGE' });
        inventory?.current?.onRefreshData();
    }, [dispatch]);

    const fetchSystems = useCallback(useFetchSystems({
        query: GET_SYSTEM_TABLE
    }), []);

    return <React.Fragment>
        <InventoryTable
            isFullView
            autoRefresh
            initialLoading
            hideFilters={{ all: true, name: false, tags: false }}
            columns={mergedColumns}
            showTags
            ref={inventory}
            fallback={<Spinner />}
            onLoad={defaultOnLoad(columns, getRegistry)}
            getEntities={async (
                _ids,
                { page = 1, per_page: perPage, orderBy, orderDirection, filters }
            ) => {
                const sortableColumn = findColumnByKey(orderBy);
                const sortBy = appendDirection(sortableColumn?.sortBy, orderDirection);
                const filterForApi = buildApiFilters(filters);
                const limit = perPage;
                const offset = page * perPage - perPage;

                const fetchedEntities = await fetchSystems(limit, offset, {
                    ...filterForApi,
                    orderBy: sortBy
                });
                const {
                    entities,
                    meta: { totalCount }
                } = fetchedEntities || {};

                return {
                    // we need "dipslay_name" in TagModal for title, hence this mapping
                    results: entities.map(entity => ({ ...entity, display_name: entity.displayName })),
                    orderBy,
                    orderDirection,
                    total: totalCount
                };
            }}
            tableProps={{
                canSelectAll: false,
                className: 'sysTable',
                isStickyHeader: true
            }}
            noSystemsTable={<MessageState className='pf-c-card' icon={SearchIcon} variant='large' title={intl.formatMessage(messages.noResults)}
                text={intl.formatMessage(messages.noResultsMatch)}/>}
            customFilters={{
                malwareParams: {
                    ...globalFilters()
                }
            }}
        />
    </React.Fragment>;
}
Example #14
Source File: App.js    From ocp-advisor-frontend with Apache License 2.0 5 votes vote down vote up
App = ({ useLogger, basename }) => {
  const intl = useIntl();
  const history = useHistory();
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const registry = getRegistry();
    registry.register({ notifications: notificationsReducer });
    insights.chrome.init();
    insights.chrome.auth.getUser().then(() => {
      setIsAuthenticated(true);
      setIsLoading(false);
    });
    insights.chrome.identifyApp('ocp-advisor');
    const unregister = insights.chrome.on('APP_NAVIGATION', (event) => {
      const targetUrl = event.domEvent?.href
        ?.replace(basename, '/')
        .replace(/^\/\//, '/');
      if (typeof targetUrl === 'string') {
        history.push(targetUrl);
      }
    });
    return () => unregister();
  }, []);
  return (
    <ErrorBoundary>
      {isLoading ? (
        <Bullseye>
          <Spinner />
        </Bullseye>
      ) : isAuthenticated ? (
        <Provider store={getStore(useLogger)}>
          <NotificationsPortal />
          <Routes />
        </Provider>
      ) : (
        <Bullseye>
          <MessageState
            variant="large"
            icon={LockIcon}
            title={intl.formatMessage(messages.permsTitle)}
            text={intl.formatMessage(messages.permsBody)}
          />
        </Bullseye>
      )}
    </ErrorBoundary>
  );
}
Example #15
Source File: WirelessEssidSelect.js    From cockpit-wicked with GNU General Public License v2.0 5 votes vote down vote up
WirelessEssidSelect = ({ essid, setEssid, iface }) => {
    const [isOpen, setIsOpen] = useState(false);
    const [essidList, setEssidList] = useState(undefined);

    const refreshList = (name) => {
        fetchEssidList(name)
                .then(result => {
                    const list = [...new Set([...result])];
                    setEssidList(list.sort());
                })
                .catch(console.error);
    };

    const onToggle = isOpen => {
        if (isOpen) {
            setEssidList(undefined);
            refreshList(iface.name);
        }

        setIsOpen(isOpen);
    };

    const onSelect = (selection) => {
        setEssid(selection);
        setIsOpen(false);
    };

    const renderOptions = () => {
        if (!essidList) {
            return [
                <DropdownItem isDisabled key="scanning" icon={<Spinner size="md" />}>
                    {_("Scanning...")}
                </DropdownItem>
            ];
        }

        if (essidList.length === 0) {
            return [
                <DropdownItem isDisabled key="no-networks-found" icon={<ExclamationIcon />}>
                    {_("No networks found")}
                </DropdownItem>
            ];
        }

        return essidList.map(value => <DropdownItem key={value} onClick={() => onSelect(value)}>{value}</DropdownItem>);
    };

    return (
        <InputGroup>
            <TextInput id="essid" value={essid} onChange={setEssid} type="text" aria-label="Essid" />
            <Dropdown
              position={DropdownPosition.right}
              isOpen={isOpen}
              dropdownItems={renderOptions()}
              toggle={
                  <DropdownToggle id="essid-scanned-list" toggleIndicator={null} onToggle={onToggle} aria-label="Essid scanned list">
                      <SearchIcon />
                  </DropdownToggle>
              }
            />
        </InputGroup>
    );
}
Example #16
Source File: SystemTable.js    From tasks-frontend with Apache License 2.0 5 votes vote down vote up
SystemTable = ({ selectedIds, selectIds }) => {
  const inventory = useRef(null);
  const { getRegistry } = useContext(RegistryContext);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch({ type: 'INVENTORY_INIT' });
    dispatch({ type: 'RESET_PAGE' });
    inventory?.current?.onRefreshData();
  }, [dispatch]);

  const mergedColumns = (defaultColumns) =>
    systemColumns.map((column) => {
      const isStringCol = typeof column === 'string';
      const key = isStringCol ? column : column.key;
      const defaultColumn = defaultColumns.find(
        (defaultCol) => defaultCol.key === key
      );
      return {
        ...defaultColumn,
        ...(isStringCol ? { key: column } : column),
        props: {
          ...defaultColumn?.props,
          ...column?.props,
        },
      };
    });

  return (
    <InventoryTable
      isFullView
      autoRefresh
      initialLoading
      showTags
      hideFilters={{
        all: true,
        //name: false,
        //tags: false,
        //operatingSystem: false,
      }}
      columns={mergedColumns}
      ref={inventory}
      fallback={<Spinner />}
      onLoad={defaultOnLoad(systemColumns, getRegistry)}
      getEntities={useGetEntities(selectedIds)}
      tableProps={{
        canSelectAll: false,
        isStickyHeader: true,
        onSelect: selectIds,
      }}
    />
  );
}
Example #17
Source File: CancelRequestModal.js    From access-requests-frontend with Apache License 2.0 5 votes vote down vote up
CancelRequestModal = ({ requestId, onClose }) => {
  const [isLoading, setIsLoading] = React.useState(false);
  const dispatch = useDispatch();
  const onCancel = () => {
    setIsLoading(true);
    // https://ci.cloud.redhat.com/docs/api-docs/rbac#operations-CrossAccountRequest-patchCrossAccountRequest
    apiInstance
      .patch(
        `${API_BASE}/cross-account-requests/${requestId}/`,
        { status: 'cancelled' },
        {
          headers: {
            'Content-Type': 'application/json',
            Accept: 'application/json',
          },
        }
      )
      .then((res) => {
        if (res.errors && res.errors.length > 0) {
          throw Error(res.errors.map((e) => e.detail).join('\n'));
        }
        dispatch(
          addNotification({
            variant: 'success',
            title: 'Request cancelled successfully',
          })
        );
        setIsLoading(false);
        onClose(true);
      })
      .catch((err) => {
        dispatch(
          addNotification({
            variant: 'danger',
            title: 'There was an error cancelling your request',
            description: err.message,
          })
        );
        setIsLoading(false);
        onClose(true);
      });
  };
  return (
    <Modal
      title="Cancel request?"
      isOpen
      variant="small"
      onClose={() => onClose(false)}
      actions={[
        <Button key="confirm" variant="danger" onClick={onCancel}>
          Yes, cancel
        </Button>,
        <Button key="cancel" variant="link" onClick={() => onClose(false)}>
          No, keep
        </Button>,
      ]}
    >
      Request <b>{requestId}</b> will be withdrawn.
      {isLoading && <Spinner size="lg" />}
    </Modal>
  );
}
Example #18
Source File: Routes.js    From access-requests-frontend with Apache License 2.0 5 votes vote down vote up
Routes = () => {
  const { getRegistry } = useContext(RegistryContext);
  const [isInternal, setIsInternal] = useState(true);

  useEffect(() => {
    insights.chrome.init();
    Promise.resolve(insights.chrome.auth.getUser()).then((user) => {
      setIsInternal(user?.identity?.user?.is_internal);
    });
  });

  const AccessRequestDetailsPageWrapper = () => (
    <AccessRequestDetailsPage
      isInternal={isInternal}
      getRegistry={getRegistry}
    />
  );
  const AccessRequestsPageWrapper = () => (
    <AccessRequestsPage isInternal={isInternal} getRegistry={getRegistry} />
  );

  return (
    <Suspense
      fallback={
        <Bullseye>
          <Spinner />
        </Bullseye>
      }
    >
      {isDev && (
        <ToggleSwitch
          id="toggle-view"
          label="Internal view"
          labelOff="External view"
          isChecked={isInternal}
          onChange={() => setIsInternal(!isInternal)}
        />
      )}
      <Switch>
        <Route path="/" exact component={AccessRequestsPageWrapper} />
        <Route
          path="/:requestId"
          exact
          component={AccessRequestDetailsPageWrapper}
        />
        <Route>
          <Redirect to="/" />
        </Route>
      </Switch>
    </Suspense>
  );
}
Example #19
Source File: App.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
App = (props) => {
  const { getRegistry } = useContext(RegistryContext);
  const [isLogged, setIsLogged] = useState(false);
  const history = useHistory();
  const [isAuth, setIsAuth] = useState(null);
  useEffect(() => {
    insights.chrome.init();
    // TODO change this to your appname
    insights.chrome.identifyApp('fleet-management');

    insights.chrome.on('APP_NAVIGATION', (event) =>
      history.push(`/${event.navId}`)
    );

    const registered = getRegistry().register({
      notifications: notificationsReducer,
    });
    (async () => {
      await insights.chrome.auth.getUser();
      setIsLogged(true);
    })();

    (async () => {
      const data = await insights.chrome.auth.getUser();
      setIsAuth(data.entitlements.smart_management.is_entitled);
    })();

    return () => {
      registered();
    };
  }, []);

  return (
    <Fragment>
      <NotificationPortal />
      {isAuth && isLogged ? (
        <Routes childProps={props} />
      ) : isAuth === null ? (
        <Bullseye>
          <Spinner size="xl" />
        </Bullseye>
      ) : (
        <AuthModal />
      )}
    </Fragment>
  );
}
Example #20
Source File: AddDeviceModal.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
AddDeviceModal = ({
  isModalOpen,
  setIsModalOpen,
  setIsCreateGroupModalOpen,
  reloadData,
  deviceIds,
}) => {
  const dispatch = useDispatch();
  const [response] = useApi({ api: getGroups });
  const { data, isLoading } = response;

  const handleAddDevices = (values) => {
    const { group } = values;
    const statusMessages = {
      onSuccess: {
        title: 'Success',
        description: `Device(s) have been added to ${group.toString()} successfully`,
      },
      onError: { title: 'Error', description: 'Failed to add device to group' },
    };

    apiWithToast(
      dispatch,
      () => addDevicesToGroup(parseInt(group.groupId), deviceIds),
      statusMessages
    );
  };
  return isLoading ? (
    <Backdrop>
      <Bullseye>
        <Spinner isSVG diameter="100px" />
      </Bullseye>
    </Backdrop>
  ) : (
    <Modal
      isOpen={isModalOpen}
      openModal={() => setIsModalOpen(false)}
      title="Add to group"
      submitLabel="Add"
      additionalMappers={{
        'search-input': {
          component: SearchInput,
          defaultOptions: data?.data || [],
        },
        'create-group-btn': {
          component: CreateGroupButton,
          openModal: () => {
            setIsCreateGroupModalOpen(true);
            setIsModalOpen(false);
          },
        },
      }}
      schema={createSchema(deviceIds)}
      onSubmit={handleAddDevices}
      reloadData={reloadData}
    />
  );
}
Example #21
Source File: ImageVersionDetail.js    From edge-frontend with Apache License 2.0 5 votes vote down vote up
ImageVersionDetail = ({ data, imageVersion }) => {
  const history = useHistory();
  const [isUpdateWizardOpen, setIsUpdateWizardOpen] = useState(false);
  const [imageData, setImageData] = useState({});

  useEffect(() => {
    setImageData(data);
  }, [data]);

  const openUpdateWizard = () => {
    history.push({
      pathname: history.location.pathname,
      search: new URLSearchParams({
        update_image: true,
      }).toString(),
    });
    setIsUpdateWizardOpen(true);
  };

  return (
    <Fragment>
      <PageHeader className="pf-m-light">
        <Stack hasGutter>
          <StackItem>
            <DetailsHead
              imageData={imageData}
              imageVersion={imageVersion}
              openUpdateWizard={openUpdateWizard}
            />
          </StackItem>
        </Stack>
        <StackItem>
          <Text>{data?.Description}</Text>
        </StackItem>
      </PageHeader>
      <ImageDetailTabs imageData={imageData} imageVersion={imageVersion} />
      {isUpdateWizardOpen && (
        <Suspense
          fallback={
            <Bullseye>
              <Spinner />
            </Bullseye>
          }
        >
          <UpdateImageWizard
            navigateBack={() => {
              history.push({ pathname: history.location.pathname });
              setIsUpdateWizardOpen(false);
            }}
            updateimageVersionId={data?.ID}
          />
        </Suspense>
      )}
    </Fragment>
  );
}
Example #22
Source File: index.js    From sed-frontend with Apache License 2.0 4 votes vote down vote up
SamplePage = () => {
  const history = useHistory();
  const { getRegistry } = useContext(RegistryContext);
  const [confirmChangesOpen, setConfirmChangesOpen] = useState(false);
  const [madeChanges, setMadeChanges] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const dataRef = useRef();
  const dispatch = useDispatch();

  const activeStateLoaded = useSelector(
    ({ activeStateReducer }) => activeStateReducer?.loaded
  );
  const { useOpenSCAP, enableCloudConnector, hasInsights } = useSelector(
    ({ activeStateReducer }) => ({
      useOpenSCAP: activeStateReducer?.values?.useOpenSCAP,
      enableCloudConnector: activeStateReducer?.values?.enableCloudConnector,
      hasInsights: activeStateReducer?.values?.hasInsights,
    }),
    shallowEqual
  );
  const { systemsCount } = useSelector(
    ({ connectedSystemsReducer }) => ({
      systemsLoaded: connectedSystemsReducer?.loaded,
      systemsCount: connectedSystemsReducer?.total,
    }),
    shallowEqual
  );

  useEffect(() => {
    getRegistry().register({
      activeStateReducer,
      logReducer,
      connectedSystemsReducer,
    });
    dispatch(fetchCurrState());
    dispatch(fetchConnectedHosts());
  }, [getRegistry]);

  useEffect(() => {
    insights?.chrome?.appAction?.('cloud-connector-dashboard');
  }, []);

  return (
    <React.Fragment>
      <Route
        exact
        path={paths.logModal}
        render={() => (
          <Suspense
            fallback={
              <Bullseye>
                <Spinner />
              </Bullseye>
            }
          >
            <ConnectLog />
          </Suspense>
        )}
      />
      <PageHeader className="page-header">
        <Split hasGutter className="page-title">
          <SplitItem isFilled>
            <Flex>
              <FlexItem spacer={{ default: 'spacerSm' }}>
                <PageHeaderTitle title="Remote Host Configuration Manager" />
              </FlexItem>
              <FlexItem>
                <AboutRemoteHostConfigPopover />
              </FlexItem>
            </Flex>
          </SplitItem>
          <SplitItem>
            <Button onClick={() => history.push(paths.logModal)} variant="link">
              View log
            </Button>
          </SplitItem>
        </Split>
        <Stack hasGutter>
          <StackItem>
            Selections here affect Red Hat Enterprise Linux (RHEL) systems
            connected to Red Hat with remote host configuration (rhc). Upon
            saving changes, Ansible Playbooks are automatically pushed to
            connected systems to update the configuration of the connection to
            Red Hat.
          </StackItem>
          <StackItem>
            <a
              target="_blank"
              rel="noopener noreferrer"
              href={
                'https://access.redhat.com/documentation/en-us/red_hat_insights/2022/html-single/red_hat_connector_configuration_guide/index'
              }
            >
              Connecting with Red Hat
              {<ExternalLinkAltIcon className="pf-u-ml-sm" />}
            </a>
          </StackItem>
        </Stack>
      </PageHeader>
      <Page>
        <div className="dashboard__content">
          {activeStateLoaded ||
          (useOpenSCAP !== undefined && enableCloudConnector !== undefined) ? (
            <Services
              madeChanges={madeChanges}
              setConfirmChangesOpen={setConfirmChangesOpen}
              setMadeChanges={setMadeChanges}
              setIsEditing={setIsEditing}
              isEditing={isEditing}
              defaults={{
                useOpenSCAP,
                enableCloudConnector,
                hasInsights,
              }}
              onChange={(data) => {
                dataRef.current = data;
              }}
            />
          ) : (
            <Bullseye>
              <Spinner className="pf-u-p-lg" size="xl" />
            </Bullseye>
          )}
        </div>
      </Page>
      <ConfirmChangesModal
        isOpen={confirmChangesOpen}
        handleCancel={() => setConfirmChangesOpen(false)}
        systemsCount={systemsCount}
        data={dataRef.current}
        handleConfirm={() => {
          setConfirmChangesOpen(false);
          (async () => {
            const saveAction = saveCurrState(dataRef.current);
            dispatch(saveAction);
            await saveAction.payload;
            dispatch(
              addNotification({
                variant: 'success',
                title: 'Changes saved',
                description:
                  'Your service enablement changes were applied to connected systems',
              })
            );
            setMadeChanges(false);
            setIsEditing(false);
          })();
        }}
      />
    </React.Fragment>
  );
}
Example #23
Source File: EditRequestModal.js    From access-requests-frontend with Apache License 2.0 4 votes vote down vote up
ReviewStep = ({
  targetAccount,
  start,
  end,
  roles,
  isLoading,
  error,
  onClose,
}) => {
  let content = null;
  if (isLoading) {
    content = (
      <EmptyState>
        <EmptyStateIcon icon={() => <Spinner size="lg" />} />
        <Title headingLevel="h2" size="lg">
          Submitting access request
        </Title>
        <Button variant="link" onClick={onClose}>
          Close
        </Button>
      </EmptyState>
    );
  } else if (error) {
    const context = React.useContext(WizardContextConsumer);
    content = (
      <EmptyState>
        <EmptyStateIcon icon={ExclamationCircleIcon} color="#C9190B" />
        <Title headingLevel="h2" size="lg">
          {error.title}
        </Title>
        <EmptyStateBody>{error.description}</EmptyStateBody>
        {error.title === invalidAccountTitle && (
          <Button variant="primary" onClick={() => context.goToStepById(1)}>
            Return to Step 1
          </Button>
        )}
      </EmptyState>
    );
  } else {
    content = (
      <React.Fragment>
        <Title headingLevel="h2" style={spaceUnderStyle}>
          Review details
        </Title>
        <table>
          <tr>
            <td style={spaceUnderStyle}>
              <b>Account number</b>
            </td>
            <td style={spaceUnderStyle}>{targetAccount}</td>
          </tr>
          <tr>
            <td style={{ paddingRight: '32px' }}>
              <b>Access duration</b>
            </td>
            <td></td>
          </tr>
          <tr>
            <td>From</td>
            <td>{start}</td>
          </tr>
          <tr>
            <td style={spaceUnderStyle}>To</td>
            <td style={spaceUnderStyle}>{end}</td>
          </tr>
          <tr>
            <td>
              <b>Roles</b>
            </td>
            <td>{roles[0]}</td>
          </tr>
          {roles.slice(1).map((role) => (
            <tr key={role}>
              <td></td>
              <td>{role}</td>
            </tr>
          ))}
        </table>
      </React.Fragment>
    );
  }

  return <React.Fragment>{content}</React.Fragment>;
}
Example #24
Source File: AccessRequestDetailsPage.js    From access-requests-frontend with Apache License 2.0 4 votes vote down vote up
BaseAccessRequestDetailsPage = ({ isInternal }) => {
  const [request, setRequest] = React.useState();
  const { requestId } = useParams();
  const dispatch = useDispatch();
  React.useEffect(() => {
    apiInstance
      .get(
        `${API_BASE}/cross-account-requests/${requestId}/${
          isInternal ? '?query_by=user_id' : '?query_by=target_account'
        }`,
        { headers: { Accept: 'application/json' } }
      )
      .then((res) => {
        if (res.errors) {
          throw Error(res.errors.map((e) => e.detail).join('\n'));
        }
        setRequest(res);
      })
      .catch((err) => {
        dispatch(
          addNotification({
            variant: 'danger',
            title: 'Could not load access request',
            description: err.message,
          })
        );
      });
  }, []);

  // Modal actions
  const [openModal, setOpenModal] = React.useState({ type: null });
  const onModalClose = () => setOpenModal({ type: null });
  const actions = getInternalActions(
    request && request.status,
    requestId,
    setOpenModal
  );
  const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);

  const requestDisplayProps = [
    ...(isInternal
      ? ['request_id', 'target_account']
      : ['first_name', 'last_name']),
    'start_date',
    'end_date',
    'created',
  ];
  return (
    <React.Fragment>
      <PageSection variant="light">
        <Breadcrumb>
          <BreadcrumbItem
            render={() => (
              <Link to={isInternal ? '/' : '/access-requests'}>
                {!isInternal && 'Red Hat '}Access Requests
              </Link>
            )}
          />
          <BreadcrumbItem>{requestId}</BreadcrumbItem>
        </Breadcrumb>
        <Flex direction={{ default: 'column', md: 'row' }}>
          <FlexItem grow={{ default: 'grow' }}>
            <Title headingLevel="h1" size="2xl" className="pf-u-pt-md">
              {requestId}
            </Title>
          </FlexItem>
          {isInternal && actions.items.length > 0 && (
            <FlexItem alignSelf={{ default: 'alignRight' }}>
              <Dropdown
                position="right"
                toggle={
                  <KebabToggle
                    onToggle={() => setIsDropdownOpen(!isDropdownOpen)}
                    id="actions-toggle"
                  />
                }
                isOpen={isDropdownOpen}
                isPlain
                dropdownItems={actions.items.map(({ title, onClick }) => (
                  <DropdownItem
                    key={title}
                    component="button"
                    onClick={onClick}
                  >
                    {title}
                  </DropdownItem>
                ))}
                isDisabled={actions.disable}
              />
            </FlexItem>
          )}
        </Flex>
      </PageSection>
      <PageSection>
        <Flex
          spaceItems={{ xl: 'spaceItemsLg' }}
          direction={{ default: 'column', lg: 'row' }}
        >
          <FlexItem
            flex={{ default: 'flex_1' }}
            alignSelf={{ default: 'alignSelfStretch' }}
          >
            <Card ouiaId="request-details" style={{ height: '100%' }}>
              <CardTitle>
                <Title headingLevel="h2" size="xl">
                  Request details
                </Title>
              </CardTitle>
              <CardBody>
                {!request ? (
                  <Spinner size="xl" />
                ) : (
                  <React.Fragment>
                    <div className="pf-u-pb-md">
                      {isInternal ? (
                        <div>
                          <label>
                            <b>Request status</b>
                          </label>
                          <br />
                          <Label
                            className="pf-u-mt-sm"
                            {...getLabelProps(request.status)}
                          >
                            {capitalize(request.status)}
                          </Label>
                        </div>
                      ) : (
                        <React.Fragment>
                          <label>
                            <b>Request decision</b>
                          </label>
                          <br />
                          <StatusLabel
                            requestId={requestId}
                            status={request.status}
                          />
                        </React.Fragment>
                      )}
                    </div>
                    {requestDisplayProps.map((prop, key) => (
                      <div className="pf-u-pb-md" key={key}>
                        <label>
                          <b>
                            {capitalize(
                              prop.replace(/_/g, ' ').replace('id', 'ID')
                            )}
                          </b>
                        </label>
                        <br />
                        <div>{request[prop]}</div>
                      </div>
                    ))}
                  </React.Fragment>
                )}
              </CardBody>
            </Card>
          </FlexItem>
          <FlexItem
            flex={{ default: 'flex_3' }}
            grow={{ default: 'grow' }}
            alignSelf={{ default: 'alignSelfStretch' }}
          >
            <Card ouiaId="request-roles" style={{ height: '100%' }}>
              <CardTitle>
                <Title headingLevel="h2" size="xl">
                  Roles requested
                </Title>
              </CardTitle>
              <CardBody>
                {!request ? (
                  <Spinner size="xl" />
                ) : (
                  <MUARolesTable roles={request.roles} />
                )}
              </CardBody>
            </Card>
          </FlexItem>
        </Flex>
      </PageSection>
      {openModal.type === 'cancel' && (
        <CancelRequestModal requestId={requestId} onClose={onModalClose} />
      )}
      {openModal.type === 'edit' && (
        <EditRequestModal
          variant="edit"
          requestId={requestId}
          onClose={onModalClose}
        />
      )}
    </React.Fragment>
  );
}
Example #25
Source File: InterfacesList.js    From cockpit-wicked with GNU General Public License v2.0 4 votes vote down vote up
InterfacesList = ({ interfaces = [], connections = [] }) => {
    const [rows, setRows] = useState([]);
    const [openRows, setOpenRows] = useState([]);

    const columns = [
        { title: "", props: { className: "status-column" } },
        { title: _("Name"), cellFormatters: [expandable] },
        { title: _("Type") },
        { title: _("Status"), transforms: [cellWidth(10)], cellTransforms: [truncate] },
        { title: _("Addresses") }
    ];

    const interfaceAddresses = (iface) => {
        if (iface.addresses.length === 0) return;

        return iface.addresses.map(i => i.local).join(', ');
    };

    const renderStatusIcon = (iface) => {
        if (!iface.status) return;

        if (iface.error) {
            return <><AlertIcon /></>;
        } else if (iface.status !== interfaceStatus.READY) {
            return <><Spinner size="md" /></>;
        }
    };

    const renderStatusText = (iface) => {
        const linkText = iface.link ? _('Up') : _('Down');

        if (!iface.status || iface.status === interfaceStatus.READY) {
            return linkText;
        } else {
            return interfaceStatus.label(iface.status);
        }
    };

    /**
     * Returns the connection for given interface name or a fake one if it does not exist yet
     *
     * When a connection does not exist yet, the user should be able to create one by configuring
     * the interface. To achieve that, a "default" connection object is needed, in order to build
     * the needed UI.
     *
     * @param {string} name - the interface/connection name
     * @return {module:model/connections~Connection}
     */
    const findOrCreateConnection = useCallback((name) => {
        return connections.find(c => c.name === name) || createConnection({ name, exists: false });
    }, [connections]);

    /**
     * Builds the needed structure for rendering the interfaces and their details in an expandable
     * Patternfly/Table
     */
    const buildRows = useCallback(() => {
        let parentId = 0;

        return interfaces.reduce((list, i) => {
            const conn = findOrCreateConnection(i.name);

            list.push(
                {
                    isOpen: openRows.includes(parentId),
                    cells: [
                        renderStatusIcon(i),
                        i.name,
                        interfaceType.label(i.type),
                        renderStatusText(i),
                        interfaceAddresses(i)
                    ]
                }
            );
            list.push(
                {
                    parent: parentId,
                    cells: [
                        "",
                        {
                            title: <InterfaceDetails iface={i} connection={conn} />,
                            props: { colSpan: 4 }
                        }
                    ]
                }
            );

            parentId += 2;

            return list;
        }, []);
    }, [interfaces, openRows, findOrCreateConnection]);

    /**
     * Keeps the openRows internal state up to date using the information provided by the
     * Patternfly/Table#onCollapse event
     */
    const onCollapseFn = () => (event, rowKey, isOpen) => {
        if (isOpen && !openRows.includes(rowKey)) {
            setOpenRows([...openRows, rowKey]);
        } else {
            setOpenRows(openRows.filter(k => k != rowKey));
        }
    };

    useEffect(() => {
        setRows(buildRows());
    }, [buildRows]);

    return (
        <Table
            aria-label="Networking interfaces"
            variant={TableVariant.compact}
            onCollapse={onCollapseFn()}
            className="interfaces-list"
            cells={columns}
            rows={rows}
        >
            <TableHeader />
            <TableBody />
        </Table>
    );
}
Example #26
Source File: run.js    From ibutsu-server with MIT License 4 votes vote down vote up
render() {
    let passed = 0, failed = 0, errors = 0, xfailed = 0, xpassed = 0, skipped = 0, not_run = 0;
    let created = 0;
    let calculatePasses = true;
    const { run, columns, rows, classificationTable, artifactTabs } = this.state;
    const jsonViewTheme = getTheme() === 'dark' ? 'tomorrow' : 'rjv-default';

    if (run.start_time) {
      created = new Date(run.start_time);
    }
    else {
      created = new Date(run.created);
    }
    if (run.summary) {
      if (run.summary.passes) {
        passed = run.summary.passes;
        calculatePasses = false;
      }
      if (run.summary.tests && calculatePasses) {
        passed = run.summary.tests;
      }
      if (run.summary.failures) {
        passed -= calculatePasses ? run.summary.failures : 0;
        failed = run.summary.failures;
      }
      if (run.summary.errors) {
        passed -= calculatePasses ? run.summary.errors : 0;
        errors = run.summary.errors;
      }
      if (run.summary.xfailures) {
        passed -= calculatePasses ? run.summary.xfailures : 0;
        xfailed = run.summary.xfailures;
      }
      if (run.summary.xpasses) {
        passed -= calculatePasses ? run.summary.xpasses : 0;
        xpassed = run.summary.xpasses;
      }
      if (run.summary.skips) {
        passed -= calculatePasses ? run.summary.skips : 0;
        skipped = run.summary.skips;
      }
      if (run.summary.not_run) {
        not_run = run.summary.not_run;
      }
      else if (run.summary.collected) {
        not_run = run.summary.collected - run.summary.tests;
      }
    }
    const pagination = {
      pageSize: this.state.pageSize,
      page: this.state.page,
      totalItems: this.state.totalItems
    }
    return (
      <React.Fragment>
        <PageSection variant={PageSectionVariants.light}>
          <TextContent>
            <Text component="h1" className="pf-c-title">Run {run.id}</Text>
          </TextContent>
        </PageSection>
        <PageSection>
          {!this.state.isRunValid &&
          <EmptyObject headingText="Run not found" returnLink="/runs" returnLinkText="Return to runs list" />
          }
          {this.state.isRunValid &&
            <Tabs activeKey={this.state.activeTab} onSelect={this.onTabSelect} isBox>
              <Tab eventKey={'summary'} title={<TabTitle icon={InfoCircleIcon} text="Summary" />}>
                <Card>
                  <CardBody style={{padding: 0}} id="run-detail">
                    <Grid style={{backgroundColor: '#fff'}}>
                      <GridItem span={6}>
                        <DataList selectedDataListItemId={null} aria-label="Run properties" style={{borderBottom: 'none', borderTop: 'none'}}>
                          <DataListItem aria-labelledby="Duration">
                            <DataListItemRow>
                              <DataListItemCells
                                dataListCells={[
                                  <DataListCell key={1} width={2}><strong>Duration:</strong></DataListCell>,
                                  <DataListCell key={2} width={4}>{round(run.duration)}s</DataListCell>
                                ]}
                              />
                            </DataListItemRow>
                          </DataListItem>
                          <DataListItem aria-labelledby="Started">
                            <DataListItemRow>
                              <DataListItemCells
                                dataListCells={[
                                  <DataListCell key={1} width={2}><strong>Started:</strong></DataListCell>,
                                  <DataListCell key={2} width={4}>{created.toLocaleString()}</DataListCell>
                                ]}
                              />
                            </DataListItemRow>
                          </DataListItem>
                          {run.metadata && run.metadata.component &&
                          <DataListItem aria-labelledby="Component">
                            <DataListItemRow>
                              <DataListItemCells
                                dataListCells={[
                                  <DataListCell key={1} width={2}><strong>Component:</strong></DataListCell>,
                                  <DataListCell key={2} width={4}>{run.metadata.component}</DataListCell>
                                ]}
                              />
                            </DataListItemRow>
                          </DataListItem>
                          }
                          {run.metadata && run.metadata.env &&
                            <DataListItem aria-labelledby="Environment">
                              <DataListItemRow>
                                <DataListItemCells
                                  dataListCells={[
                                    <DataListCell key={1} width={2}><strong>Environment:</strong></DataListCell>,
                                    <DataListCell key={2} width={4}>{run.metadata.env}</DataListCell>
                                  ]}
                                />
                              </DataListItemRow>
                            </DataListItem>
                          }
                          {run.metadata && run.metadata.tags &&
                            <DataListItem aria-labelledby="tags-label">
                              <DataListItemRow>
                                <DataListItemCells
                                  dataListCells={[
                                    <DataListCell key="tags-label" width={2}><strong>Tags:</strong></DataListCell>,
                                    <DataListCell key="tags-data" width={4}>
                                      <Flex>
                                        {run.metadata.tags.map((tag) => <FlexItem spacer={{ default: 'spacerXs' }} key={tag}><Label color="blue" variant="filled">{tag}</Label></FlexItem>)}
                                      </Flex>
                                    </DataListCell>
                                  ]}
                                />
                              </DataListItemRow>
                            </DataListItem>
                          }
                        {run.metadata && run.metadata.jenkins && run.metadata.jenkins.job_name &&
                          <DataListItem aria-labelledby="Jenkins Job Name">
                            <DataListItemRow>
                              <DataListItemCells
                                dataListCells={[
                                  <DataListCell key={1} width={2}><strong>Jenkins Job Name:</strong></DataListCell>,
                                  <DataListCell key={2} width={4}>{run.metadata.jenkins.job_name}</DataListCell>
                                ]}
                              />
                            </DataListItemRow>
                          </DataListItem>
                          }
                          {run.source &&
                            <DataListItem aria-labelledby="Source">
                              <DataListItemRow>
                                <DataListItemCells
                                  dataListCells={[
                                    <DataListCell key={1} width={2}><strong>Source:</strong></DataListCell>,
                                    <DataListCell key={2} width={4}>{run.source}</DataListCell>
                                  ]}
                                />
                              </DataListItemRow>
                            </DataListItem>
                          }
                        </DataList>
                      </GridItem>
                      <GridItem span={6}>
                        <DataList selectedDataListItemId={null} aria-label="Summary properties" style={{borderBottom: 0, borderTop: 0}}>
                          <DataListItem aria-labelledby="Summary">
                            <DataListItemRow>
                              <DataListItemCells
                                style={{paddingBottom: 0}}
                                dataListCells={[
                                  <DataListCell key={1} width={2}><strong>Summary:</strong></DataListCell>,
                                  <DataListCell key={2} width={4} style={{paddingTop: 0}}>
                                    <DataList selectedDataListItemId={null} aria-label="Summary" style={{borderBottom: 0, borderTop: 0}}>
                                      <DataListItem aria-labelledby="Total">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Total:</DataListCell>,
                                              <DataListCell key={2}>{run.summary.collected ? run.summary.collected : run.summary.tests}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Passed">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Passed:</DataListCell>,
                                              <DataListCell key={2}>{passed}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Failed">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Failed:</DataListCell>,
                                              <DataListCell key={2}>{failed}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Error">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Error:</DataListCell>,
                                              <DataListCell key={2}>{errors}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Xfailed">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Xfailed:</DataListCell>,
                                              <DataListCell key={2}>{xfailed}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Xpassed">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Xpassed:</DataListCell>,
                                              <DataListCell key={2}>{xpassed}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Skipped">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Skipped:</DataListCell>,
                                              <DataListCell key={2}>{skipped}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                      <DataListItem aria-labelledby="Not Run">
                                        <DataListItemRow>
                                          <DataListItemCells
                                            dataListCells={[
                                              <DataListCell key={1}>Not Run:</DataListCell>,
                                              <DataListCell key={2}>{not_run}</DataListCell>
                                            ]}
                                          />
                                        </DataListItemRow>
                                      </DataListItem>
                                    </DataList>
                                  </DataListCell>
                                ]}
                              />
                            </DataListItemRow>
                          </DataListItem>
                        </DataList>
                      </GridItem>
                    </Grid>
                  </CardBody>
                </Card>
              </Tab>
              <Tab eventKey={'results-list'} title={<TabTitle icon={CatalogIcon} text="Results List" />}>
                <Card className="pf-u-mt-lg">
                  <CardHeader>
                    <Flex style={{ width: '100%' }}>
                      <FlexItem grow={{ default: 'grow' }}>
                        <TextContent>
                          <Text component="h2" className="pf-c-title pf-m-xl">Test Results</Text>
                        </TextContent>
                      </FlexItem>
                      <FlexItem>
                        <Button variant="secondary" onClick={this.refreshResults}>Refresh results</Button>
                      </FlexItem>
                      <FlexItem>
                        <Link to={`/results?run_id[eq]=${run.id}`} className="pf-c-button pf-m-primary" style={{marginLeft: '2px'}}>See all results <ChevronRightIcon /></Link>
                      </FlexItem>
                    </Flex>
                  </CardHeader>
                  <CardBody>
                    <FilterTable
                      columns={columns}
                      rows={rows}
                      pagination={pagination}
                      isEmpty={this.state.isEmpty}
                      isError={this.state.isError}
                      onSetPage={this.setPage}
                      onSetPageSize={this.pageSizeSelect}
                    />
                  </CardBody>
                </Card>
              </Tab>
              <Tab eventKey={'results-tree'} title={<TabTitle icon={RepositoryIcon} text="Results Tree" />}>
                <Card className="pf-u-mt-lg">
                  <CardBody>
                    <Grid gutter="sm">
                      {false && <GridItem span={12}>
                        <div style={{paddingTop: "1em"}}>
                          <TextInput value={this.state.treeSearch} type="text" onChange={this.onSearch} placeholder="Search tree..." aria-label="Filter tree" />
                        </div>
                      </GridItem>
                      }
                      {this.state.resultsTree.core.data.length === 0 &&
                        <GridItem span={12}>
                          <Bullseye><center><Spinner size="xl"/></center></Bullseye>
                        </GridItem>
                      }
                      {this.state.resultsTree.core.data !== 0 &&
                        <React.Fragment>
                          <GridItem span={5}>
                            <TreeView treeData={this.state.resultsTree} onChange={(e, data) => this.handleJSTreeChange(e, data)}/>
                          </GridItem>
                          <GridItem span={7}>
                            {this.state.testResult &&
                            <Card className={this.state.testResult.result}>
                              <CardHeader>
                                {this.state.testResult.test_id}
                                {this.state.testResult.metadata.markers &&
                                  <div style={{float: 'right'}}>
                                    {this.state.testResult.metadata.markers.map((marker) => {
                                      return <Badge isRead key={marker.name}>{marker.name}</Badge>;
                                    })}
                                  </div>
                                }
                              </CardHeader>
                              <CardBody style={{backgroundColor: "var(--pf-c-page__main-section--BackgroundColor)", paddingTop: "1.2em"}}>
                                <ResultView testResult={this.state.testResult}/>
                              </CardBody>
                            </Card>
                            }
                          </GridItem>
                        </React.Fragment>
                      }
                    </Grid>
                  </CardBody>
                </Card>
              </Tab>
              <Tab eventKey={'classify-failures'} title={<TabTitle icon={MessagesIcon} text="Classify Failures" />}>
                {classificationTable}
              </Tab>
              {artifactTabs}
              <Tab eventKey={'run-object'} title={<TabTitle icon={CodeIcon} text="Run Object" />}>
                <Card>
                  <CardBody>
                    <ReactJson src={run} name={null} iconStyle={"triangle"} collapseStringsAfterLength={120} enableClipboard={false} displayDataTypes={false} theme={jsonViewTheme} />
                  </CardBody>
                </Card>
              </Tab>
            </Tabs>
          }
        </PageSection>
      </React.Fragment>
    );
  }
Example #27
Source File: Notification.js    From user-preferences-frontend with Apache License 2.0 4 votes vote down vote up
Notification = () => {
  const { bundleName } = useParams();
  const navigateTo = useChromePush();
  const dispatch = useDispatch();
  const store = useSelector(
    ({ notificationPreferences }) => notificationPreferences
  );
  const bundleDisplayTitle = notificationConfigForBundle(bundleName)?.title;

  useEffect(() => {
    register(notificationPreferences);
  }, []);

  useEffect(() => {
    (async () => {
      await insights.chrome.auth.getUser();
      if (bundleName) {
        dispatch(getNotificationSchema({ bundleName }));
      }
    })();
  }, [bundleName]);

  const { isLoaded, schema } = useMemo(() => {
    if (store?.loaded) {
      const schema = { ...store.schema };
      if (schema.fields) {
        schema.fields = [...schema.fields];
        schema.fields[0].sections = [...schema.fields[0].sections];
        schema.fields[0].sections.push({
          fields: unsubscribe,
        });
      } else {
        schema.fields = [];
      }

      return {
        isLoaded: true,
        schema: schema,
      };
    }
    return {
      isLoaded: false,
      schema: [],
    };
  }, [store]);

  const saveValues = useCallback(
    async ({ unsubscribe, ...values }) => {
      const action = saveNotificationValues({ bundleName, values });
      dispatch(action);
      try {
        await action.payload;
        dispatch(
          addNotification({
            dismissable: false,
            variant: 'success',
            title: `Notification preferences successfully saved`,
          })
        );
      } catch (e) {
        dispatch(
          addNotification({
            dismissable: false,
            variant: 'danger',
            title: `Notification preferences unsuccessfully saved`,
          })
        );
      }
    },
    [bundleName]
  );

  return (
    <React.Fragment>
      <PageHeader>
        <Split>
          <SplitItem isFilled>
            <PageHeaderTitle
              className="notif-page-header"
              title={`My Notifications | ${bundleDisplayTitle}`}
            />
            <StackItem>
              This service allows you to opt-in and out of receiving
              notifications. Your Organization Administrator has configured
              which notifications you can or can not receive in their{' '}
              <a
                onClick={(e) =>
                  navigateTo(e, `/settings/notifications/${bundleName}`)
                }
                href={`/settings/notifications/${bundleName}`}
              >
                Settings
              </a>
              .
            </StackItem>
          </SplitItem>
        </Split>
      </PageHeader>
      <Main className="pref-notification">
        <Stack hasGutter>
          <StackItem>
            <Card ouiaId="user-pref-notification-subscriptions-card">
              <CardHeader className="pf-u-pb-0"></CardHeader>
              <CardBody className="pref-notification_form">
                {isLoaded ? (
                  <FormRender
                    componentMapper={{
                      ...componentMapper,
                      [DESCRIPTIVE_CHECKBOX]: DescriptiveCheckbox,
                      [LOADER]: Loader,
                      [DATA_LIST]: DataListLayout,
                    }}
                    FormTemplate={(props) => (
                      <FormTemplate {...props} FormButtons={FormButtons} />
                    )}
                    schema={schema}
                    onSubmit={saveValues}
                  />
                ) : (
                  <Bullseye>
                    <Spinner />
                  </Bullseye>
                )}
              </CardBody>
            </Card>
          </StackItem>
        </Stack>
      </Main>
    </React.Fragment>
  );
}
Example #28
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 #29
Source File: DeviceDetail.js    From edge-frontend with Apache License 2.0 4 votes vote down vote up
DeviceDetail = () => {
  const [imageId, setImageId] = useState(null);
  const { getRegistry } = useContext(RegistryContext);
  const { inventoryId, uuid } = useParams();
  const entity = useSelector(({ entityDetails }) => entityDetails?.entity);
  const groupName = useSelector(
    ({ groupsDetailReducer }) => groupsDetailReducer?.name
  );
  const deviceId = useSelector(
    ({ entityDetails }) => entityDetails?.entity?.id
  );

  const [imageData, setImageData] = useState();
  const [updateModal, setUpdateModal] = useState({
    isOpen: false,
    deviceData: null,
  });
  const [isDeviceStatusLoading, setIsDeviceStatusLoading] = useState(true);
  const [reload, setReload] = useState(false);
  useEffect(() => {
    insights.chrome.registerModule('inventory');
    insights.chrome?.hideGlobalFilter?.(true);
    insights.chrome.appAction('system-detail');
  }, []);

  useEffect(() => {
    (async () => {
      if (!entity?.display_name) {
        return;
      }
      const image_data = await getDeviceHasUpdate(deviceId);
      setImageData(image_data);
      setIsDeviceStatusLoading(false);
      setUpdateModal((prevState) => ({
        ...prevState,
        deviceData: [
          {
            display_name: entity.display_name,
            id: entity.id,
          },
        ],
        imageSetId: image_data?.ImageInfo?.Image?.ImageSetID,
      }));
      setImageId(image_data?.ImageInfo?.Image?.ID);
    })();
  }, [entity, reload]);

  useEffect(() => {
    insights?.chrome?.appObjectId?.(inventoryId);
  }, [inventoryId]);

  return (
    <>
      <DetailWrapper
        hideInvLink
        showTags
        onLoad={({ mergeWithDetail }) => {
          getRegistry().register({
            systemProfileStore,
            ...mergeWithDetail(deviceDetail),
          });
        }}
      >
        <PageHeader>
          <Breadcrumb ouiaId="systems-list">
            <BreadcrumbItem>
              <Link to={uuid ? `/groups` : '/inventory'}>
                {uuid ? 'Groups' : 'Systems'}
              </Link>
            </BreadcrumbItem>
            {uuid && (
              <BreadcrumbItem>
                {groupName ? (
                  <Link to={`/groups/${uuid}`}>{groupName}</Link>
                ) : (
                  <Skeleton size={SkeletonSize.xs} />
                )}
              </BreadcrumbItem>
            )}
            <BreadcrumbItem isActive>
              <div className="ins-c-inventory__detail--breadcrumb-name">
                {entity?.display_name || <Skeleton size={SkeletonSize.xs} />}
              </div>
            </BreadcrumbItem>
          </Breadcrumb>
          <InventoryDetailHead
            fallback=""
            actions={[
              {
                title: 'Update',
                isDisabled:
                  imageData?.UpdateTransactions?.[
                    imageData?.UpdateTransactions.length - 1
                  ]?.Status === 'BUILDING' ||
                  imageData?.UpdateTransactions?.[
                    imageData?.UpdateTransactions.length - 1
                  ]?.Status === 'CREATED' ||
                  !imageData?.ImageInfo?.UpdatesAvailable?.length > 0 ||
                  !updateModal.imageSetId,
                onClick: () => {
                  setUpdateModal((prevState) => ({
                    ...prevState,
                    isOpen: true,
                  }));
                },
              },
            ]}
            hideBack
            hideInvDrawer
          />

          {isDeviceStatusLoading ? (
            <Skeleton size={SkeletonSize.xs} />
          ) : imageData?.UpdateTransactions[
              imageData?.UpdateTransactions?.length - 1
            ]?.Status === 'BUILDING' ||
            imageData?.UpdateTransactions[
              imageData?.UpdateTransactions?.length - 1
            ]?.Status === 'CREATED' ? (
            <Status type="updating" isLabel={true} className="pf-u-mt-sm" />
          ) : imageData?.Device?.UpdateAvailable ? (
            <Status
              type="updateAvailable"
              isLabel={true}
              className="pf-u-mt-sm"
            />
          ) : (
            <Status type="running" isLabel={true} className="pf-u-mt-sm" />
          )}
        </PageHeader>
        <Grid gutter="md">
          <GridItem span={12}>
            <DeviceDetailTabs
              systemProfile={imageData}
              imageId={imageId}
              setUpdateModal={setUpdateModal}
              setReload={setReload}
            />
          </GridItem>
        </Grid>
        {updateModal.isOpen && (
          <Suspense
            fallback={
              <Bullseye>
                <Spinner />
              </Bullseye>
            }
          >
            <UpdateDeviceModal
              navigateBack={() => {
                history.push({ pathname: history.location.pathname });
                setUpdateModal((prevState) => {
                  return {
                    ...prevState,
                    isOpen: false,
                  };
                });
              }}
              setUpdateModal={setUpdateModal}
              updateModal={updateModal}
              refreshTable={() => setReload(true)}
            />
          </Suspense>
        )}
      </DetailWrapper>
    </>
  );
}