stitch-ui
Version:
305 lines (272 loc) • 8.87 kB
JavaScript
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import React from "react";
import PropTypes from "prop-types";
import DropdownMenu from "react-dd-menu";
import { connect } from "react-redux";
import { Route, Switch, Redirect } from "react-router-dom";
import * as serviceActions from "../actions";
import * as appActions from "../../app/actions";
import { Banner, NavItem, Spinner, Confirm, Button } from "../../core";
import {
servicesByType,
SVCTYPE_MONGODB_ATLAS,
CONFIG_TAB,
RULES_TAB,
INCOMING_WEBHOOK_TAB
} from "../registry";
import { EditConfig, EditRules } from "../../service";
import EditIncomingWebhooks from "../../incomingwebhooks/components/EditIncomingWebhooks";
class EditService extends React.Component {
constructor(props, context) {
super(props, context);
this.state = { dropdownOpen: false };
this.remove = this.remove.bind(this);
}
componentDidMount() {
const {
app: { groupId, _id },
match: { params: { svcname } }
} = this.props;
this.props.loadSvc(groupId, _id, svcname);
}
componentWillReceiveProps(nextProps) {
const {
app: { _id: appId },
match: { params: { svcname: svcName } }
} = this.props;
const {
app: { _id: nextAppId, groupId },
match: { params: { svcname: nextSvcName } }
} = nextProps;
if (appId !== nextAppId || svcName !== nextSvcName) {
this.props.loadSvc(groupId, appId, nextSvcName, true);
}
}
remove() {
const {
app: { _id: appId, groupId },
match: { params: { svcname: svcName } }
} = this.props;
return Confirm.confirm(
`Are you sure you want to delete service '${svcName}'?`
).then(
() =>
this.props
.deleteService(groupId, appId, svcName)
.then(() => this.props.loadServices(groupId, appId)),
() => Promise.resolve()
);
}
render() {
const { service } = this.props;
if (!service) {
return null;
}
const {
app,
client,
loadingSvc,
switchingSvc,
error,
loadSvc,
match,
settings
} = this.props;
const {
service: { name: svcname },
app: { _id: appId, groupId }
} = this.props;
const configProps = {
client,
svcname,
app,
service,
onUpdate: loadSvc,
settings
};
if (loadingSvc && switchingSvc) {
return (
<div>
<div className="section-header section-header-has-tabs">
<div className="section-header-title">
<div className="section-header-title-text">
<Spinner open xlarge />
</div>
</div>
</div>
</div>
);
}
const menuOptions = {
isOpen: this.state.dropdownOpen,
close: () => {
this.setState({ dropdownOpen: false });
},
toggle: (
<Button
small
className="button-is-dropdowntoggle"
onClick={() => {
this.setState({ dropdownOpen: !this.state.dropdownOpen });
}}
>
<i className="mms-icon-ellipsis" />
</Button>
),
align: "right"
};
const activeService = servicesByType.get(service.type);
const matchedService = app.services[match.params.svcname];
const defaultRedirect = matchedService
? `${match.url}/${servicesByType.get(matchedService.type).defaultTab}`
: `${match.url}/`;
let serviceType = service.type;
if (service.type === "mongodb") {
serviceType = "Collections";
} else {
serviceType = "Rules";
}
return (
<div>
<div className="section-header section-header-has-tabs">
<div className="section-header-title">
<div className="section-header-title-icon">
{React.createElement(activeService.icon, {
className:
"rich-radio-illustration-item rich-radio-illustration-item-is-active"
})}
</div>
<div className="section-header-title-text">
{svcname}
</div>
{service.type !== SVCTYPE_MONGODB_ATLAS &&
<div className="section-header-title-controls">
<DropdownMenu {...menuOptions}>
<li onClick={this.remove}>
<a>Delete</a>
</li>
</DropdownMenu>
</div>}
<Banner message={error} error />
<Spinner open={loadingSvc} xlarge />
</div>
<ul className="section-header-tabs">
{activeService.configEditor &&
<NavItem
to={`/groups/${groupId}/apps/${appId}/services/${svcname}/${CONFIG_TAB}`}
className="section-header-tab apptabs-services section-header-tab-is-left"
linkClassName="section-header-tab-link"
activeClassName="section-header-tab-is-active"
>
Config
</NavItem>}
{activeService.incomingWebhooks &&
<NavItem
to={`/groups/${groupId}/apps/${appId}/services/${svcname}/${INCOMING_WEBHOOK_TAB}`}
className="section-header-tab apptabs-auth"
linkClassName="section-header-tab-link"
activeClassName="section-header-tab-is-active"
>
Incoming Webhooks
</NavItem>}
{activeService.actions.size > 0 &&
<NavItem
to={`/groups/${groupId}/apps/${appId}/services/${svcname}/${RULES_TAB}`}
className="section-header-tab section-header-tab-is-right apptabs-variables"
linkClassName="section-header-tab-link"
activeClassName="section-header-tab-is-active"
>
{serviceType}
</NavItem>}
</ul>
</div>
<div className="tabs-content">
{this.props.children}
</div>
<Switch>
<Redirect exact from={`${match.url}/`} to={defaultRedirect} />
<Route
// disallow GCM from being accessed like a service
exact
path={`/groups/${groupId}/apps/${appId}/services/gcm/:tab`}
render={({ match: { params } }) =>
<Redirect
to={`/groups/${groupId}/apps/${appId}/push/${params.tab}`}
/>}
/>
<Route
path={`${match.url}/${CONFIG_TAB}`}
render={routeProps =>
<EditConfig {...routeProps} {...configProps} />}
/>
<Route
path={`${match.url}/${RULES_TAB}`}
render={routeProps =>
<EditRules {...routeProps} {...configProps} />}
/>
<Route
path={`${match.url}/${INCOMING_WEBHOOK_TAB}`}
render={routeProps =>
<EditIncomingWebhooks {...routeProps} {...configProps} />}
/>
</Switch>
</div>
);
}
}
const mapStateToProps = state => {
const { client } = state.base;
const { app, services, error } = state.app.root;
const { service, loadingSvc, switchingSvc } = state.service.base;
return { app, client, services, error, service, loadingSvc, switchingSvc };
};
const mapDispatchToProps = (dispatch, ownProps) => ({
loadServices: (groupId, appId) =>
dispatch(appActions.loadServices(groupId, appId)),
loadSvc: (groupId, appId, svcName, switching) => {
dispatch(serviceActions.loadSvc(groupId, appId, svcName, { switching }));
},
deleteService: (groupId, appId, svcName) =>
dispatch(serviceActions.deleteSvc(groupId, appId, svcName)).then(() =>
ownProps.history.replace(`/groups/${groupId}/apps/${appId}`)
),
resetError: () => {
dispatch(serviceActions.resetError());
}
});
EditService.contextTypes = {
router: PropTypes.object
};
/* eslint-disable react/forbid-prop-types */
EditService.propTypes = {
// params: PropTypes.shape({
// svcname: PropTypes.string,
// appId: PropTypes.string,
// groupId: PropTypes.string
// }).isRequired,
deleteService: PropTypes.func.isRequired,
loadSvc: PropTypes.func.isRequired,
loadServices: PropTypes.func.isRequired,
service: PropTypes.object,
app: PropTypes.object,
switchingSvc: PropTypes.bool,
loadingSvc: PropTypes.bool,
children: PropTypes.any,
error: PropTypes.string,
match: PropTypes.object,
settings: PropTypes.object,
client: PropTypes.object
};
EditService.defaultProps = {
children: null,
app: null,
service: null,
switchingSvc: false,
loadingSvc: false,
error: "",
match: null,
settings: null,
client: null
};
export default connect(mapStateToProps, mapDispatchToProps)(EditService);