1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00
unleash.unleash/frontend/src/component/common/index.js

188 lines
5.7 KiB
JavaScript
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
2017-08-28 21:40:44 +02:00
import { List, ListItem, ListItemContent, Button, Icon, Switch, MenuItem } from 'react-mdl';
import styles from './common.module.scss';
2016-12-09 22:11:05 +01:00
export { styles };
2017-08-28 21:40:44 +02:00
export const shorten = (str, len = 50) => (str && str.length > len ? `${str.substring(0, len)}...` : str);
2016-12-10 15:39:03 +01:00
2016-12-09 22:11:05 +01:00
export const AppsLinkList = ({ apps }) => (
<List>
{apps.length > 0 &&
2020-09-24 19:31:49 +02:00
apps.map(({ appName, description, icon }) => (
<ListItem twoLine key={appName}>
2017-08-28 21:40:44 +02:00
<span className="mdl-list__item-primary-content" style={{ minWidth: 0 }}>
<Icon name={icon || 'apps'} className="mdl-list__item-avatar" />
2017-08-28 21:40:44 +02:00
<Link to={`/applications/${appName}`} className={[styles.listLink, styles.truncate].join(' ')}>
{appName}
2017-08-28 21:40:44 +02:00
<span className={['mdl-list__item-sub-title', styles.truncate].join(' ')}>
2020-10-02 11:05:29 +02:00
{description || 'No description'}
</span>
</Link>
</span>
</ListItem>
))}
2016-12-09 22:11:05 +01:00
</List>
);
AppsLinkList.propTypes = {
apps: PropTypes.array.isRequired,
};
2016-12-09 22:11:05 +01:00
export const HeaderTitle = ({ title, actions, subtitle }) => (
<div
style={{
display: 'flex',
borderBottom: '1px solid #f1f1f1',
marginBottom: '10px',
padding: '16px 20px ',
}}
>
2017-06-29 08:36:10 +02:00
<div style={{ flex: '2' }}>
<h6 style={{ margin: 0 }}>{title}</h6>
{subtitle && <small>{subtitle}</small>}
</div>
2016-12-10 12:21:27 +01:00
2017-08-28 21:40:44 +02:00
{actions && <div style={{ flex: '1', textAlign: 'right' }}>{actions}</div>}
2016-12-10 12:21:27 +01:00
</div>
);
HeaderTitle.propTypes = {
title: PropTypes.string,
subtitle: PropTypes.string,
actions: PropTypes.any,
};
export const DataTableHeader = ({ title, actions }) => (
<div className={styles.dataTableHeader}>
<div className={styles.title}>
<h2 className={styles.titleText}>{title}</h2>
</div>
{actions && <div className={styles.actions}>{actions}</div>}
</div>
);
DataTableHeader.propTypes = {
title: PropTypes.string,
actions: PropTypes.any,
};
export const FormButtons = ({ submitText = 'Create', onCancel }) => (
<div>
<Button type="submit" ripple raised primary icon="add">
2019-03-13 08:58:00 +01:00
<Icon name="add" />
&nbsp;&nbsp;&nbsp;
{submitText}
</Button>
&nbsp;
<Button type="cancel" onClick={onCancel}>
Cancel
</Button>
</div>
);
FormButtons.propTypes = {
submitText: PropTypes.string,
onCancel: PropTypes.func.isRequired,
};
2016-12-10 12:21:27 +01:00
2017-08-28 21:40:44 +02:00
export const SwitchWithLabel = ({ onChange, checked, children, ...switchProps }) => (
<span className={styles.switchWithLabel}>
<span className={styles.label}>{children}</span>
<span className={styles.switch}>
<Switch checked={checked} onChange={onChange} {...switchProps} />
2016-12-10 12:21:27 +01:00
</span>
</span>
);
SwitchWithLabel.propTypes = {
checked: PropTypes.bool,
onChange: PropTypes.func,
};
2016-12-10 12:21:27 +01:00
2016-12-10 13:49:22 +01:00
export const TogglesLinkList = ({ toggles }) => (
<List style={{ textAlign: 'left' }} className={styles.truncate}>
{toggles.length > 0 &&
toggles.map(({ name, description = '-', icon = 'toggle' }) => (
<ListItem twoLine key={name}>
<ListItemContent avatar={icon} subtitle={description}>
<Link key={name} to={`/features/view/${name}`}>
{name}
</Link>
</ListItemContent>
</ListItem>
))}
2016-12-10 13:49:22 +01:00
</List>
);
TogglesLinkList.propTypes = {
toggles: PropTypes.array,
};
2016-12-10 14:02:41 +01:00
export function getIcon(type) {
2016-12-10 14:02:41 +01:00
switch (type) {
case 'feature-updated':
return 'autorenew';
case 'feature-created':
return 'add';
case 'feature-deleted':
return 'remove';
case 'feature-archived':
return 'archived';
default:
return 'star';
2016-12-10 14:02:41 +01:00
}
}
2016-12-10 15:10:03 +01:00
export const IconLink = ({ url, icon }) => (
2017-08-28 21:40:44 +02:00
<a href={url} target="_blank" rel="noopener" className="mdl-color-text--grey-600">
<Icon name={icon} />
2016-12-10 15:10:03 +01:00
</a>
);
IconLink.propTypes = {
url: PropTypes.string,
icon: PropTypes.string,
};
2016-12-10 15:10:03 +01:00
2020-11-20 15:35:41 +01:00
export const DropdownButton = ({ label, id, className, title }) => (
<Button id={id} className={[className, styles.dropdownButton].join(' ')} title={title}>
{label}
<Icon name="arrow_drop_down" className="mdl-color-text--grey-600" />
</Button>
);
DropdownButton.propTypes = {
label: PropTypes.string,
id: PropTypes.string,
2020-11-20 15:35:41 +01:00
title: PropTypes.string,
};
2017-08-28 21:40:44 +02:00
export const MenuItemWithIcon = ({ icon, label, disabled, ...menuItemProps }) => (
<MenuItem disabled={disabled} style={{ display: 'flex', alignItems: 'center' }} {...menuItemProps}>
<Icon name={icon} style={{ paddingRight: '16px' }} />
{label}
</MenuItem>
);
MenuItemWithIcon.propTypes = {
icon: PropTypes.string,
label: PropTypes.string,
disabled: PropTypes.bool,
};
const badNumbers = [NaN, Infinity, -Infinity];
export function calc(value, total, decimal) {
2017-08-28 21:40:44 +02:00
if (typeof value !== 'number' || typeof total !== 'number' || typeof decimal !== 'number') {
return null;
}
if (total === 0) {
return 0;
}
badNumbers.forEach(number => {
if ([value, total, decimal].indexOf(number) > -1) {
return number;
}
});
return ((value / total) * 100).toFixed(decimal);
2017-02-23 22:18:23 +01:00
}
export function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
2018-02-16 21:18:20 +01:00
}