stitch-ui
Version:
198 lines (189 loc) • 6.44 kB
JavaScript
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import React from "react";
import PropTypes from "prop-types";
import {
Button,
Banner,
Tooltip,
Spinner,
Panel,
Tabs,
Tab
} from "../../../core";
import { AlertContainer } from "../../../alert";
import FilterRules from "./FilterRules";
import { MongoDBServiceRule, FieldRule } from "../mongodb_rule";
import FieldBrowseEditor from "./FieldBrowseEditor";
const alertKey = id => `mongodb rule/${id}`;
export default class RuleEditor extends React.Component {
constructor(props) {
super(props);
this.state = { activeTab: "fields" };
this.save = this.save.bind(this);
}
setActiveTab(activeTab) {
this.setState({ activeTab });
}
save() {
const { setRule, updateRule, addAlert } = this.props;
let { rule } = this.props;
const parsedFieldRules = rule.fieldRules.parseInputs();
rule = rule.parseFilters().set("fieldRules", parsedFieldRules);
setRule(rule.set("fieldRules", parsedFieldRules));
if (
parsedFieldRules.hasError ||
parsedFieldRules.hasChildError ||
rule.filtersHasError
) {
return Promise.resolve();
}
const ruleToSave = rule.toRawRule();
return updateRule(rule._id, ruleToSave)
.then(() => {
addAlert(alertKey(rule._id), "Saved.");
})
.then(this.props.reloadService);
}
render() {
const {
setEditingPath,
addFilter,
removeFilter,
discardFilterChanges,
setFieldType,
ruleSaveState,
ruleEditState,
rule,
editingFieldRule
} = this.props;
if (!rule) {
return null;
}
const { setOtherFieldsEnabled, changePermissionsField } = this.props;
const { setFilterWhenInput, setFilterMatchInput } = this.props;
const { saving, error } = ruleSaveState;
return (
<Panel>
<div className="panel-header">
<div className="panel-header-title">
{rule.namespace}
</div>
<div className="panel-header-actions">
<Spinner open={saving} />
<AlertContainer alertKey={alertKey(rule._id)} />
{(rule.dirty || rule.fieldRules.dirty) &&
<span>
<i>You have unsaved changes.</i>
</span>}
<Button
primary
small
disabled={!(rule.fieldRules.dirty || rule.dirty) || saving}
onClick={this.save}
>
Save
</Button>
<Button
default
small
onClick={() => {
this.props.deleteRule(rule._id, rule.namespace);
}}
>
Delete
</Button>
</div>
</div>
<div>
<Tabs>
<Tab
onClick={() => this.setActiveTab("filters")}
active={this.state.activeTab === "filters"}
>
<a className="section-header-tab-link">
Filters
<Tooltip
dataFor="filter-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
Filters are applied to documents when specified conditions are
met. Filters are applied before rules.
</Tooltip>
</a>
</Tab>
<Tab
onClick={() => this.setActiveTab("fields")}
active={this.state.activeTab === "fields"}
>
<a className="section-header-tab-link">
Field Rules
<Tooltip
dataFor="field-rule-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
Field Rules control access to fields for read and write
operations.
</Tooltip>
</a>
</Tab>
</Tabs>
<FilterRules
open={this.state.activeTab === "filters"}
setFilterWhenInput={setFilterWhenInput}
setFilterMatchInput={setFilterMatchInput}
discardFilterChanges={i => discardFilterChanges(rule._id, i)}
filters={rule.filters}
addFilter={() => addFilter(rule._id)}
removeFilter={index => removeFilter(rule._id, index)}
/>
<FieldBrowseEditor
open={this.state.activeTab === "fields"}
changePermissionsField={changePermissionsField}
discardPermissionsFieldChanges={
this.props.discardPermissionsFieldChanges
}
setEditingPath={setEditingPath}
setOtherFieldsEnabled={setOtherFieldsEnabled}
ruleEditState={ruleEditState}
rule={rule}
setFieldType={setFieldType}
editingFieldRule={editingFieldRule}
/>
{rule.fieldRules.hasChildError &&
<div className="error">
Rule contains fields with error (highlighted in red above)
</div>}
<Banner message={error} error />
</div>
</Panel>
);
}
}
RuleEditor.propTypes = {
setRule: PropTypes.func.isRequired,
reloadService: PropTypes.func.isRequired,
updateRule: PropTypes.func.isRequired,
addAlert: PropTypes.func.isRequired,
rule: PropTypes.instanceOf(MongoDBServiceRule).isRequired,
addFilter: PropTypes.func.isRequired,
removeFilter: PropTypes.func.isRequired,
setFieldType: PropTypes.func.isRequired,
deleteRule: PropTypes.func.isRequired,
discardFilterChanges: PropTypes.func.isRequired,
discardPermissionsFieldChanges: PropTypes.func.isRequired,
ruleSaveState: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
ruleEditState: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
editingFieldRule: PropTypes.instanceOf(FieldRule),
setEditingPath: PropTypes.func.isRequired,
setOtherFieldsEnabled: PropTypes.func.isRequired,
changePermissionsField: PropTypes.func.isRequired,
setFilterWhenInput: PropTypes.func.isRequired,
setFilterMatchInput: PropTypes.func.isRequired
};
RuleEditor.defaultProps = {
editingFieldRule: null
};