UNPKG

stitch-ui

Version:

198 lines (189 loc) 6.44 kB
/* 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 };