Add positionig for services tooltip
adding tooltip to store and passing props down to component Add tooltip to services list Add queck actions tooltip to services
This commit is contained in:
parent
2bede6e669
commit
b229c7b63e
@ -8,7 +8,7 @@ import { remcalc } from '@ui/shared/functions';
|
|||||||
import Logo from '../../resources/logo.svg';
|
import Logo from '../../resources/logo.svg';
|
||||||
import PropTypes from '@root/prop-types';
|
import PropTypes from '@root/prop-types';
|
||||||
import Row from '@ui/components/row';
|
import Row from '@ui/components/row';
|
||||||
import Tooltip from '@ui/components/tooltip';
|
import Tooltip, { TooltipButton } from '@ui/components/tooltip';
|
||||||
import { pseudoEl, typography } from '@ui/shared/composers';
|
import { pseudoEl, typography } from '@ui/shared/composers';
|
||||||
import { colors } from '@ui/shared/constants';
|
import { colors } from '@ui/shared/constants';
|
||||||
|
|
||||||
@ -46,12 +46,6 @@ const StyledAvatarWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTooltipWrapper = styled.div`
|
|
||||||
right: ${remcalc(-18)};
|
|
||||||
bottom: ${remcalc(-140)};
|
|
||||||
position: absolute;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledName = styled.span`
|
const StyledName = styled.span`
|
||||||
color: ${colors.base.secondaryDark};
|
color: ${colors.base.secondaryDark};
|
||||||
font-size: ${remcalc(16)};
|
font-size: ${remcalc(16)};
|
||||||
@ -76,7 +70,7 @@ const StyledAvatar = styled(Avatar)`
|
|||||||
|
|
||||||
const arrowPosition = {
|
const arrowPosition = {
|
||||||
bottom: '100%',
|
bottom: '100%',
|
||||||
right: '10%'
|
right: 18
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header = ({
|
const Header = ({
|
||||||
@ -96,19 +90,21 @@ const Header = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const tooltipComponent = !tooltip ? null : (
|
const tooltipComponent = !tooltip ? null : (
|
||||||
<StyledTooltipWrapper>
|
<Tooltip
|
||||||
<Tooltip arrowPosition={arrowPosition}>
|
arrowPosition={arrowPosition}
|
||||||
<li>
|
right={0}
|
||||||
<Link to='/'>My Account</Link>
|
top={39}
|
||||||
</li>
|
>
|
||||||
<li>
|
<li>
|
||||||
<Link to='/'>Settings</Link>
|
<TooltipButton to='/'>My Account</TooltipButton>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to='/'>About</Link>
|
<TooltipButton to='/'>Settings</TooltipButton>
|
||||||
</li>
|
</li>
|
||||||
</Tooltip>
|
<li>
|
||||||
</StyledTooltipWrapper>
|
<TooltipButton to='/'>About</TooltipButton>
|
||||||
|
</li>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,6 +30,7 @@ const TitleInnerContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const ServiceItem = ({
|
const ServiceItem = ({
|
||||||
|
onQuickActions=() => {},
|
||||||
org = '',
|
org = '',
|
||||||
project = '',
|
project = '',
|
||||||
service = {}
|
service = {}
|
||||||
@ -72,6 +73,10 @@ const ServiceItem = ({
|
|||||||
<ListItemDescription>Flags</ListItemDescription>
|
<ListItemDescription>Flags</ListItemDescription>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onOptionsClick = (evt) => {
|
||||||
|
onQuickActions(evt, service.uuid);
|
||||||
|
};
|
||||||
|
|
||||||
const header = isChild ? null : (
|
const header = isChild ? null : (
|
||||||
<ListItemHeader>
|
<ListItemHeader>
|
||||||
<ListItemMeta>
|
<ListItemMeta>
|
||||||
@ -79,7 +84,9 @@ const ServiceItem = ({
|
|||||||
{subtitle}
|
{subtitle}
|
||||||
{description}
|
{description}
|
||||||
</ListItemMeta>
|
</ListItemMeta>
|
||||||
<ListItemOptions>…</ListItemOptions>
|
<ListItemOptions onClick={onOptionsClick}>
|
||||||
|
…
|
||||||
|
</ListItemOptions>
|
||||||
</ListItemHeader>
|
</ListItemHeader>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -113,6 +120,7 @@ const ServiceItem = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
ServiceItem.propTypes = {
|
ServiceItem.propTypes = {
|
||||||
|
onQuickActions: React.PropTypes.func,
|
||||||
org: React.PropTypes.string,
|
org: React.PropTypes.string,
|
||||||
project: React.PropTypes.string,
|
project: React.PropTypes.string,
|
||||||
service: PropTypes.service
|
service: PropTypes.service
|
||||||
|
41
frontend/src/components/services/tooltip.js
Normal file
41
frontend/src/components/services/tooltip.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Tooltip, { TooltipButton, TooltipDivider } from '@ui/components/tooltip';
|
||||||
|
|
||||||
|
const ServicesTooltip = ({
|
||||||
|
show,
|
||||||
|
position
|
||||||
|
}) => {
|
||||||
|
return show ? (
|
||||||
|
<Tooltip {...position}>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Scale</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Rollback</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Reprovision</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Transfer</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Setup metrics</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<TooltipDivider />
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Stop</TooltipButton>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<TooltipButton>Delete</TooltipButton>
|
||||||
|
</li>
|
||||||
|
</Tooltip>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
ServicesTooltip.propTypes = {
|
||||||
|
position: React.PropTypes.object,
|
||||||
|
show: React.PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServicesTooltip;
|
@ -1,44 +1,93 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from '@root/prop-types';
|
import PropTypes from '@root/prop-types';
|
||||||
import ServiceItem from '@components/service/item';
|
import ServiceItem from '@components/service/item';
|
||||||
import UnmanagedInstances from '@components/services/unmanaged-instances';
|
import UnmanagedInstances from '@components/services/unmanaged-instances';
|
||||||
|
import { toggleTooltip } from '@state/actions';
|
||||||
|
import ServicesTooltip from '@components/services/tooltip';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
orgByIdSelector,
|
orgByIdSelector,
|
||||||
projectByIdSelector,
|
projectByIdSelector,
|
||||||
servicesByProjectIdSelector
|
servicesByProjectIdSelector,
|
||||||
|
serviceUiTooltipSelector
|
||||||
} from '@state/selectors';
|
} from '@state/selectors';
|
||||||
|
|
||||||
const Services = (props) => {
|
const StyledContainer = styled.div`
|
||||||
const {
|
position: relative;
|
||||||
org = {},
|
`;
|
||||||
project = {},
|
|
||||||
services = []
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const instances = 5;
|
class Services extends React.Component {
|
||||||
const serviceList = services.map((service) => (
|
|
||||||
<ServiceItem
|
|
||||||
key={service.uuid}
|
|
||||||
org={org.id}
|
|
||||||
project={project.id}
|
|
||||||
service={service}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
|
|
||||||
return (
|
ref(name) {
|
||||||
<div>
|
this._refs = this._refs || {};
|
||||||
{ serviceList }
|
|
||||||
{ instances && <UnmanagedInstances instances={instances} /> }
|
return (el) => {
|
||||||
</div>
|
this._refs[name] = el;
|
||||||
);
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
org = {},
|
||||||
|
project = {},
|
||||||
|
services = [],
|
||||||
|
toggleTooltip = (() => {}),
|
||||||
|
uiTooltip = {}
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const onQuickActions = (evt, service) => {
|
||||||
|
const list = this._refs.container;
|
||||||
|
const listRect = list.getBoundingClientRect();
|
||||||
|
const button = evt.currentTarget;
|
||||||
|
const buttonRect = button.getBoundingClientRect();
|
||||||
|
|
||||||
|
const position = {
|
||||||
|
left: buttonRect.left - listRect.left
|
||||||
|
+ (buttonRect.right - buttonRect.left)/2,
|
||||||
|
top: buttonRect.bottom - listRect.top
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleTooltip({
|
||||||
|
service: service,
|
||||||
|
position: position
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const instances = 5;
|
||||||
|
|
||||||
|
const serviceList = services.map((service) => (
|
||||||
|
<ServiceItem
|
||||||
|
key={service.uuid}
|
||||||
|
onQuickActions={onQuickActions}
|
||||||
|
org={org.id}
|
||||||
|
project={project.id}
|
||||||
|
service={service}
|
||||||
|
uiTooltip={uiTooltip}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{ instances && <UnmanagedInstances instances={instances} /> }
|
||||||
|
<StyledContainer>
|
||||||
|
<div ref={this.ref('container')}>
|
||||||
|
{serviceList}
|
||||||
|
<ServicesTooltip {...uiTooltip} />
|
||||||
|
</div>
|
||||||
|
</StyledContainer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Services.propTypes = {
|
Services.propTypes = {
|
||||||
org: PropTypes.org,
|
org: PropTypes.org,
|
||||||
project: PropTypes.project,
|
project: PropTypes.project,
|
||||||
services: React.PropTypes.arrayOf(PropTypes.service)
|
services: React.PropTypes.arrayOf(PropTypes.service),
|
||||||
|
toggleTooltip: React.PropTypes.func,
|
||||||
|
uiTooltip: React.PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state, {
|
const mapStateToProps = (state, {
|
||||||
@ -49,9 +98,15 @@ const mapStateToProps = (state, {
|
|||||||
}) => ({
|
}) => ({
|
||||||
org: orgByIdSelector(match.params.org)(state),
|
org: orgByIdSelector(match.params.org)(state),
|
||||||
project: projectByIdSelector(match.params.projectId)(state),
|
project: projectByIdSelector(match.params.projectId)(state),
|
||||||
services: servicesByProjectIdSelector(match.params.projectId)(state)
|
services: servicesByProjectIdSelector(match.params.projectId)(state),
|
||||||
|
uiTooltip: serviceUiTooltipSelector(state)
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
toggleTooltip: (data) => dispatch(toggleTooltip(data))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
)(Services);
|
)(Services);
|
||||||
|
@ -1,26 +1,49 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import styled from 'styled-components';
|
||||||
import PropTypes from '@root/prop-types';
|
import PropTypes from '@root/prop-types';
|
||||||
import { TopologyGraph } from '@ui/components/topology';
|
import { TopologyGraph } from '@ui/components/topology';
|
||||||
|
import ServicesTooltip from '@components/services/tooltip';
|
||||||
|
|
||||||
|
import { toggleTooltip } from '@state/actions';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
orgByIdSelector,
|
orgByIdSelector,
|
||||||
projectByIdSelector,
|
projectByIdSelector,
|
||||||
servicesForTopologySelector
|
servicesForTopologySelector,
|
||||||
|
serviceUiTooltipSelector
|
||||||
} from '@state/selectors';
|
} from '@state/selectors';
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
position: relative;
|
||||||
|
`;
|
||||||
|
|
||||||
const Services = (props) => {
|
const Services = (props) => {
|
||||||
const {
|
const {
|
||||||
services = []
|
services = [],
|
||||||
|
toggleTooltip,
|
||||||
|
uiTooltip
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const onQuickActions = (evt, tooltipData) => {
|
||||||
|
toggleTooltip(tooltipData);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TopologyGraph services={services} />
|
<StyledContainer>
|
||||||
|
<TopologyGraph
|
||||||
|
onQuickActions={onQuickActions}
|
||||||
|
services={services}
|
||||||
|
/>
|
||||||
|
<ServicesTooltip {...uiTooltip} />
|
||||||
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Services.propTypes = {
|
Services.propTypes = {
|
||||||
services: React.PropTypes.arrayOf(PropTypes.service)
|
services: React.PropTypes.arrayOf(PropTypes.service),
|
||||||
|
toggleTooltip: React.PropTypes.func,
|
||||||
|
uiTooltip: React.PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state, {
|
const mapStateToProps = (state, {
|
||||||
@ -30,9 +53,15 @@ const mapStateToProps = (state, {
|
|||||||
}) => ({
|
}) => ({
|
||||||
org: orgByIdSelector(match.params.org)(state),
|
org: orgByIdSelector(match.params.org)(state),
|
||||||
project: projectByIdSelector(match.params.projectId)(state),
|
project: projectByIdSelector(match.params.projectId)(state),
|
||||||
services: servicesForTopologySelector(match.params.projectId)(state)
|
services: servicesForTopologySelector(match.params.projectId)(state),
|
||||||
|
uiTooltip: serviceUiTooltipSelector(state)
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
toggleTooltip: (data) => dispatch(toggleTooltip(data))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
)(Services);
|
)(Services);
|
||||||
|
@ -627,7 +627,10 @@
|
|||||||
"activity-feed",
|
"activity-feed",
|
||||||
"service-manifest",
|
"service-manifest",
|
||||||
"firewall"
|
"firewall"
|
||||||
]
|
],
|
||||||
|
"tooltip": {
|
||||||
|
"show": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"data": [{
|
"data": [{
|
||||||
"uuid": "081a792c-47e0-4439-924b-2efa9788ae9e",
|
"uuid": "081a792c-47e0-4439-924b-2efa9788ae9e",
|
||||||
|
@ -52,3 +52,5 @@ export const switchMonitorViewPage =
|
|||||||
createAction(`${APP}/SWITCH_MONITOR_VIEW_PAGE`);
|
createAction(`${APP}/SWITCH_MONITOR_VIEW_PAGE`);
|
||||||
export const handleNewProject =
|
export const handleNewProject =
|
||||||
createAction(`${APP}/CREATE_NEW_PROJECT`);
|
createAction(`${APP}/CREATE_NEW_PROJECT`);
|
||||||
|
export const toggleTooltip =
|
||||||
|
createAction(`${APP}/TOGGLE_QUICK_ACTIONS_TOOLTIP`);
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { handleActions } from 'redux-actions';
|
import { handleActions } from 'redux-actions';
|
||||||
import { addMetric, toggleServiceCollapsed } from '@state/actions';
|
import {
|
||||||
|
addMetric,
|
||||||
|
toggleServiceCollapsed,
|
||||||
|
toggleTooltip
|
||||||
|
} from '@state/actions';
|
||||||
import { toggleCollapsed } from '@state/reducers/common';
|
import { toggleCollapsed } from '@state/reducers/common';
|
||||||
|
|
||||||
const getMetrics = (stateMetrics, addMetric, metric) => {
|
const getMetrics = (stateMetrics, addMetric, metric) => {
|
||||||
@ -42,5 +46,31 @@ export default handleActions({
|
|||||||
action.payload.service,
|
action.payload.service,
|
||||||
action.payload.metric
|
action.payload.metric
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
[toggleTooltip.toString()]: (state, action) => {
|
||||||
|
|
||||||
|
const {
|
||||||
|
position,
|
||||||
|
service
|
||||||
|
} = action.payload;
|
||||||
|
|
||||||
|
const show = state.ui.tooltip.service !== service;
|
||||||
|
const tooltip = show ? {
|
||||||
|
show: true,
|
||||||
|
position: {
|
||||||
|
...position
|
||||||
|
},
|
||||||
|
service: service
|
||||||
|
} : {
|
||||||
|
show: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ui: {
|
||||||
|
...state.ui,
|
||||||
|
tooltip: tooltip
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}, {});
|
}, {});
|
||||||
|
@ -7,6 +7,7 @@ const account = (state) => get(state, 'account.data', {});
|
|||||||
const accountUi = (state) => get(state, 'account.ui', {});
|
const accountUi = (state) => get(state, 'account.ui', {});
|
||||||
const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
|
const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
|
||||||
const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
|
const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
|
||||||
|
const serviceUiTooltip = (state) => get(state, 'services.ui.tooltip', []);
|
||||||
const serviceUiSections = (state) => get(state, 'services.ui.sections', []);
|
const serviceUiSections = (state) => get(state, 'services.ui.sections', []);
|
||||||
const orgs = (state) => get(state, 'orgs.data', []);
|
const orgs = (state) => get(state, 'orgs.data', []);
|
||||||
const orgUI = (state) => get(state, 'orgs.ui', []);
|
const orgUI = (state) => get(state, 'orgs.ui', []);
|
||||||
@ -249,5 +250,6 @@ export {
|
|||||||
members as membersSelector,
|
members as membersSelector,
|
||||||
peopleByProjectId as peopleByProjectIdSelector,
|
peopleByProjectId as peopleByProjectIdSelector,
|
||||||
projectsUI as projectUISelector,
|
projectsUI as projectUISelector,
|
||||||
projectIndexById as projectIndexByIdSelect
|
projectIndexById as projectIndexByIdSelect,
|
||||||
|
serviceUiTooltip as serviceUiTooltipSelector
|
||||||
};
|
};
|
||||||
|
36
ui/src/components/tooltip/button.js
Normal file
36
ui/src/components/tooltip/button.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { colors } from '../../shared/constants';
|
||||||
|
import { unitcalc } from '../../shared/functions';
|
||||||
|
import Button from '../button';
|
||||||
|
|
||||||
|
const TooltipButton = styled(Button)`
|
||||||
|
width: 100%;
|
||||||
|
padding: ${unitcalc(1)} ${unitcalc(3)};
|
||||||
|
background-color: ${colors.base.white};
|
||||||
|
color: ${colors.base.secondary};
|
||||||
|
text-align: left;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
background-color: ${colors.base.white};
|
||||||
|
color: ${colors.base.primary};
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${colors.base.white};
|
||||||
|
color: ${colors.base.primary};
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:active:hover,
|
||||||
|
&:active:focus {
|
||||||
|
background-color: ${colors.base.white};
|
||||||
|
color: ${colors.base.primary};
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default TooltipButton;
|
@ -1,42 +1,60 @@
|
|||||||
import { remcalc } from '../../shared/functions';
|
import { remcalc, unitcalc } from '../../shared/functions';
|
||||||
import {
|
import {
|
||||||
|
absolutePosition,
|
||||||
baseBox,
|
baseBox,
|
||||||
pseudoEl,
|
pseudoEl,
|
||||||
Baseline,
|
Baseline,
|
||||||
moveZ
|
moveZ,
|
||||||
|
getMeasurement
|
||||||
} from '../../shared/composers';
|
} from '../../shared/composers';
|
||||||
import { colors } from '../../shared/constants';
|
import { boxes, colors, tooltipShadow } from '../../shared/constants';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const ItemPadder = 9;
|
const ItemPadder = 9;
|
||||||
const WrapperPadder = 24;
|
const WrapperPadder = 24;
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
${(props) => absolutePosition(props)}
|
||||||
|
`;
|
||||||
|
|
||||||
const StyledList = styled.ul`
|
const StyledList = styled.ul`
|
||||||
background: ${colors.base.white};
|
background: ${colors.base.white};
|
||||||
|
box-sizing: border-box;
|
||||||
color: ${colors.base.text};
|
color: ${colors.base.text};
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: ${unitcalc(2)} 0;
|
||||||
min-width: ${remcalc(200)};
|
/*min-width: ${remcalc(200)};*/
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
${(props) => {
|
||||||
|
return props.arrowPosition.left ?
|
||||||
|
`left: -${getMeasurement(props.arrowPosition.left)}` :
|
||||||
|
props.arrowPosition.right ?
|
||||||
|
`right: -${getMeasurement(props.arrowPosition.right)}` : null;
|
||||||
|
}};
|
||||||
|
|
||||||
${props => props.styles}
|
${props => props.styles}
|
||||||
${baseBox()}
|
${baseBox({
|
||||||
|
shadow: tooltipShadow
|
||||||
|
})}
|
||||||
|
|
||||||
${moveZ({
|
${moveZ({
|
||||||
amount: 1
|
amount: 1
|
||||||
})}
|
})}
|
||||||
|
|
||||||
& > * {
|
/*& > * {
|
||||||
|
|
||||||
padding: ${remcalc(ItemPadder)} ${remcalc(WrapperPadder)};
|
padding: ${remcalc(ItemPadder)} ${remcalc(WrapperPadder)};
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: ${colors.base.grey};
|
background: ${colors.base.grey};
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
&:after, &:before {
|
&:after, &:before {
|
||||||
border: solid transparent;
|
border: solid transparent;
|
||||||
@ -49,14 +67,14 @@ const StyledList = styled.ul`
|
|||||||
&:after {
|
&:after {
|
||||||
border-color: rgba(255, 255, 255, 0);
|
border-color: rgba(255, 255, 255, 0);
|
||||||
border-bottom-color: ${colors.base.white};
|
border-bottom-color: ${colors.base.white};
|
||||||
border-width: ${remcalc(10)};
|
border-width: ${remcalc(3)};
|
||||||
margin-left: ${remcalc(-10)};
|
margin-left: ${remcalc(-3)};
|
||||||
}
|
}
|
||||||
&:before {
|
&:before {
|
||||||
border-color: rgba(216, 216, 216, 0);
|
border-color: rgba(216, 216, 216, 0);
|
||||||
border-bottom-color: ${colors.base.greyDark};
|
border-bottom-color: ${colors.base.grey};
|
||||||
border-width: ${remcalc(12)};
|
border-width: ${remcalc(5)};
|
||||||
margin-left: ${remcalc(-12)};
|
margin-left: ${remcalc(-5)};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -64,13 +82,15 @@ const Tooltip = ({
|
|||||||
children,
|
children,
|
||||||
arrowPosition = {
|
arrowPosition = {
|
||||||
bottom: '100%',
|
bottom: '100%',
|
||||||
left: '10%'
|
left: '50%'
|
||||||
},
|
},
|
||||||
...props
|
...props
|
||||||
}) => (
|
}) => (
|
||||||
<StyledList arrowPosition={arrowPosition} {...props}>
|
<StyledContainer {...props}>
|
||||||
{children}
|
<StyledList arrowPosition={arrowPosition} {...props}>
|
||||||
</StyledList>
|
{children}
|
||||||
|
</StyledList>
|
||||||
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|
||||||
Tooltip.propTypes = {
|
Tooltip.propTypes = {
|
||||||
@ -81,3 +101,10 @@ Tooltip.propTypes = {
|
|||||||
export default Baseline(
|
export default Baseline(
|
||||||
Tooltip
|
Tooltip
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export { default as TooltipButton } from './button';
|
||||||
|
|
||||||
|
export const TooltipDivider = styled.div`
|
||||||
|
border-top: ${boxes.border.unchecked};
|
||||||
|
margin: ${unitcalc(1)} 0 ${unitcalc(1.5)} 0;
|
||||||
|
`;
|
||||||
|
@ -13,7 +13,8 @@ const GraphNode = ({
|
|||||||
connected,
|
connected,
|
||||||
data,
|
data,
|
||||||
index,
|
index,
|
||||||
onDragStart
|
onDragStart,
|
||||||
|
onQuickActions
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -38,7 +39,26 @@ const GraphNode = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onButtonClick = (evt) => {
|
const onButtonClick = (evt) => {
|
||||||
// console.log('Rect clicked!!!');
|
|
||||||
|
const tooltipPosition = {
|
||||||
|
x: data.x + Constants.buttonRect.x + Constants.buttonRect.width/2,
|
||||||
|
y: data.y + Constants.buttonRect.y + Constants.buttonRect.height
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( connected ) {
|
||||||
|
tooltipPosition.x = tooltipPosition.x + left;
|
||||||
|
tooltipPosition.y = tooltipPosition.y + top;
|
||||||
|
}
|
||||||
|
|
||||||
|
const d = {
|
||||||
|
service: data.uuid,
|
||||||
|
position: {
|
||||||
|
left: tooltipPosition.x,
|
||||||
|
top: tooltipPosition.y
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onQuickActions(evt, d);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStart = (evt) => {
|
const onStart = (evt) => {
|
||||||
@ -102,7 +122,8 @@ GraphNode.propTypes = {
|
|||||||
connected: React.PropTypes.bool,
|
connected: React.PropTypes.bool,
|
||||||
data: React.PropTypes.object.isRequired,
|
data: React.PropTypes.object.isRequired,
|
||||||
index: React.PropTypes.number.isRequired,
|
index: React.PropTypes.number.isRequired,
|
||||||
onDragStart: React.PropTypes.func
|
onDragStart: React.PropTypes.func,
|
||||||
|
onQuickActions: React.PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Baseline(
|
export default Baseline(
|
||||||
|
@ -88,7 +88,7 @@ class TopologyGraph extends React.Component {
|
|||||||
const n = Math.ceil(
|
const n = Math.ceil(
|
||||||
Math.log(
|
Math.log(
|
||||||
nextSimulation.alphaMin()) / Math.log(
|
nextSimulation.alphaMin()) / Math.log(
|
||||||
1 - nextSimulation.alphaDecay())) - 200;
|
1 - nextSimulation.alphaDecay()));
|
||||||
for (var i = 0; i < n; ++i) {
|
for (var i = 0; i < n; ++i) {
|
||||||
nextSimulation.tick();
|
nextSimulation.tick();
|
||||||
}
|
}
|
||||||
@ -104,7 +104,10 @@ class TopologyGraph extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const services = this.props.services;
|
const {
|
||||||
|
onQuickActions,
|
||||||
|
services
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
nodes,
|
nodes,
|
||||||
@ -218,6 +221,7 @@ class TopologyGraph extends React.Component {
|
|||||||
data={n}
|
data={n}
|
||||||
index={index}
|
index={index}
|
||||||
onDragStart={onDragStart}
|
onDragStart={onDragStart}
|
||||||
|
onQuickActions={onQuickActions}
|
||||||
connected={n.id !== 'consul'}
|
connected={n.id !== 'consul'}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
@ -250,6 +254,7 @@ class TopologyGraph extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TopologyGraph.propTypes = {
|
TopologyGraph.propTypes = {
|
||||||
|
onQuickActions: React.PropTypes.func,
|
||||||
services: React.PropTypes.array
|
services: React.PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import camelCase from 'camel-case';
|
import camelCase from 'camel-case';
|
||||||
|
import isString from 'lodash.isstring';
|
||||||
import { boxes, colors } from '../constants';
|
import { boxes, colors } from '../constants';
|
||||||
import { unitcalc, remcalc } from '../functions';
|
import { unitcalc, remcalc } from '../functions';
|
||||||
|
|
||||||
@ -82,15 +83,25 @@ export const baseBox = ({
|
|||||||
box-shadow: ${shadow};
|
box-shadow: ${shadow};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const getMeasurement = (measurement) =>
|
||||||
|
isString(measurement) ? measurement :
|
||||||
|
!isNaN(measurement) ? `${measurement}px`: 'auto';
|
||||||
|
|
||||||
|
export const absolutePosition = (
|
||||||
|
positions = {}
|
||||||
|
) => css`
|
||||||
|
position: absolute;
|
||||||
|
top: ${getMeasurement(positions.top)};
|
||||||
|
right: ${getMeasurement(positions.right)};
|
||||||
|
bottom: ${getMeasurement(positions.bottom)};
|
||||||
|
left: ${getMeasurement(positions.left)};
|
||||||
|
`;
|
||||||
|
|
||||||
export const pseudoEl = (
|
export const pseudoEl = (
|
||||||
positions = {}
|
positions = {}
|
||||||
) => css`
|
) => css`
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
${absolutePosition(positions)};
|
||||||
top: ${positions.top || 'auto'};
|
|
||||||
right: ${positions.right || 'auto'};
|
|
||||||
bottom: ${positions.bottom || 'auto'};
|
|
||||||
left: ${positions.left || 'auto'};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const clearfix = css`
|
export const clearfix = css`
|
||||||
|
@ -5,6 +5,8 @@ export const borderRadius = remcalc(4);
|
|||||||
export const bottomShaddow = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.05)`;
|
export const bottomShaddow = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.05)`;
|
||||||
export const bottomShaddowDarker = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.1)`;
|
export const bottomShaddowDarker = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.1)`;
|
||||||
export const insetShaddow = `inset 0 ${remcalc(3)} 0 0 rgba(0, 0, 0, 0.05)`;
|
export const insetShaddow = `inset 0 ${remcalc(3)} 0 0 rgba(0, 0, 0, 0.05)`;
|
||||||
|
export const tooltipShadow =
|
||||||
|
`0 ${remcalc(2)} ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)`;
|
||||||
|
|
||||||
export const border = {
|
export const border = {
|
||||||
checked: `${remcalc(1)} solid ${base.primary}`,
|
checked: `${remcalc(1)} solid ${base.primary}`,
|
||||||
|
Loading…
Reference in New Issue
Block a user