stitch-ui
Version:
196 lines (192 loc) • 6.41 kB
JavaScript
// TODO proptypes
/* eslint-disable react/prop-types */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import React from "react";
import { OrderedMap } from "immutable";
import classNames from "classnames";
import FontAwesome from "react-fontawesome";
import FieldRuleDisplay from "./FieldRuleDisplay";
import FieldRuleValueDisplay from "./FieldRuleValueDisplay";
import TypePicker from "./TypePicker";
import Indent from "./Indent";
import { baseFieldPropTypes, baseFieldDefaultProps } from "../proptypes";
import OtherFieldsRuleDisplay from "./OtherFieldsRuleDisplay";
import AddFieldForm from "./AddFieldForm";
import { Confirm, Button } from "../../../core";
export default class FieldRuleObjectDisplay extends React.Component {
constructor(props) {
super(props);
this.state = { showAddFieldForm: false };
this.handleMouseEnter = this.handleMouseEnter.bind(this);
this.handleMouseLeave = this.handleMouseLeave.bind(this);
this.removeField = this.removeField.bind(this);
}
removeField() {
const { dottedFullPath } = this.props.fieldRule;
return Confirm.confirm(
`Are you sure you want to delete field ${dottedFullPath}?`
).then(
() => this.props.removeField(this.props.rule._id, dottedFullPath),
() => Promise.resolve()
);
}
handleMouseEnter() {
if (!this.props.fieldRule.dottedFullPath) {
return;
}
this.props.pushHoveringPath(
this.props.rule._id,
this.props.fieldRule.dottedFullPath,
false
);
}
handleMouseLeave() {
if (!this.props.fieldRule.dottedFullPath) {
return;
}
this.props.popHoveringPath(this.props.rule._id);
}
render() {
const {
rule,
fieldRule,
addField,
depth,
setFieldType,
editingPath,
hoveringPath
} = this.props;
const { setNewFieldInput, setEditingPath } = this.props;
const isActive =
depth > 0 &&
editingPath &&
editingPath.path === fieldRule.dottedFullPath &&
!editingPath.elements &&
!editingPath.other;
const isHovering =
depth > 0 &&
hoveringPath &&
hoveringPath.length > 0 &&
hoveringPath[hoveringPath.length - 1].path === fieldRule.dottedFullPath &&
!hoveringPath[hoveringPath.length - 1].elements &&
!hoveringPath[hoveringPath.length - 1].other;
return (
<div
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onClick={e => {
e.stopPropagation();
if (fieldRule.dottedFullPath) {
setEditingPath(rule._id, fieldRule.dottedFullPath, false);
}
}}
className={classNames("mongo-schema", {
"mongo-schema-is-hovering": isHovering,
"mongo-schema-is-editing": isActive,
"mongo-schema-field-is-dirty":
this.props.fieldRule.dirty && this.props.fieldRule.path
})}
>
<div
className={classNames("mongo-schema-field", {
"mongo-schema-field-is-editing":
isActive && this.props.fieldRule.path,
"mongo-schema-field-is-dirty":
this.props.fieldRule.dirty && this.props.fieldRule.path
})}
>
{depth > 0 &&
<span className="mongo-schema-fieldname">
<Indent size={depth} />
<span
className={classNames("mongo-schema-mono", {
"mongo-schema-field-has-error": this.props.fieldRule.hasError
})}
>
{fieldRule.path}
</span>
<span className="mongo-schema-colon">:</span>
</span>}
{depth > 0 &&
<span className="mongo-schema-mono">
{"{"}
</span>}
{depth > 0 &&
<span className="mongo-schema-value">
<TypePicker
editingFieldRule={fieldRule}
setFieldType={(path, type) =>
setFieldType(rule._id, path, type)}
/>
<FieldRuleValueDisplay
perms={fieldRule.permissions}
shadows={rule.getShadows(
fieldRule.dottedFullPath,
false,
false
)}
/>
<FontAwesome
name="times-circle"
className={classNames("mongo-schema-field-control", {
"mongo-schema-field-control-is-hidden":
!isHovering || depth === 0
})}
onClick={this.removeField}
/>
</span>}
</div>
<span>
{(fieldRule.fields || new OrderedMap())
.entrySeq()
.map(([fieldName, field]) =>
<FieldRuleDisplay
rule={rule}
depth={depth + 1}
key={fieldName}
fieldRule={field}
setFieldType={setFieldType}
/>
)
.toArray()}
</span>
<OtherFieldsRuleDisplay
fieldRule={fieldRule}
depth={depth}
rule={rule}
/>
<div className="mongo-schema-field">
<Indent size={depth + 1} />
{fieldRule.newFieldPath !== null
? <AddFieldForm
rootPath={fieldRule.dottedFullPath}
newFieldInput={fieldRule.newFieldPath}
addField={(rootPath, field) =>
addField(rule._id, rootPath, field)}
setNewFieldInput={x =>
setNewFieldInput(rule._id, fieldRule.dottedFullPath, x)}
cancelAddField={() =>
setNewFieldInput(rule._id, fieldRule.dottedFullPath, null)}
/>
: <Button
small
default
onClick={e => {
e.stopPropagation();
setNewFieldInput(rule._id, fieldRule.dottedFullPath, "");
}}
>
+ Add…
</Button>}
</div>
{depth > 0 &&
<span className="mongo-schema-mono">
<Indent size={depth} />
{"}"}
</span>}
</div>
);
}
}
FieldRuleObjectDisplay.propTypes = baseFieldPropTypes;
FieldRuleObjectDisplay.defaultProps = baseFieldDefaultProps;