mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-08 01:15:49 +02:00
Merge pull request #221 from Unleash/feat/stale-flag
This commit is contained in:
commit
99514009bb
@ -38,7 +38,8 @@
|
|||||||
"prepublish": "npm run build"
|
"prepublish": "npm run build"
|
||||||
},
|
},
|
||||||
"main": "./index.js",
|
"main": "./index.js",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.9.0",
|
"@babel/core": "^7.9.0",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||||
@ -84,6 +85,7 @@
|
|||||||
"react-redux": "^7.2.0",
|
"react-redux": "^7.2.0",
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-select": "^3.1.0",
|
"react-select": "^3.1.0",
|
||||||
|
"react-timeago": "^4.4.0",
|
||||||
"react-test-renderer": "^16.13.1",
|
"react-test-renderer": "^16.13.1",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-devtools": "^3.5.0",
|
"redux-devtools": "^3.5.0",
|
||||||
|
@ -81,3 +81,8 @@
|
|||||||
text-transform: none;
|
text-transform: none;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggleName {
|
||||||
|
color: #37474f !important;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
@ -140,8 +140,8 @@ IconLink.propTypes = {
|
|||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DropdownButton = ({ label, id }) => (
|
export const DropdownButton = ({ label, id, className }) => (
|
||||||
<Button id={id} className={styles.dropdownButton}>
|
<Button id={id} className={className || styles.dropdownButton}>
|
||||||
{label}
|
{label}
|
||||||
<Icon name="arrow_drop_down" className="mdl-color-text--grey-600" />
|
<Icon name="arrow_drop_down" className="mdl-color-text--grey-600" />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -35,7 +35,22 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
href="/features/strategies/Another"
|
href="/features/strategies/Another"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
>
|
>
|
||||||
Another
|
<span
|
||||||
|
className="toggleName"
|
||||||
|
>
|
||||||
|
Another
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<small
|
||||||
|
className="mdl-color-text--blue-grey-300"
|
||||||
|
>
|
||||||
|
<time
|
||||||
|
dateTime="2018-02-04T20:27:52.127Z"
|
||||||
|
title="2018-02-04T20:27:52.127Z"
|
||||||
|
>
|
||||||
|
3 years ago
|
||||||
|
</time>
|
||||||
|
</small>
|
||||||
<span
|
<span
|
||||||
className="mdl-list__item-sub-title truncate"
|
className="mdl-list__item-sub-title truncate"
|
||||||
>
|
>
|
||||||
@ -47,7 +62,7 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
className="listItemStrategies hideLt920"
|
className="listItemStrategies hideLt920"
|
||||||
>
|
>
|
||||||
<react-mdl-Chip
|
<react-mdl-Chip
|
||||||
className="mdl-color--blue-grey-100"
|
className="typeChip"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span />
|
<span />
|
||||||
@ -88,7 +103,22 @@ exports[`renders correctly with one feature without permission 1`] = `
|
|||||||
href="/features/strategies/Another"
|
href="/features/strategies/Another"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
>
|
>
|
||||||
Another
|
<span
|
||||||
|
className="toggleName"
|
||||||
|
>
|
||||||
|
Another
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<small
|
||||||
|
className="mdl-color-text--blue-grey-300"
|
||||||
|
>
|
||||||
|
<time
|
||||||
|
dateTime="2018-02-04T20:27:52.127Z"
|
||||||
|
title="2018-02-04T20:27:52.127Z"
|
||||||
|
>
|
||||||
|
3 years ago
|
||||||
|
</time>
|
||||||
|
</small>
|
||||||
<span
|
<span
|
||||||
className="mdl-list__item-sub-title truncate"
|
className="mdl-list__item-sub-title truncate"
|
||||||
>
|
>
|
||||||
@ -100,7 +130,7 @@ exports[`renders correctly with one feature without permission 1`] = `
|
|||||||
className="listItemStrategies hideLt920"
|
className="listItemStrategies hideLt920"
|
||||||
>
|
>
|
||||||
<react-mdl-Chip
|
<react-mdl-Chip
|
||||||
className="mdl-color--blue-grey-100"
|
className="typeChip"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span />
|
<span />
|
||||||
|
@ -136,6 +136,12 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
>
|
>
|
||||||
Enabled
|
Enabled
|
||||||
</react-mdl-MenuItem>
|
</react-mdl-MenuItem>
|
||||||
|
<react-mdl-MenuItem
|
||||||
|
data-target="stale"
|
||||||
|
disabled={false}
|
||||||
|
>
|
||||||
|
Stale
|
||||||
|
</react-mdl-MenuItem>
|
||||||
<react-mdl-MenuItem
|
<react-mdl-MenuItem
|
||||||
data-target="created"
|
data-target="created"
|
||||||
disabled={false}
|
disabled={false}
|
||||||
@ -301,6 +307,12 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
>
|
>
|
||||||
Enabled
|
Enabled
|
||||||
</react-mdl-MenuItem>
|
</react-mdl-MenuItem>
|
||||||
|
<react-mdl-MenuItem
|
||||||
|
data-target="stale"
|
||||||
|
disabled={false}
|
||||||
|
>
|
||||||
|
Stale
|
||||||
|
</react-mdl-MenuItem>
|
||||||
<react-mdl-MenuItem
|
<react-mdl-MenuItem
|
||||||
data-target="created"
|
data-target="created"
|
||||||
disabled={false}
|
disabled={false}
|
||||||
|
@ -10,6 +10,19 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<react-mdl-Chip
|
||||||
|
className="mdl-color--light-green-500 mdl-color-text--white mdl-shadow--2dp"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"position": "absolute",
|
||||||
|
"right": "4px",
|
||||||
|
"top": "4px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
title="Feature toggle is active."
|
||||||
|
>
|
||||||
|
Active
|
||||||
|
</react-mdl-Chip>
|
||||||
<react-mdl-CardTitle
|
<react-mdl-CardTitle
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
@ -73,6 +86,39 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
</react-mdl-Switch>
|
</react-mdl-Switch>
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
|
<span>
|
||||||
|
<react-mdl-Button
|
||||||
|
className="mdl-button"
|
||||||
|
id="update_status"
|
||||||
|
>
|
||||||
|
Status
|
||||||
|
<react-mdl-Icon
|
||||||
|
className="mdl-color-text--grey-600"
|
||||||
|
name="arrow_drop_down"
|
||||||
|
/>
|
||||||
|
</react-mdl-Button>
|
||||||
|
<react-mdl-Menu
|
||||||
|
onClick={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"width": "168px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target="update_status"
|
||||||
|
>
|
||||||
|
<react-mdl-MenuItem
|
||||||
|
data-target="active"
|
||||||
|
disabled={true}
|
||||||
|
>
|
||||||
|
Set toggle Active
|
||||||
|
</react-mdl-MenuItem>
|
||||||
|
<react-mdl-MenuItem
|
||||||
|
data-target="stale"
|
||||||
|
>
|
||||||
|
Mark toggle as Stale
|
||||||
|
</react-mdl-MenuItem>
|
||||||
|
</react-mdl-Menu>
|
||||||
|
</span>
|
||||||
<a
|
<a
|
||||||
href="/features/copy/Another"
|
href="/features/copy/Another"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
|
@ -2,9 +2,11 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Switch, Chip, ListItem, ListItemAction, Icon } from 'react-mdl';
|
import { Switch, Chip, ListItem, ListItemAction, Icon } from 'react-mdl';
|
||||||
|
import TimeAgo from 'react-timeago';
|
||||||
import Progress from './progress';
|
import Progress from './progress';
|
||||||
import { UPDATE_FEATURE } from '../../permissions';
|
import { UPDATE_FEATURE } from '../../permissions';
|
||||||
import { calc, styles as commonStyles } from '../common';
|
import { calc, styles as commonStyles } from '../common';
|
||||||
|
import StatusComponent from './status-component';
|
||||||
|
|
||||||
import styles from './feature.scss';
|
import styles from './feature.scss';
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ const Feature = ({
|
|||||||
revive,
|
revive,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
}) => {
|
}) => {
|
||||||
const { name, description, enabled, type } = feature;
|
const { name, description, enabled, type, stale, createdAt } = feature;
|
||||||
const { showLastHour = false } = settings;
|
const { showLastHour = false } = settings;
|
||||||
const isStale = showLastHour ? metricsLastHour.isFallback : metricsLastMinute.isFallback;
|
const isStale = showLastHour ? metricsLastHour.isFallback : metricsLastMinute.isFallback;
|
||||||
const percent =
|
const percent =
|
||||||
@ -25,7 +27,6 @@ const Feature = ({
|
|||||||
(showLastHour
|
(showLastHour
|
||||||
? calc(metricsLastHour.yes, metricsLastHour.yes + metricsLastHour.no, 0)
|
? calc(metricsLastHour.yes, metricsLastHour.yes + metricsLastHour.no, 0)
|
||||||
: calc(metricsLastMinute.yes, metricsLastMinute.yes + metricsLastMinute.no, 0));
|
: calc(metricsLastMinute.yes, metricsLastMinute.yes + metricsLastMinute.no, 0));
|
||||||
const typeChip = <Chip className="mdl-color--blue-grey-100">{type}</Chip>;
|
|
||||||
const featureUrl = toggleFeature === undefined ? `/archive/strategies/${name}` : `/features/strategies/${name}`;
|
const featureUrl = toggleFeature === undefined ? `/archive/strategies/${name}` : `/features/strategies/${name}`;
|
||||||
return (
|
return (
|
||||||
<ListItem twoLine>
|
<ListItem twoLine>
|
||||||
@ -47,11 +48,17 @@ const Feature = ({
|
|||||||
</span>
|
</span>
|
||||||
<span className={['mdl-list__item-primary-content', styles.listItemLink].join(' ')}>
|
<span className={['mdl-list__item-primary-content', styles.listItemLink].join(' ')}>
|
||||||
<Link to={featureUrl} className={[commonStyles.listLink, commonStyles.truncate].join(' ')}>
|
<Link to={featureUrl} className={[commonStyles.listLink, commonStyles.truncate].join(' ')}>
|
||||||
{name}
|
<span className={commonStyles.toggleName}>{name} </span>
|
||||||
|
<small className="mdl-color-text--blue-grey-300">
|
||||||
|
<TimeAgo date={createdAt} />
|
||||||
|
</small>
|
||||||
<span className={['mdl-list__item-sub-title', commonStyles.truncate].join(' ')}>{description}</span>
|
<span className={['mdl-list__item-sub-title', commonStyles.truncate].join(' ')}>{description}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
<span className={[styles.listItemStrategies, commonStyles.hideLt920].join(' ')}>{typeChip}</span>
|
<span className={[styles.listItemStrategies, commonStyles.hideLt920].join(' ')}>
|
||||||
|
<StatusComponent stale={stale} showActive={false} />
|
||||||
|
<Chip className={styles.typeChip}>{type}</Chip>
|
||||||
|
</span>
|
||||||
{revive && hasPermission(UPDATE_FEATURE) ? (
|
{revive && hasPermission(UPDATE_FEATURE) ? (
|
||||||
<ListItemAction onClick={() => revive(feature.name)}>
|
<ListItemAction onClick={() => revive(feature.name)}>
|
||||||
<Icon name="undo" />
|
<Icon name="undo" />
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.typeChip {
|
.typeChip {
|
||||||
margin-left: 8px !important;
|
margin: 0 8px !important;
|
||||||
background: #d3c1ff;
|
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||||
|
background-color: #b0bec5 !important;
|
||||||
}
|
}
|
@ -111,6 +111,9 @@ export default class FeatureListComponent extends React.Component {
|
|||||||
<MenuItem disabled={settings.sort === 'enabled'} data-target="enabled">
|
<MenuItem disabled={settings.sort === 'enabled'} data-target="enabled">
|
||||||
Enabled
|
Enabled
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem disabled={settings.sort === 'stale'} data-target="stale">
|
||||||
|
Stale
|
||||||
|
</MenuItem>
|
||||||
<MenuItem disabled={settings.sort === 'created'} data-target="created">
|
<MenuItem disabled={settings.sort === 'created'} data-target="created">
|
||||||
Created
|
Created
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -33,6 +33,11 @@ export const mapStateToPropsConfigurable = isFeature => state => {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
a.enabled === b.enabled ? 0 : a.enabled ? -1 : 1
|
a.enabled === b.enabled ? 0 : a.enabled ? -1 : 1
|
||||||
);
|
);
|
||||||
|
} else if (settings.sort === 'stale') {
|
||||||
|
features = features.sort((a, b) =>
|
||||||
|
// eslint-disable-next-line
|
||||||
|
a.stale === b.stale ? 0 : a.stale ? -1 : 1
|
||||||
|
);
|
||||||
} else if (settings.sort === 'created') {
|
} else if (settings.sort === 'created') {
|
||||||
features = features.sort((a, b) => (new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1));
|
features = features.sort((a, b) => (new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1));
|
||||||
} else if (settings.sort === 'name') {
|
} else if (settings.sort === 'name') {
|
||||||
|
28
frontend/src/component/feature/status-component.jsx
Normal file
28
frontend/src/component/feature/status-component.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Chip } from 'react-mdl';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default function StatusComponent({ stale, style, showActive = true }) {
|
||||||
|
if (!stale && !showActive) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const className = stale
|
||||||
|
? 'mdl-color--red mdl-color-text--white mdl-shadow--2dp'
|
||||||
|
: 'mdl-color--light-green-500 mdl-color-text--white mdl-shadow--2dp';
|
||||||
|
|
||||||
|
const title = stale ? 'Feature toggle is deprecated.' : 'Feature toggle is active.';
|
||||||
|
const value = stale ? 'Stale' : 'Active';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Chip style={style} title={title} className={className}>
|
||||||
|
{value}
|
||||||
|
</Chip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusComponent.propTypes = {
|
||||||
|
stale: PropTypes.bool.isRequired,
|
||||||
|
style: PropTypes.object,
|
||||||
|
showActive: PropTypes.bool,
|
||||||
|
};
|
37
frontend/src/component/feature/status-update-component.jsx
Normal file
37
frontend/src/component/feature/status-update-component.jsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Menu, MenuItem } from 'react-mdl';
|
||||||
|
import { DropdownButton } from '../common';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default function StatusUpdateComponent({ stale, updateStale }) {
|
||||||
|
function setStatus(field) {
|
||||||
|
if (field === 'active') {
|
||||||
|
updateStale(false);
|
||||||
|
} else {
|
||||||
|
updateStale(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<DropdownButton className="mdl-button" id="update_status" label="Status" />
|
||||||
|
<Menu
|
||||||
|
target="update_status"
|
||||||
|
onClick={e => setStatus(e.target.getAttribute('data-target'))}
|
||||||
|
style={{ width: '168px' }}
|
||||||
|
>
|
||||||
|
<MenuItem disabled={!stale} data-target="active">
|
||||||
|
Set toggle Active
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem disabled={stale} data-target="stale">
|
||||||
|
Mark toggle as Stale
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusUpdateComponent.propTypes = {
|
||||||
|
stale: PropTypes.bool.isRequired,
|
||||||
|
updateStale: PropTypes.func.isRequired,
|
||||||
|
};
|
@ -12,6 +12,8 @@ import FeatureTypeSelect from './form/feature-type-select-container';
|
|||||||
import UpdateDescriptionComponent from './form/update-description-component';
|
import UpdateDescriptionComponent from './form/update-description-component';
|
||||||
import { styles as commonStyles } from '../common';
|
import { styles as commonStyles } from '../common';
|
||||||
import { CREATE_FEATURE, DELETE_FEATURE, UPDATE_FEATURE } from '../../permissions';
|
import { CREATE_FEATURE, DELETE_FEATURE, UPDATE_FEATURE } from '../../permissions';
|
||||||
|
import StatusComponent from './status-component';
|
||||||
|
import StatusUpdateComponent from './status-update-component';
|
||||||
|
|
||||||
const TABS = {
|
const TABS = {
|
||||||
strategies: 0,
|
strategies: 0,
|
||||||
@ -32,6 +34,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
|||||||
featureToggleName: PropTypes.string.isRequired,
|
featureToggleName: PropTypes.string.isRequired,
|
||||||
features: PropTypes.array.isRequired,
|
features: PropTypes.array.isRequired,
|
||||||
toggleFeature: PropTypes.func,
|
toggleFeature: PropTypes.func,
|
||||||
|
setStale: PropTypes.func,
|
||||||
removeFeatureToggle: PropTypes.func,
|
removeFeatureToggle: PropTypes.func,
|
||||||
revive: PropTypes.func,
|
revive: PropTypes.func,
|
||||||
fetchArchive: PropTypes.func,
|
fetchArchive: PropTypes.func,
|
||||||
@ -159,8 +162,20 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
|||||||
this.props.editFeatureToggle(feature);
|
this.props.editFeatureToggle(feature);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateStale = stale => {
|
||||||
|
this.props.setStale(stale, featureToggleName);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card shadow={0} className={commonStyles.fullwidth} style={{ overflow: 'visible' }}>
|
<Card shadow={0} className={commonStyles.fullwidth} style={{ overflow: 'visible' }}>
|
||||||
|
<StatusComponent
|
||||||
|
stale={featureToggle.stale}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
right: '4px',
|
||||||
|
top: '4px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<CardTitle style={{ wordBreak: 'break-all', paddingBottom: 0 }}>{featureToggle.name} </CardTitle>
|
<CardTitle style={{ wordBreak: 'break-all', paddingBottom: 0 }}>{featureToggle.name} </CardTitle>
|
||||||
<CardText>
|
<CardText>
|
||||||
<UpdateDescriptionComponent
|
<UpdateDescriptionComponent
|
||||||
@ -201,6 +216,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
|||||||
|
|
||||||
{this.isFeatureView ? (
|
{this.isFeatureView ? (
|
||||||
<div>
|
<div>
|
||||||
|
<StatusUpdateComponent stale={featureToggle.stale} updateStale={updateStale} />
|
||||||
<Link
|
<Link
|
||||||
to={`/features/copy/${featureToggle.name}`}
|
to={`/features/copy/${featureToggle.name}`}
|
||||||
title="Create new feature toggle by cloning configuration"
|
title="Create new feature toggle by cloning configuration"
|
||||||
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
|||||||
import {
|
import {
|
||||||
fetchFeatureToggles,
|
fetchFeatureToggles,
|
||||||
toggleFeature,
|
toggleFeature,
|
||||||
|
setStale,
|
||||||
removeFeatureToggle,
|
removeFeatureToggle,
|
||||||
editFeatureToggle,
|
editFeatureToggle,
|
||||||
} from './../../store/feature-actions';
|
} from './../../store/feature-actions';
|
||||||
@ -20,6 +21,7 @@ export default connect(
|
|||||||
{
|
{
|
||||||
fetchFeatureToggles,
|
fetchFeatureToggles,
|
||||||
toggleFeature,
|
toggleFeature,
|
||||||
|
setStale,
|
||||||
removeFeatureToggle,
|
removeFeatureToggle,
|
||||||
editFeatureToggle,
|
editFeatureToggle,
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,17 @@ function toggle(enable, name) {
|
|||||||
}).then(throwIfNotSuccess);
|
}).then(throwIfNotSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setStale(isStale, name) {
|
||||||
|
const action = isStale ? 'on' : 'off';
|
||||||
|
return fetch(`${URI}/${name}/stale/${action}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
credentials: 'include',
|
||||||
|
})
|
||||||
|
.then(throwIfNotSuccess)
|
||||||
|
.then(response => response.json());
|
||||||
|
}
|
||||||
|
|
||||||
function remove(featureToggleName) {
|
function remove(featureToggleName) {
|
||||||
return fetch(`${URI}/${featureToggleName}`, {
|
return fetch(`${URI}/${featureToggleName}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
@ -75,5 +86,6 @@ export default {
|
|||||||
validate,
|
validate,
|
||||||
update,
|
update,
|
||||||
toggle,
|
toggle,
|
||||||
|
setStale,
|
||||||
remove,
|
remove,
|
||||||
};
|
};
|
||||||
|
@ -26,6 +26,13 @@ export function toggleFeature(enable, name) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setStale(stale, name) {
|
||||||
|
debug('Set stale property on feature toggle ', name);
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(requestSetStaleFeatureToggle(stale, name));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function editFeatureToggle(featureToggle) {
|
export function editFeatureToggle(featureToggle) {
|
||||||
debug('Update feature toggle ', featureToggle);
|
debug('Update feature toggle ', featureToggle);
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
@ -76,6 +83,21 @@ export function requestToggleFeatureToggle(enable, name) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function requestSetStaleFeatureToggle(stale, name) {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch({ type: START_UPDATE_FEATURE_TOGGLE });
|
||||||
|
|
||||||
|
return api
|
||||||
|
.setStale(stale, name)
|
||||||
|
.then(featureToggle => {
|
||||||
|
const info = `${name} marked as ${stale ? 'Stale' : 'Active'}.`;
|
||||||
|
setTimeout(() => dispatch({ type: MUTE_ERROR, error: info }), 1000);
|
||||||
|
dispatch({ type: UPDATE_FEATURE_TOGGLE, featureToggle, info });
|
||||||
|
})
|
||||||
|
.catch(dispatchAndThrow(dispatch, ERROR_UPDATE_FEATURE_TOGGLE));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function requestUpdateFeatureToggle(featureToggle) {
|
export function requestUpdateFeatureToggle(featureToggle) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch({ type: START_UPDATE_FEATURE_TOGGLE });
|
dispatch({ type: START_UPDATE_FEATURE_TOGGLE });
|
||||||
|
@ -7965,6 +7965,11 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.13.1:
|
|||||||
react-is "^16.8.6"
|
react-is "^16.8.6"
|
||||||
scheduler "^0.19.1"
|
scheduler "^0.19.1"
|
||||||
|
|
||||||
|
react-timeago@^4.4.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-timeago/-/react-timeago-4.4.0.tgz#4520dd9ba63551afc4d709819f52b14b9343ba2b"
|
||||||
|
integrity sha512-Zj8RchTqZEH27LAANemzMR2RpotbP2aMd+UIajfYMZ9KW4dMcViUVKzC7YmqfiqlFfz8B0bjDw2xUBjmcxDngA==
|
||||||
|
|
||||||
react-transition-group@^4.3.0:
|
react-transition-group@^4.3.0:
|
||||||
version "4.4.1"
|
version "4.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
||||||
|
Loading…
Reference in New Issue
Block a user