mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
improved page layout + horizontal scrolling tables on mobile
This commit is contained in:
parent
553989f636
commit
3415fcb82e
@ -145,8 +145,8 @@ export default class App extends Component {
|
|||||||
</Navigation>
|
</Navigation>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<ScrollContainer scrollKey="container" shouldUpdateScroll={shouldUpdateScroll}>
|
<ScrollContainer scrollKey="container" shouldUpdateScroll={shouldUpdateScroll}>
|
||||||
<Content>
|
<Content className="mdl-color--grey-50">
|
||||||
<Grid shadow={1} style={{ maxWidth: '1200px', margin: '0 auto' }}>
|
<Grid noSpacing className={styles.content}>
|
||||||
<Cell col={12}>
|
<Cell col={12}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
<ErrorContainer />
|
<ErrorContainer />
|
||||||
|
@ -152,18 +152,20 @@ class ClientApplications extends PureComponent {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<HeaderTitle title={<span><Icon name={icon} /> {appName}</span>} subtitle={description}
|
<Cell col={12}>
|
||||||
actions={url && <ExternalIconLink url={url}>Visit site</ExternalIconLink>}
|
<HeaderTitle title={<span><Icon name={icon} /> {appName}</span>} subtitle={description}
|
||||||
/>
|
actions={url && <ExternalIconLink url={url}>Visit site</ExternalIconLink>}
|
||||||
|
/>
|
||||||
|
|
||||||
<Tabs activeTab={this.state.activeTab} onChange={(tabId) => this.setState({ activeTab: tabId })} ripple>
|
<Tabs activeTab={this.state.activeTab} onChange={(tabId) => this.setState({ activeTab: tabId })} ripple>
|
||||||
<Tab>Details</Tab>
|
<Tab>Details</Tab>
|
||||||
<Tab>Edit</Tab>
|
<Tab>Edit</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { ProgressBar } from 'react-mdl';
|
import { ProgressBar, Grid, Cell } from 'react-mdl';
|
||||||
import { AppsLinkList, HeaderTitle } from '../common';
|
import { AppsLinkList, HeaderTitle } from '../common';
|
||||||
|
|
||||||
class ClientStrategies extends Component {
|
class ClientStrategies extends Component {
|
||||||
@ -17,10 +17,12 @@ class ClientStrategies extends Component {
|
|||||||
return <ProgressBar indeterminate />;
|
return <ProgressBar indeterminate />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<HeaderTitle title="Applications" />
|
<Cell col={12}>
|
||||||
<AppsLinkList apps={applications} />
|
<HeaderTitle title="Applications" />
|
||||||
</div>
|
<AppsLinkList apps={applications} />
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
import { DataTable, TableHeader, IconButton, Icon } from 'react-mdl';
|
import { DataTable, TableHeader, IconButton, Icon, Grid, Cell } from 'react-mdl';
|
||||||
import { HeaderTitle } from '../common';
|
import { HeaderTitle } from '../common';
|
||||||
|
|
||||||
class ArchiveList extends Component {
|
class ArchiveList extends Component {
|
||||||
@ -14,26 +14,31 @@ class ArchiveList extends Component {
|
|||||||
e.reviveName = e.name;
|
e.reviveName = e.name;
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<HeaderTitle title="Toggle Archive" />
|
<Cell col={12}>
|
||||||
{
|
<HeaderTitle title="Toggle Archive" />
|
||||||
archive.length > 0 ?
|
<div style={{ overflowX: 'scroll' }}>
|
||||||
<DataTable
|
{
|
||||||
rows={archive}
|
archive.length > 0 ?
|
||||||
style={{ width: '100%' }}>
|
<DataTable
|
||||||
<TableHeader style={{ width: '25px' }} name="reviveName" cellFormatter={(reviveName) => (
|
rows={archive}
|
||||||
<IconButton colored name="undo" onClick={() => revive(reviveName)} />
|
style={{ width: '100%' }}>
|
||||||
)}>Revive</TableHeader>
|
<TableHeader style={{ width: '25px' }} name="reviveName" cellFormatter={(reviveName) => (
|
||||||
<TableHeader style={{ width: '25px' }} name="enabled" cellFormatter={(v) => (v ? 'Yes' : '-')}>Enabled</TableHeader>
|
<IconButton colored name="undo" onClick={() => revive(reviveName)} />
|
||||||
<TableHeader name="name">Toggle name</TableHeader>
|
)}>Revive</TableHeader>
|
||||||
<TableHeader numeric name="createdAt">Created</TableHeader>
|
<TableHeader style={{ width: '25px' }} name="enabled" cellFormatter={(v) => (v ? 'Yes' : '-')}>
|
||||||
</DataTable> :
|
Enabled</TableHeader>
|
||||||
<div style={{ textAlign: 'center' }}>
|
<TableHeader name="name">Toggle name</TableHeader>
|
||||||
<Icon name="report" style={{ color: '#aaa', fontSize: '40px' }}/><br />
|
<TableHeader numeric name="createdAt">Created</TableHeader>
|
||||||
No archived feature toggles, go see <Link to="/features">active toggles here</Link>
|
</DataTable> :
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<Icon name="report" style={{ color: '#aaa', fontSize: '40px' }}/><br />
|
||||||
|
No archived feature toggles, go see <Link to="/features">active toggles here</Link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
</Cell>
|
||||||
</div>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,21 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fullwidth {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.divider {
|
.divider {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-color: rgba(0,0,0,.12);
|
border-color: rgba(0,0,0,.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
.list {
|
||||||
.hideLt960 {
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 920px) {
|
||||||
|
.hideLt920 {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ const Feature = ({
|
|||||||
<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={commonStyles.hideLt960} style={{ flexShrink: 0 }}>
|
<span className={commonStyles.hideLt920} style={{ flexShrink: 0 }}>
|
||||||
{strategyChips}
|
{strategyChips}
|
||||||
{summaryChip}
|
{summaryChip}
|
||||||
</span>
|
</span>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
.topList {
|
.topList {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 10px 10px 10px 10px;
|
margin: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topListItem0 {
|
.topListItem0 {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { Textfield, Switch } from 'react-mdl';
|
import { Textfield, Switch, Grid, Cell } from 'react-mdl';
|
||||||
import StrategiesSection from './strategies-section-container';
|
import StrategiesSection from './strategies-section-container';
|
||||||
|
|
||||||
import { FormButtons, HeaderTitle } from '../../common';
|
import { FormButtons, HeaderTitle } from '../../common';
|
||||||
@ -45,53 +45,57 @@ class AddFeatureToggleComponent extends Component {
|
|||||||
const configuredStrategies = input.strategies || [];
|
const configuredStrategies = input.strategies || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onSubmit(input)}>
|
<Grid className="mdl-color--white">
|
||||||
{title && <HeaderTitle title={title} />}
|
<Cell col={12}>
|
||||||
<section>
|
<form onSubmit={onSubmit(input)}>
|
||||||
<Textfield
|
{title && <HeaderTitle title={title} />}
|
||||||
floatingLabel
|
<section>
|
||||||
label="Name"
|
<Textfield
|
||||||
name="name"
|
floatingLabel
|
||||||
disabled={editmode}
|
label="Name"
|
||||||
required
|
name="name"
|
||||||
value={name}
|
disabled={editmode}
|
||||||
error={nameError}
|
required
|
||||||
onBlur={(v) => validateName(v.target.value)}
|
value={name}
|
||||||
onChange={(v) => setValue('name', trim(v.target.value))} />
|
error={nameError}
|
||||||
<br />
|
onBlur={(v) => validateName(v.target.value)}
|
||||||
<Textfield
|
onChange={(v) => setValue('name', trim(v.target.value))} />
|
||||||
floatingLabel
|
<br />
|
||||||
style={{ width: '100%' }}
|
<Textfield
|
||||||
rows={1}
|
floatingLabel
|
||||||
label="Description"
|
style={{ width: '100%' }}
|
||||||
required
|
rows={1}
|
||||||
value={description}
|
label="Description"
|
||||||
onChange={(v) => setValue('description', v.target.value)} />
|
required
|
||||||
|
value={description}
|
||||||
|
onChange={(v) => setValue('description', v.target.value)} />
|
||||||
|
|
||||||
|
{!editmode && <div>
|
||||||
|
<br />
|
||||||
|
<Switch
|
||||||
|
checked={enabled}
|
||||||
|
onChange={() => {
|
||||||
|
setValue('enabled', !enabled);
|
||||||
|
}}>Enabled</Switch>
|
||||||
|
<hr />
|
||||||
|
</div>}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<StrategiesSection
|
||||||
|
configuredStrategies={configuredStrategies}
|
||||||
|
addStrategy={addStrategy}
|
||||||
|
updateStrategy={updateStrategy}
|
||||||
|
moveStrategy={moveStrategy}
|
||||||
|
removeStrategy={removeStrategy} />
|
||||||
|
|
||||||
{!editmode && <div>
|
|
||||||
<br />
|
<br />
|
||||||
<Switch
|
<FormButtons
|
||||||
checked={enabled}
|
submitText={editmode ? 'Update' : 'Create'}
|
||||||
onChange={() => {
|
onCancel={onCancel}
|
||||||
setValue('enabled', !enabled);
|
/>
|
||||||
}}>Enabled</Switch>
|
</form>
|
||||||
<hr />
|
</Cell>
|
||||||
</div>}
|
</Grid>
|
||||||
</section>
|
|
||||||
|
|
||||||
<StrategiesSection
|
|
||||||
configuredStrategies={configuredStrategies}
|
|
||||||
addStrategy={addStrategy}
|
|
||||||
updateStrategy={updateStrategy}
|
|
||||||
moveStrategy={moveStrategy}
|
|
||||||
removeStrategy={removeStrategy} />
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<FormButtons
|
|
||||||
submitText={editmode ? 'Update' : 'Create'}
|
|
||||||
onCancel={onCancel}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import Feature from './feature-list-item-component';
|
import Feature from './feature-list-item-component';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
import { Icon, Chip, ChipContact, IconButton, FABButton, Textfield, Menu, MenuItem } from 'react-mdl';
|
import { Icon, Chip, ChipContact, IconButton, FABButton, Textfield, Menu, MenuItem, Grid, Cell } from 'react-mdl';
|
||||||
|
|
||||||
|
import { styles as commonStyles } from '../common';
|
||||||
import styles from './feature.scss';
|
import styles from './feature.scss';
|
||||||
|
|
||||||
export default class FeatureListComponent extends React.PureComponent {
|
export default class FeatureListComponent extends React.PureComponent {
|
||||||
@ -49,70 +50,72 @@ export default class FeatureListComponent extends React.PureComponent {
|
|||||||
const { features, toggleFeature, featureMetrics, settings } = this.props;
|
const { features, toggleFeature, featureMetrics, settings } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<div className={styles.topList}>
|
<Cell col={12}>
|
||||||
<Chip onClick={() => this.toggleMetrics()} className={styles.topListItem0}>
|
<div className={styles.topList}>
|
||||||
{ settings.showLastHour &&
|
<Chip onClick={() => this.toggleMetrics()} className={styles.topListItem0}>
|
||||||
<ChipContact className="mdl-color--teal mdl-color-text--white">
|
{ settings.showLastHour &&
|
||||||
<Icon name="hourglass_full" style={{ fontSize: '16px' }} />
|
<ChipContact className="mdl-color--teal mdl-color-text--white">
|
||||||
</ChipContact> }
|
<Icon name="hourglass_full" style={{ fontSize: '16px' }} />
|
||||||
{ '1 hour' }
|
</ChipContact> }
|
||||||
</Chip>
|
{ '1 hour' }
|
||||||
|
</Chip>
|
||||||
<Chip onClick={() => this.toggleMetrics()} className={styles.topListItem0}>
|
|
||||||
{ !settings.showLastHour &&
|
<Chip onClick={() => this.toggleMetrics()} className={styles.topListItem0}>
|
||||||
<ChipContact className="mdl-color--teal mdl-color-text--white">
|
{ !settings.showLastHour &&
|
||||||
<Icon name="hourglass_empty" style={{ fontSize: '16px' }} />
|
<ChipContact className="mdl-color--teal mdl-color-text--white">
|
||||||
</ChipContact> }
|
<Icon name="hourglass_empty" style={{ fontSize: '16px' }} />
|
||||||
{ '1 minute' }
|
</ChipContact> }
|
||||||
</Chip>
|
{ '1 minute' }
|
||||||
|
</Chip>
|
||||||
|
|
||||||
<div className={styles.topListItem2} style={{ margin: '-10px 10px 0 10px' }}>
|
<div className={styles.topListItem2} style={{ margin: '-10px 10px 0 10px' }}>
|
||||||
<Textfield
|
<Textfield
|
||||||
floatingLabel
|
floatingLabel
|
||||||
value={settings.filter}
|
value={settings.filter}
|
||||||
onChange={(e) => { this.setFilter(e.target.value); }}
|
onChange={(e) => { this.setFilter(e.target.value); }}
|
||||||
label="Filter toggles"
|
label="Filter toggles"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ position: 'relative' }} className={styles.topListItem0}>
|
||||||
|
<IconButton name="sort" id="demo-menu-top-right" colored title="Sort" />
|
||||||
|
<Menu target="demo-menu-top-right" valign="bottom" align="right" ripple onClick={
|
||||||
|
(e) => this.setSort(e.target.getAttribute('data-target'))}>
|
||||||
|
<MenuItem disabled>Filter by:</MenuItem>
|
||||||
|
<MenuItem disabled={!settings.sort || settings.sort === 'nosort'} data-target="nosort">Default</MenuItem>
|
||||||
|
<MenuItem disabled={settings.sort === 'name'} data-target="name">Name</MenuItem>
|
||||||
|
<MenuItem disabled={settings.sort === 'enabled'} data-target="enabled">Enabled</MenuItem>
|
||||||
|
<MenuItem disabled={settings.sort === 'appName'} data-target="appName">Application name</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>
|
||||||
|
</div>
|
||||||
|
<Link to="/features/create" className={styles.topListItem0}>
|
||||||
|
<IconButton ripple raised name="add" component="span" style={{ color: 'black' }}/>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ position: 'relative' }} className={styles.topListItem0}>
|
<ul className={['mdl-list', commonStyles.list].join(' ')}>
|
||||||
<IconButton name="sort" id="demo-menu-top-right" colored title="Sort" />
|
{features.map((feature, i) =>
|
||||||
<Menu target="demo-menu-top-right" valign="bottom" align="right" ripple onClick={
|
<Feature key={i}
|
||||||
(e) => this.setSort(e.target.getAttribute('data-target'))}>
|
settings={settings}
|
||||||
<MenuItem disabled>Filter by:</MenuItem>
|
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
||||||
<MenuItem disabled={!settings.sort || settings.sort === 'nosort'} data-target="nosort">Default</MenuItem>
|
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
||||||
<MenuItem disabled={settings.sort === 'name'} data-target="name">Name</MenuItem>
|
feature={feature}
|
||||||
<MenuItem disabled={settings.sort === 'enabled'} data-target="enabled">Enabled</MenuItem>
|
toggleFeature={toggleFeature}/>
|
||||||
<MenuItem disabled={settings.sort === 'appName'} data-target="appName">Application name</MenuItem>
|
)}
|
||||||
<MenuItem disabled={settings.sort === 'created'} data-target="created">Created</MenuItem>
|
</ul>
|
||||||
<MenuItem disabled={settings.sort === 'strategies'} data-target="strategies">Strategies</MenuItem>
|
<hr />
|
||||||
<MenuItem disabled={settings.sort === 'metrics'} data-target="metrics">Metrics</MenuItem>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
<Link to="/features/create" className={styles.topListItem0}>
|
<Link to="/features/create" className={styles.topListItem0}>
|
||||||
<IconButton ripple raised name="add" component="span" style={{ color: 'black' }}/>
|
<FABButton ripple component="span" mini>
|
||||||
|
<Icon name="add" />
|
||||||
|
</FABButton>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</Cell>
|
||||||
|
</Grid>
|
||||||
<ul className="mdl-list">
|
|
||||||
{features.map((feature, i) =>
|
|
||||||
<Feature key={i}
|
|
||||||
settings={settings}
|
|
||||||
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
|
||||||
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
|
||||||
feature={feature}
|
|
||||||
toggleFeature={toggleFeature}/>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
<hr />
|
|
||||||
<Link to="/features/create" className={styles.topListItem0}>
|
|
||||||
<FABButton ripple component="span" mini>
|
|
||||||
<Icon name="add" />
|
|
||||||
</FABButton>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { Tabs, Tab, ProgressBar, IconButton } from 'react-mdl';
|
import { Tabs, Tab, ProgressBar, IconButton, Grid, Cell } from 'react-mdl';
|
||||||
import { hashHistory, Link } from 'react-router';
|
import { hashHistory, Link } from 'react-router';
|
||||||
|
|
||||||
import HistoryComponent from '../history/history-list-toggle-container';
|
import HistoryComponent from '../history/history-list-toggle-container';
|
||||||
@ -90,25 +90,27 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<h4>
|
<Cell col={12}>
|
||||||
<SwitchWithLabel checked={featureToggle.enabled} onChange={() => toggleFeature(featureToggle.name)} />
|
<h4 style={{ marginTop: '16px' }}>
|
||||||
{featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small>
|
<SwitchWithLabel checked={featureToggle.enabled} onChange={() => toggleFeature(featureToggle.name)} />
|
||||||
|
{featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small>
|
||||||
|
|
||||||
<IconButton style={{ float: 'right' }} name="delete" onClick={removeToggle} className="mdl-color-text--grey-600" />
|
<IconButton style={{ float: 'right' }} name="delete" onClick={removeToggle} className="mdl-color-text--grey-600" />
|
||||||
<small style={{ float: 'right', lineHeight: '38px' }}>
|
<small style={{ float: 'right', lineHeight: '38px' }}>
|
||||||
Created {formatFullDateTime(featureToggle.createdAt)}
|
Created {formatFullDateTime(featureToggle.createdAt)}
|
||||||
</small>
|
</small>
|
||||||
</h4>
|
</h4>
|
||||||
<div className="mdl-color-text--grey"><small>{featureToggle.description}</small></div>
|
<div className="mdl-color-text--grey"><small>{featureToggle.description}</small></div>
|
||||||
<Tabs activeTab={activeTabId} ripple style={{ marginBottom: '10px' }}>
|
<Tabs activeTab={activeTabId} ripple style={{ marginBottom: '10px' }} tabBarProps={{ style: { width: '100%' } }}>
|
||||||
<Tab onClick={() => this.goToTab('view', featureToggleName)}>Metrics</Tab>
|
<Tab onClick={() => this.goToTab('view', featureToggleName)}>Metrics</Tab>
|
||||||
<Tab onClick={() => this.goToTab('edit', featureToggleName)}>Edit</Tab>
|
<Tab onClick={() => this.goToTab('edit', featureToggleName)}>Edit</Tab>
|
||||||
<Tab onClick={() => this.goToTab('history', featureToggleName)}>History</Tab>
|
<Tab onClick={() => this.goToTab('history', featureToggleName)}>History</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
{tabContent}
|
{tabContent}
|
||||||
</div>
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Grid, Cell } from 'react-mdl';
|
||||||
import HistoryList from './history-list-container';
|
import HistoryList from './history-list-container';
|
||||||
|
|
||||||
class History extends PureComponent {
|
class History extends PureComponent {
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@ -18,7 +18,11 @@ class History extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HistoryList history={history} title="Last 100 changes" />
|
<Grid className="mdl-color--white">
|
||||||
|
<Cell col={12}>
|
||||||
|
<HistoryList history={history} title="Last 100 changes" />
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ class HistoryItem extends PureComponent {
|
|||||||
changes = <div className={KLASSES.N}>{JSON.stringify(entry.data, null, 2)}</div>;
|
changes = <div className={KLASSES.N}>{JSON.stringify(entry.data, null, 2)}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<pre style={{ maxWidth: '500px', overflowX: 'auto', overflowY: 'hidden', width: 'auto' }}>
|
return (<pre style={{ maxWidth: '354px', overflowX: 'auto', overflowY: 'hidden', width: 'auto' }}>
|
||||||
<code className="smalltext man">{changes.length === 0 ? '(no changes)' : changes}</code>
|
<code className="smalltext man">{changes.length === 0 ? '(no changes)' : changes}</code>
|
||||||
</pre>);
|
</pre>);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@ import React, { Component } from 'react';
|
|||||||
import HistoryItemDiff from './history-item-diff';
|
import HistoryItemDiff from './history-item-diff';
|
||||||
import HistoryItemJson from './history-item-json';
|
import HistoryItemJson from './history-item-json';
|
||||||
import { Table, TableHeader } from 'react-mdl';
|
import { Table, TableHeader } from 'react-mdl';
|
||||||
import { HeaderTitle, SwitchWithLabel } from '../common';
|
import { HeaderTitle, SwitchWithLabel, styles as commonStyles } from '../common';
|
||||||
import { formatFullDateTime } from '../common/util';
|
import { formatFullDateTime } from '../common/util';
|
||||||
|
|
||||||
import style from './history.scss';
|
import styles from './history.scss';
|
||||||
|
|
||||||
class HistoryList extends Component {
|
class HistoryList extends Component {
|
||||||
|
|
||||||
@ -32,7 +32,8 @@ class HistoryList extends Component {
|
|||||||
diff: (<HistoryItemDiff entry={entry} />),
|
diff: (<HistoryItemDiff entry={entry} />),
|
||||||
}, entry))
|
}, entry))
|
||||||
}
|
}
|
||||||
style={{ width: '100%' }}
|
className={commonStyles.fullwidth}
|
||||||
|
style={{ border: 0 }}
|
||||||
>
|
>
|
||||||
<TableHeader name="type">Type</TableHeader>
|
<TableHeader name="type">Type</TableHeader>
|
||||||
<TableHeader name="createdBy">User</TableHeader>
|
<TableHeader name="createdBy">User</TableHeader>
|
||||||
@ -42,11 +43,13 @@ class HistoryList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.history}>
|
<div className={styles.history}>
|
||||||
<HeaderTitle title={this.props.title} actions={
|
<HeaderTitle title={this.props.title} actions={
|
||||||
<SwitchWithLabel checked={showData} onChange={this.toggleShowDiff.bind(this)}>Show full events</SwitchWithLabel>
|
<SwitchWithLabel checked={showData} onChange={this.toggleShowDiff.bind(this)}>Show full events</SwitchWithLabel>
|
||||||
}/>
|
}/>
|
||||||
{entries}
|
<div style={{ overflowX: 'scroll' }}>
|
||||||
|
{entries}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PropTypes, Component } from 'react';
|
import React, { PropTypes, Component } from 'react';
|
||||||
|
|
||||||
import { Textfield, IconButton, Menu, MenuItem, Checkbox } from 'react-mdl';
|
import { Textfield, IconButton, Menu, MenuItem, Checkbox, Grid, Cell } from 'react-mdl';
|
||||||
import { FormButtons } from '../common';
|
import { FormButtons } from '../common';
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ const Parameter = ({ set, input = {}, index }) => (
|
|||||||
|
|
||||||
const EditHeader = () => (
|
const EditHeader = () => (
|
||||||
<div>
|
<div>
|
||||||
<h4>Edit strategy</h4>
|
<h4 style={{ marginTop: '16px' }}>Edit strategy</h4>
|
||||||
<p style={{ background: '#ffb7b7', padding: '16px 20px' }}>
|
<p style={{ background: '#ffb7b7', padding: '16px 20px' }}>
|
||||||
Be carefull! Changing a strategy definition might also require changes to the
|
Be carefull! Changing a strategy definition might also require changes to the
|
||||||
implementation in the clients.
|
implementation in the clients.
|
||||||
@ -74,7 +74,7 @@ const EditHeader = () => (
|
|||||||
|
|
||||||
const CreateHeader = () => (
|
const CreateHeader = () => (
|
||||||
<div>
|
<div>
|
||||||
<h4>Create a new Strategy definition</h4>
|
<h4 style={{ marginTop: '16px' }}>Create a new Strategy definition</h4>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -130,44 +130,48 @@ class AddStrategy extends Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onSubmit(input)}>
|
<Grid className="mdl-color--white">
|
||||||
{editmode ? <EditHeader /> : <CreateHeader />}
|
<Cell col={12}>
|
||||||
<Textfield label="Strategy name"
|
<form onSubmit={onSubmit(input)}>
|
||||||
floatingLabel
|
{editmode ? <EditHeader /> : <CreateHeader />}
|
||||||
name="name"
|
<Textfield label="Strategy name"
|
||||||
required
|
floatingLabel
|
||||||
disabled={editmode}
|
name="name"
|
||||||
pattern="^[0-9a-zA-Z\.\-]+$"
|
required
|
||||||
onChange={({ target }) => setValue('name', trim(target.value))}
|
disabled={editmode}
|
||||||
value={input.name}
|
pattern="^[0-9a-zA-Z\.\-]+$"
|
||||||
/>
|
onChange={({ target }) => setValue('name', trim(target.value))}
|
||||||
<br />
|
value={input.name}
|
||||||
<Textfield
|
/>
|
||||||
floatingLabel
|
<br />
|
||||||
style={{ width: '100%' }}
|
<Textfield
|
||||||
rows={1}
|
floatingLabel
|
||||||
label="Description"
|
style={{ width: '100%' }}
|
||||||
name="description"
|
rows={1}
|
||||||
onChange={({ target }) => setValue('description', target.value)}
|
label="Description"
|
||||||
value={input.description}
|
name="description"
|
||||||
/>
|
onChange={({ target }) => setValue('description', target.value)}
|
||||||
|
value={input.description}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<Parameters input={input.parameters} count={input._params} updateInList={updateInList} />
|
<Parameters input={input.parameters} count={input._params} updateInList={updateInList} />
|
||||||
<IconButton raised name="add" title="Add parameter" onClick={(e) => {
|
<IconButton raised name="add" title="Add parameter" onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
incValue('_params');
|
incValue('_params');
|
||||||
}}/> Add parameter
|
}}/> Add parameter
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<FormButtons
|
<FormButtons
|
||||||
submitText={editmode ? 'Update' : 'Create'}
|
submitText={editmode ? 'Update' : 'Create'}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import { List, ListItem, ListItemContent, IconButton } from 'react-mdl';
|
import { List, ListItem, ListItemContent, IconButton, Grid, Cell } from 'react-mdl';
|
||||||
import { HeaderTitle } from '../common';
|
import { HeaderTitle, styles as commonStyles } from '../common';
|
||||||
|
|
||||||
class StrategiesListComponent extends Component {
|
class StrategiesListComponent extends Component {
|
||||||
|
|
||||||
@ -18,26 +18,28 @@ class StrategiesListComponent extends Component {
|
|||||||
const { strategies, removeStrategy } = this.props;
|
const { strategies, removeStrategy } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<HeaderTitle title="Strategies"
|
<Cell col={12}>
|
||||||
actions={
|
<HeaderTitle title="Strategies"
|
||||||
<IconButton raised
|
actions={
|
||||||
name="add"
|
<IconButton raised
|
||||||
onClick={() => this.context.router.push('/strategies/create')}
|
name="add"
|
||||||
title="Add new strategy" />} />
|
onClick={() => this.context.router.push('/strategies/create')}
|
||||||
<List>
|
title="Add new strategy" />} />
|
||||||
{strategies.length > 0 ? strategies.map((strategy, i) => (
|
<List className={commonStyles.list}>
|
||||||
<ListItem key={i} twoLine>
|
{strategies.length > 0 ? strategies.map((strategy, i) => (
|
||||||
<ListItemContent icon="extension" subtitle={strategy.description}>
|
<ListItem key={i} twoLine>
|
||||||
<Link to={`/strategies/view/${strategy.name}`}>
|
<ListItemContent icon="extension" subtitle={strategy.description}>
|
||||||
<strong>{strategy.name}</strong>
|
<Link to={`/strategies/view/${strategy.name}`}>
|
||||||
</Link>
|
<strong>{strategy.name}</strong>
|
||||||
</ListItemContent>
|
</Link>
|
||||||
<IconButton name="delete" onClick={() => removeStrategy(strategy)} />
|
</ListItemContent>
|
||||||
</ListItem>
|
<IconButton name="delete" onClick={() => removeStrategy(strategy)} />
|
||||||
)) : <ListItem>No entries</ListItem>}
|
</ListItem>
|
||||||
</List>
|
)) : <ListItem>No entries</ListItem>}
|
||||||
</div>
|
</List>
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PropTypes, Component } from 'react';
|
import React, { PropTypes, Component } from 'react';
|
||||||
import { hashHistory } from 'react-router';
|
import { hashHistory } from 'react-router';
|
||||||
import { Tabs, Tab, ProgressBar } from 'react-mdl';
|
import { Tabs, Tab, ProgressBar, Grid, Cell } from 'react-mdl';
|
||||||
import ShowStrategy from './show-strategy-component';
|
import ShowStrategy from './show-strategy-component';
|
||||||
import EditStrategy from './edit-container';
|
import EditStrategy from './edit-container';
|
||||||
import { HeaderTitle } from '../common';
|
import { HeaderTitle } from '../common';
|
||||||
@ -61,18 +61,20 @@ export default class StrategyDetails extends Component {
|
|||||||
const tabContent = this.getTabContent(activeTabId);
|
const tabContent = this.getTabContent(activeTabId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Grid className="mdl-color--white">
|
||||||
<HeaderTitle title={strategy.name} subtitle={strategy.description} />
|
<Cell col={12}>
|
||||||
<Tabs activeTab={activeTabId} ripple>
|
<HeaderTitle title={strategy.name} subtitle={strategy.description} />
|
||||||
<Tab onClick={() => this.goToTab('view')}>Details</Tab>
|
<Tabs activeTab={activeTabId} ripple>
|
||||||
<Tab onClick={() => this.goToTab('edit')}>Edit</Tab>
|
<Tab onClick={() => this.goToTab('view')}>Details</Tab>
|
||||||
</Tabs>
|
<Tab onClick={() => this.goToTab('edit')}>Edit</Tab>
|
||||||
<section>
|
</Tabs>
|
||||||
<div className="content">
|
<section>
|
||||||
{tabContent}
|
<div className="content">
|
||||||
</div>
|
{tabContent}
|
||||||
</section>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,34 @@
|
|||||||
|
.content {
|
||||||
|
width: 1200px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
@media (max-width: 1800px) {
|
||||||
|
.content {
|
||||||
|
width: 66.66%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 1260px) {
|
||||||
|
.content {
|
||||||
|
width: 840px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 920px) {
|
||||||
|
.content {
|
||||||
|
width: auto;
|
||||||
|
margin-left: 40px;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.content {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.headerTitleLink {
|
.headerTitleLink {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user