@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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Loading = () => {
return (
<Bullseye>
<Spinner />
</Bullseye>
);
}
Example #10
Source File: Routes.js From edge-frontend with Apache License 2.0 | 5 votes |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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>
</>
);
}