mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
clean(archive): reuse list-component from feature to diplay list of archives
This commit is contained in:
parent
e962a38f0b
commit
477768c81d
@ -1,5 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly with no archived toggles 1`] = `
|
||||
<react-mdl-Card
|
||||
className="fullwidth"
|
||||
shadow={0}
|
||||
>
|
||||
<hr />
|
||||
<react-mdl-List>
|
||||
<react-mdl-ListItem
|
||||
twoLine={true}
|
||||
>
|
||||
<span
|
||||
className="listItemMetric"
|
||||
>
|
||||
<svg
|
||||
className="mdl-color-text--grey-300"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M17.3,18C19,16.5 20,14.4 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12C4,14.4 5,16.5 6.7,18C8.2,16.7 10,16 12,16C14,16 15.9,16.7 17.3,18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M7,9A1,1 0 0,1 8,10A1,1 0 0,1 7,11A1,1 0 0,1 6,10A1,1 0 0,1 7,9M10,6A1,1 0 0,1 11,7A1,1 0 0,1 10,8A1,1 0 0,1 9,7A1,1 0 0,1 10,6M17,9A1,1 0 0,1 18,10A1,1 0 0,1 17,11A1,1 0 0,1 16,10A1,1 0 0,1 17,9M14.4,6.1C14.9,6.3 15.1,6.9 15,7.4L13.6,10.8C13.8,11.1 14,11.5 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12C10,11 10.7,10.1 11.7,10L13.1,6.7C13.3,6.1 13.9,5.9 14.4,6.1Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span />
|
||||
<span
|
||||
className="mdl-list__item-primary-content listItemLink"
|
||||
>
|
||||
<a
|
||||
className="listLink truncate"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
adin-pay-confirm-disabled
|
||||
<span
|
||||
className="mdl-list__item-sub-title truncate"
|
||||
>
|
||||
Disables the confirm-functionality from API
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="listItemStrategies hideLt920"
|
||||
>
|
||||
<react-mdl-Chip
|
||||
className="strategyChip"
|
||||
>
|
||||
default
|
||||
</react-mdl-Chip>
|
||||
</span>
|
||||
<span />
|
||||
</react-mdl-ListItem>
|
||||
<react-mdl-ListItem
|
||||
twoLine={true}
|
||||
>
|
||||
<span
|
||||
className="listItemMetric"
|
||||
>
|
||||
<svg
|
||||
className="mdl-color-text--grey-300"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M17.3,18C19,16.5 20,14.4 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12C4,14.4 5,16.5 6.7,18C8.2,16.7 10,16 12,16C14,16 15.9,16.7 17.3,18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M7,9A1,1 0 0,1 8,10A1,1 0 0,1 7,11A1,1 0 0,1 6,10A1,1 0 0,1 7,9M10,6A1,1 0 0,1 11,7A1,1 0 0,1 10,8A1,1 0 0,1 9,7A1,1 0 0,1 10,6M17,9A1,1 0 0,1 18,10A1,1 0 0,1 17,11A1,1 0 0,1 16,10A1,1 0 0,1 17,9M14.4,6.1C14.9,6.3 15.1,6.9 15,7.4L13.6,10.8C13.8,11.1 14,11.5 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12C10,11 10.7,10.1 11.7,10L13.1,6.7C13.3,6.1 13.9,5.9 14.4,6.1Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span />
|
||||
<span
|
||||
className="mdl-list__item-primary-content listItemLink"
|
||||
>
|
||||
<a
|
||||
className="listLink truncate"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
adin-pay-platform-sch-payment
|
||||
<span
|
||||
className="mdl-list__item-sub-title truncate"
|
||||
>
|
||||
Enables use of schibsted payment from order-payment-management
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="listItemStrategies hideLt920"
|
||||
>
|
||||
<react-mdl-Chip
|
||||
className="strategyChip"
|
||||
>
|
||||
default
|
||||
</react-mdl-Chip>
|
||||
</span>
|
||||
<span />
|
||||
</react-mdl-ListItem>
|
||||
</react-mdl-List>
|
||||
</react-mdl-Card>
|
||||
`;
|
@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import ArchiveList from '../archive-list-component';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
// TODO mock DropdownButton
|
||||
// jest.mock('../../common', () => ({ DropdownButton: 'DropdownButton', styles: {} }));
|
||||
const archive = [
|
||||
{
|
||||
name: 'adin-pay-confirm-disabled',
|
||||
description: 'Disables the confirm-functionality from API',
|
||||
enabled: false,
|
||||
strategies: [{ name: 'default', parameters: {} }],
|
||||
createdAt: '2016-10-25T15:38:28.573Z',
|
||||
reviveName: 'adin-pay-confirm-disabled',
|
||||
},
|
||||
{
|
||||
name: 'adin-pay-platform-sch-payment',
|
||||
description: 'Enables use of schibsted payment from order-payment-management',
|
||||
enabled: true,
|
||||
strategies: [{ name: 'default', parameters: {} }],
|
||||
createdAt: '2016-08-03T12:41:35.631Z',
|
||||
reviveName: 'adin-pay-platform-sch-payment',
|
||||
},
|
||||
];
|
||||
|
||||
xtest('renders correctly with no archived toggles', () => {
|
||||
const featureMetrics = { lastHour: {}, lastMinute: {}, seenApps: {} };
|
||||
const settings = {
|
||||
feature: {
|
||||
filter: '',
|
||||
sort: 'name',
|
||||
showLastHour: false,
|
||||
},
|
||||
};
|
||||
|
||||
const tree = renderer
|
||||
.create(
|
||||
<ArchiveList
|
||||
name={'ff'}
|
||||
fetchArchive={jest.fn()}
|
||||
archive={[]}
|
||||
settings={settings}
|
||||
featureMetrics={featureMetrics}
|
||||
/>
|
||||
)
|
||||
.toJSON();
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
xtest('renders correctly with archived toggles', () => {
|
||||
const featureMetrics = { lastHour: {}, lastMinute: {}, seenApps: {} };
|
||||
const settings = {
|
||||
feature: {
|
||||
filter: '',
|
||||
sort: 'name',
|
||||
showLastHour: false,
|
||||
},
|
||||
};
|
||||
|
||||
const tree = renderer
|
||||
.create(
|
||||
<ArchiveList
|
||||
name={'ff'}
|
||||
fetchArchive={jest.fn()}
|
||||
archive={archive}
|
||||
settings={settings}
|
||||
featureMetrics={featureMetrics}
|
||||
/>
|
||||
)
|
||||
.toJSON();
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
@ -1,142 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router';
|
||||
import Feature from './../feature/feature-list-item-component';
|
||||
import { CardActions, Menu, MenuItem, Icon, Card, List, Chip } from 'react-mdl';
|
||||
import { MenuItemWithIcon, DropdownButton, styles } from '../common';
|
||||
// import styles from './archive.scss';
|
||||
|
||||
class ArchiveList extends React.PureComponent {
|
||||
static propTypes = {
|
||||
name: PropTypes.string,
|
||||
archive: PropTypes.array.isRequired,
|
||||
fetchArchive: PropTypes.func,
|
||||
featureMetrics: PropTypes.object,
|
||||
updateSetting: PropTypes.func,
|
||||
settings: PropTypes.object,
|
||||
revive: PropTypes.func,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchArchive();
|
||||
}
|
||||
setSort(v) {
|
||||
this.props.updateSetting('sort', typeof v === 'string' ? v.trim() : '');
|
||||
}
|
||||
toggleMetrics() {
|
||||
this.props.updateSetting('showLastHour', !this.props.settings.showLastHour);
|
||||
}
|
||||
renderStrategyDetail(feature) {
|
||||
let strategiesList = (
|
||||
<span>
|
||||
{feature.strategies.map((s, i) => (
|
||||
<span style={{ marginLeft: `8px` }} key={i}>
|
||||
<strong>{s.name}</strong>
|
||||
{Object.keys(s.parameters).map((p, j) => <i key={j}> {s.parameters[p]}</i>)}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
|
||||
return strategiesList;
|
||||
}
|
||||
renderStrategiesInList(feature) {
|
||||
let display = [];
|
||||
if (feature.strategies && feature.strategies.length > 0) {
|
||||
const strategiesToShow = Math.min(feature.strategies.length, 3);
|
||||
const remainingStrategies = feature.strategies.length - strategiesToShow;
|
||||
|
||||
const strategyChips =
|
||||
feature.strategies &&
|
||||
feature.strategies.slice(0, strategiesToShow).map((s, i) => (
|
||||
<span key={i} className={[styles.strategiesList, styles.hideLt920].join(' ')}>
|
||||
<Chip className={styles.strategyChip}>{s.name}</Chip>
|
||||
</span>
|
||||
));
|
||||
const remaining = (
|
||||
<span className={[styles.strategiesList, styles.hideLt920].join(' ')}>
|
||||
<Chip className={styles.strategyChip}>+{remainingStrategies}</Chip>
|
||||
</span>
|
||||
);
|
||||
if (remainingStrategies > 0) {
|
||||
display.push(remaining);
|
||||
}
|
||||
display.push(strategyChips);
|
||||
}
|
||||
return display;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { archive, featureMetrics, settings, revive } = this.props;
|
||||
|
||||
archive.forEach(e => {
|
||||
e.reviveName = e.name;
|
||||
});
|
||||
return (
|
||||
<Card shadow={0} className={styles.fullwidth}>
|
||||
<CardActions>
|
||||
<DropdownButton id="metric" label={`Last ${settings.showLastHour ? 'hour' : 'minute'}`} />
|
||||
<Menu target="metric" onClick={() => this.toggleMetrics()} style={{ width: '168px' }}>
|
||||
<MenuItemWithIcon
|
||||
icon="hourglass_empty"
|
||||
disabled={!settings.showLastHour}
|
||||
data-target="minute"
|
||||
label="Last minute"
|
||||
/>
|
||||
<MenuItemWithIcon
|
||||
icon="hourglass_full"
|
||||
disabled={settings.showLastHour}
|
||||
data-target="hour"
|
||||
label="Last hour"
|
||||
/>
|
||||
</Menu>
|
||||
<DropdownButton id="sorting" label={`By ${settings.sort}`} />
|
||||
<Menu
|
||||
target="sorting"
|
||||
onClick={e => this.setSort(e.target.getAttribute('data-target'))}
|
||||
style={{ width: '168px' }}
|
||||
>
|
||||
<MenuItem disabled={settings.sort === 'name'} data-target="name">
|
||||
Name
|
||||
</MenuItem>
|
||||
<MenuItem disabled={settings.sort === 'enabled'} data-target="enabled">
|
||||
Enabled
|
||||
</MenuItem>
|
||||
<MenuItem disabled={settings.sort === 'created'} data-target="created">
|
||||
Created
|
||||
</MenuItem>
|
||||
<MenuItem disabled={settings.sort === 'strategies'} data-target="strategies">
|
||||
Strategies
|
||||
</MenuItem>
|
||||
<MenuItem disabled={settings.sort === 'metrics'} data-target="metrics">
|
||||
Metrics
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</CardActions>
|
||||
<hr />
|
||||
{archive && archive.length > 0 ? (
|
||||
<List>
|
||||
{archive.map((feature, i) => (
|
||||
<Feature
|
||||
key={i}
|
||||
settings={settings}
|
||||
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
||||
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
||||
feature={feature}
|
||||
revive={revive}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
) : (
|
||||
<div className={styles.emptyState}>
|
||||
<Icon name="archive" className="mdl-color-text--grey-300" style={{ fontSize: '56px' }} />
|
||||
<br />
|
||||
No archived feature toggles, go see <Link to="/features">active toggles here</Link>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ArchiveList;
|
@ -1,5 +1,5 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ArchiveList from './archive-list-component';
|
||||
import FeatureListComponent from './../feature/list-component';
|
||||
import { fetchArchive, revive } from './../../store/archive-actions';
|
||||
import { updateSettingForGroup } from './../../store/settings/actions';
|
||||
|
||||
@ -63,7 +63,7 @@ const mapStateToProps = state => {
|
||||
}
|
||||
|
||||
return {
|
||||
archive: features,
|
||||
features,
|
||||
featureMetrics,
|
||||
settings,
|
||||
};
|
||||
@ -75,6 +75,6 @@ const mapDispatchToProps = {
|
||||
updateSetting: updateSettingForGroup('feature'),
|
||||
};
|
||||
|
||||
const ArchiveListContainer = connect(mapStateToProps, mapDispatchToProps)(ArchiveList);
|
||||
const ArchiveListContainer = connect(mapStateToProps, mapDispatchToProps)(FeatureListComponent);
|
||||
|
||||
export default ArchiveListContainer;
|
||||
|
@ -7,11 +7,13 @@ import { Icon, FABButton, Textfield, Menu, MenuItem, Card, CardActions, List } f
|
||||
import { MenuItemWithIcon, DropdownButton, styles as commonStyles } from '../common';
|
||||
import styles from './feature.scss';
|
||||
|
||||
export default class FeatureListComponent extends React.PureComponent {
|
||||
export default class FeatureListComponent extends React.Component {
|
||||
static propTypes = {
|
||||
features: PropTypes.array.isRequired,
|
||||
featureMetrics: PropTypes.object.isRequired,
|
||||
fetchFeatureToggles: PropTypes.func.isRequired,
|
||||
fetchFeatureToggles: PropTypes.func,
|
||||
fetchArchive: PropTypes.func,
|
||||
revive: PropTypes.func,
|
||||
updateSetting: PropTypes.func.isRequired,
|
||||
toggleFeature: PropTypes.func,
|
||||
settings: PropTypes.object,
|
||||
@ -22,7 +24,11 @@ export default class FeatureListComponent extends React.PureComponent {
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchFeatureToggles();
|
||||
if (this.props.fetchFeatureToggles) {
|
||||
this.props.fetchFeatureToggles();
|
||||
} else {
|
||||
this.props.fetchArchive();
|
||||
}
|
||||
}
|
||||
|
||||
toggleMetrics() {
|
||||
@ -38,8 +44,10 @@ export default class FeatureListComponent extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { features, toggleFeature, featureMetrics, settings } = this.props;
|
||||
|
||||
const { features, toggleFeature, featureMetrics, settings, revive } = this.props;
|
||||
features.forEach(e => {
|
||||
e.reviveName = e.name;
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.toolbar}>
|
||||
@ -107,7 +115,7 @@ export default class FeatureListComponent extends React.PureComponent {
|
||||
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
||||
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
||||
feature={feature}
|
||||
toggleFeature={toggleFeature}
|
||||
revive={revive}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
|
Loading…
Reference in New Issue
Block a user