2017-08-28 21:30:12 +02:00
|
|
|
import React from 'react';
|
2018-02-04 14:32:33 +01:00
|
|
|
import PropTypes from 'prop-types';
|
2018-08-06 22:16:36 +02:00
|
|
|
import { Link } from 'react-router-dom';
|
2021-03-30 15:14:02 +02:00
|
|
|
import {
|
|
|
|
List,
|
|
|
|
MenuItem,
|
|
|
|
Icon,
|
|
|
|
ListItem,
|
|
|
|
ListItemText,
|
|
|
|
ListItemAvatar,
|
|
|
|
Button,
|
|
|
|
Avatar,
|
|
|
|
Typography,
|
2022-05-02 15:52:41 +02:00
|
|
|
} from '@mui/material';
|
|
|
|
import { Apps } from '@mui/icons-material';
|
2021-06-29 10:21:54 +02:00
|
|
|
|
2021-01-07 13:36:13 +01:00
|
|
|
import styles from './common.module.scss';
|
2022-05-02 12:52:33 +02:00
|
|
|
import { ConditionallyRender } from './ConditionallyRender/ConditionallyRender';
|
2016-12-09 22:11:05 +01:00
|
|
|
|
2017-01-04 00:29:27 +01:00
|
|
|
export { styles };
|
|
|
|
|
2016-12-09 22:11:05 +01:00
|
|
|
export const AppsLinkList = ({ apps }) => (
|
2017-02-14 12:11:18 +01:00
|
|
|
<List>
|
2021-03-30 15:14:02 +02:00
|
|
|
<ConditionallyRender
|
|
|
|
condition={apps.length > 0}
|
|
|
|
show={apps.map(({ appName, description, icon }) => (
|
|
|
|
<ListItem key={appName} className={styles.listItem}>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar>
|
|
|
|
<ConditionallyRender
|
|
|
|
key={`avatar_conditional_${appName}`}
|
|
|
|
condition={icon}
|
|
|
|
show={<Icon>{icon}</Icon>}
|
2021-06-29 10:21:54 +02:00
|
|
|
elseShow={<Apps />}
|
2021-03-30 15:14:02 +02:00
|
|
|
/>
|
|
|
|
</Avatar>
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
|
|
|
primary={
|
|
|
|
<Link
|
2022-09-30 15:53:02 +02:00
|
|
|
to={`/applications/${encodeURIComponent(
|
|
|
|
appName
|
|
|
|
)}`}
|
2021-04-12 15:04:03 +02:00
|
|
|
className={[
|
|
|
|
styles.listLink,
|
|
|
|
styles.truncate,
|
|
|
|
].join(' ')}
|
2021-03-30 15:14:02 +02:00
|
|
|
>
|
|
|
|
{appName}
|
|
|
|
</Link>
|
|
|
|
}
|
|
|
|
secondary={description || 'No description'}
|
|
|
|
/>
|
2017-08-28 19:15:47 +02:00
|
|
|
</ListItem>
|
|
|
|
))}
|
2021-03-30 15:14:02 +02:00
|
|
|
/>
|
2016-12-09 22:11:05 +01:00
|
|
|
</List>
|
|
|
|
);
|
2018-02-04 14:32:33 +01:00
|
|
|
AppsLinkList.propTypes = {
|
|
|
|
apps: PropTypes.array.isRequired,
|
|
|
|
};
|
2016-12-09 22:11:05 +01:00
|
|
|
|
2017-01-26 11:53:07 +01:00
|
|
|
export const DataTableHeader = ({ title, actions }) => (
|
|
|
|
<div className={styles.dataTableHeader}>
|
|
|
|
<div className={styles.title}>
|
2021-03-30 15:14:02 +02:00
|
|
|
<Typography variant="h2" className={styles.titleText}>
|
|
|
|
{title}
|
|
|
|
</Typography>
|
2017-01-26 11:53:07 +01:00
|
|
|
</div>
|
2017-08-28 19:15:47 +02:00
|
|
|
{actions && <div className={styles.actions}>{actions}</div>}
|
2017-01-26 11:53:07 +01:00
|
|
|
</div>
|
|
|
|
);
|
2018-02-04 14:32:33 +01:00
|
|
|
DataTableHeader.propTypes = {
|
|
|
|
title: PropTypes.string,
|
|
|
|
actions: PropTypes.any,
|
|
|
|
};
|
2017-01-26 11:53:07 +01:00
|
|
|
|
2021-04-12 15:04:03 +02:00
|
|
|
export const FormButtons = ({
|
|
|
|
submitText = 'Create',
|
|
|
|
onCancel,
|
|
|
|
primaryButtonTestId,
|
|
|
|
}) => (
|
2016-12-10 11:47:25 +01:00
|
|
|
<div>
|
2021-03-30 15:14:02 +02:00
|
|
|
<Button
|
2022-04-08 13:13:45 +02:00
|
|
|
data-testid={primaryButtonTestId}
|
2021-03-30 15:14:02 +02:00
|
|
|
type="submit"
|
|
|
|
color="primary"
|
|
|
|
variant="contained"
|
|
|
|
>
|
2017-08-28 19:15:47 +02:00
|
|
|
{submitText}
|
2016-12-10 11:47:25 +01:00
|
|
|
</Button>
|
|
|
|
|
2020-02-27 21:36:07 +01:00
|
|
|
<Button type="cancel" onClick={onCancel}>
|
|
|
|
Cancel
|
2016-12-10 11:47:25 +01:00
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
);
|
2018-02-04 14:32:33 +01:00
|
|
|
FormButtons.propTypes = {
|
|
|
|
submitText: PropTypes.string,
|
|
|
|
onCancel: PropTypes.func.isRequired,
|
2021-03-30 15:14:02 +02:00
|
|
|
primaryButtonTestId: PropTypes.string,
|
2018-02-04 14:32:33 +01:00
|
|
|
};
|
2016-12-10 14:02:41 +01:00
|
|
|
|
2021-06-29 10:21:54 +02:00
|
|
|
export const IconLink = ({ url, icon: IconComponent }) => (
|
2021-04-12 15:04:03 +02:00
|
|
|
<a
|
|
|
|
href={url}
|
|
|
|
target="_blank"
|
|
|
|
rel="noreferrer"
|
|
|
|
className="mdl-color-text--grey-600"
|
|
|
|
>
|
2021-06-29 10:21:54 +02:00
|
|
|
<IconComponent />
|
2016-12-10 15:10:03 +01:00
|
|
|
</a>
|
|
|
|
);
|
2018-02-04 14:32:33 +01:00
|
|
|
IconLink.propTypes = {
|
|
|
|
url: PropTypes.string,
|
2021-06-29 10:21:54 +02:00
|
|
|
icon: PropTypes.object,
|
2018-02-04 14:32:33 +01:00
|
|
|
};
|
2016-12-10 15:10:03 +01:00
|
|
|
|
2021-06-29 10:21:54 +02:00
|
|
|
export const MenuItemWithIcon = React.forwardRef(
|
|
|
|
({ icon: IconComponent, label, disabled, ...menuItemProps }, ref) => (
|
|
|
|
<MenuItem
|
|
|
|
disabled={disabled}
|
|
|
|
style={{ display: 'flex', alignItems: 'center' }}
|
|
|
|
{...menuItemProps}
|
|
|
|
>
|
|
|
|
<IconComponent />
|
|
|
|
{label}
|
|
|
|
</MenuItem>
|
|
|
|
)
|
2017-02-04 19:30:06 +01:00
|
|
|
);
|
2018-02-04 14:32:33 +01:00
|
|
|
MenuItemWithIcon.propTypes = {
|
2021-06-29 10:21:54 +02:00
|
|
|
icon: PropTypes.object,
|
2018-02-04 14:32:33 +01:00
|
|
|
label: PropTypes.string,
|
|
|
|
disabled: PropTypes.bool,
|
|
|
|
};
|
2017-02-04 19:30:06 +01:00
|
|
|
|
2016-12-17 20:54:48 +01:00
|
|
|
const badNumbers = [NaN, Infinity, -Infinity];
|
2017-08-28 19:15:47 +02:00
|
|
|
export function calc(value, total, decimal) {
|
2021-04-12 15:04:03 +02:00
|
|
|
if (
|
|
|
|
typeof value !== 'number' ||
|
|
|
|
typeof total !== 'number' ||
|
|
|
|
typeof decimal !== 'number'
|
|
|
|
) {
|
2016-12-17 20:54:48 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (total === 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
badNumbers.forEach(number => {
|
2016-12-17 20:54:48 +01:00
|
|
|
if ([value, total, decimal].indexOf(number) > -1) {
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-10-09 19:58:49 +02:00
|
|
|
return ((value / total) * 100).toFixed(decimal);
|
2017-02-23 22:18:23 +01:00
|
|
|
}
|
2021-02-24 11:03:18 +01:00
|
|
|
|
|
|
|
export const selectStyles = {
|
|
|
|
control: provided => ({
|
|
|
|
...provided,
|
|
|
|
border: '1px solid #607d8b',
|
|
|
|
boxShadow: '0',
|
|
|
|
':hover': {
|
|
|
|
borderColor: '#607d8b',
|
|
|
|
boxShadow: '0 0 0 1px #607d8b',
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
};
|