Stubs for adding and deleting a rule

This commit is contained in:
Tomas Bures 2017-08-16 21:41:36 +02:00
parent e5cf2962dc
commit 6fbbe9a497
4 changed files with 117 additions and 25 deletions

View file

@ -45,6 +45,8 @@
"css-loader": "^0.28.4",
"i18next-conv": "^3.0.3",
"node-sass": "^4.5.3",
"react-dnd-html5-backend": "^2.4.1",
"react-dnd-touch-backend": "^0.3.13",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",

View file

@ -12,11 +12,16 @@ import {DeleteModalDialog} from "../../lib/delete";
import interoperableErrors from '../../../../shared/interoperable-errors';
import styles from './CUD.scss';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import TouchBackend from 'react-dnd-touch-backend';
import SortableTree from 'react-sortable-tree';
import {ActionLink, Icon} from "../../lib/bootstrap-components";
console.log(styles);
// https://stackoverflow.com/a/4819886/1601953
const isTouchDevice = !!('ontouchstart' in window || navigator.maxTouchPoints);
@DragDropContext(isTouchDevice ? TouchBackend : HTML5Backend)
@translate()
@withForm
@withPageHelpers
@ -28,6 +33,7 @@ export default class CUD extends Component {
this.compoundRuleTypes = [ 'all', 'some', 'one', 'none' ];
/*
const allRule = {
type: 'all'
};
@ -69,11 +75,11 @@ export default class CUD extends Component {
]
}
];
*/
this.state = {
rules: sampleRules,
rulesTree: this.getTreeFromRules(sampleRules)
rules: [],
rulesTree: this.getTreeFromRules([])
};
this.initForm();
@ -89,7 +95,7 @@ export default class CUD extends Component {
getRulesFromTree(tree) {
const rules = [];
for (const node of tree) {
const rule = Object.assign({}, node.rule);
const rule = node.rule;
rule.rules = this.getRulesFromTree(node.children);
rules.push(rule);
}
@ -185,16 +191,49 @@ export default class CUD extends Component {
}
async onRuleDelete(data) {
console.log(data);
let finishedSearching = false;
function childrenWithoutRule(rules) {
console.log(rules);
const newRules = [];
for (const rule of rules) {
if (finishedSearching) {
newRules.push(rule);
} else if (rule !== data.node.rule) {
const newRule = Object.assign({}, rule);
if (rule.rules) {
newRule.rules = childrenWithoutRule(rule.rules);
}
newRules.push(newRule);
} else {
finishedSearching = true;
}
}
return newRules;
}
const rules = childrenWithoutRule(this.state.rules);
console.log(rules);
this.setState({
rules,
rulesTree: this.getTreeFromRules(rules)
});
}
async onRuleOptions(data) {
async showRuleOptions(data) {
this.setState({
ruleOptionsVisible: true
});
}
async onRuleTree() {
async hideRuleOptions() {
this.setState({
ruleOptionsVisible: false
});
@ -207,6 +246,28 @@ export default class CUD extends Component {
})
}
_addRule(type) {
const rules = this.state.rules;
rules.push({
type,
rules: []
});
this.setState({
rules,
rulesTree: this.getTreeFromRules(rules)
});
}
async addCompositeRule() {
this._addRule('all');
}
async addRule() {
this._addRule('eq');
}
render() {
const t = this.props.t;
const isEdit = !!this.props.entity;
@ -251,18 +312,31 @@ export default class CUD extends Component {
<div className={styles.rulePane + ruleOptionsVisibilityClass}>
<div className={styles.leftPane}>
<SortableTree
treeData={this.state.rulesTree}
onChange={rulesTree => this.onRulesChanged(rulesTree)}
isVirtualized={false}
canDrop={ data => !data.nextParent || this.compoundRuleTypes.includes(data.nextParent.rule.type) }
generateNodeProps={data => ({
buttons: [
<ActionLink onClickAsync={async () => await this.onRuleOptions(data)} className={styles.ruleActionLink}><Icon name="edit"/></ActionLink>,
<ActionLink onClickAsync={async () => await this.onRuleDelete(data)} className={styles.ruleActionLink}><Icon name="remove"/></ActionLink>
]
})}
/>
<div className={styles.leftPaneInner}>
<Toolbar>
<Button className="btn-primary" label={t('Add Composite Rule')} onClickAsync={::this.addCompositeRule}/>
<Button className="btn-primary" label={t('Add Rule')} onClickAsync={::this.addRule}/>
</Toolbar>
<h3>{t('Rules')}</h3>
<div className="clearfix"/>
<div className={styles.ruleTree}>
<SortableTree
treeData={this.state.rulesTree}
onChange={rulesTree => this.onRulesChanged(rulesTree)}
isVirtualized={false}
canDrop={ data => !data.nextParent || this.compoundRuleTypes.includes(data.nextParent.rule.type) }
generateNodeProps={data => ({
buttons: [
<ActionLink onClickAsync={async () => await this.showRuleOptions(data)} className={styles.ruleActionLink}><Icon name="edit"/></ActionLink>,
<ActionLink onClickAsync={async () => await this.onRuleDelete(data)} className={styles.ruleActionLink}><Icon name="remove"/></ActionLink>
]
})}
/>
</div>
</div>
<div className={styles.leftPaneOverlay} />
@ -272,13 +346,13 @@ export default class CUD extends Component {
</div>
<div className={styles.rightPane}>
<div className={styles.rulePaneRightInner}>
<div className={styles.rightPaneInner}>
<div className={styles.ruleOptions}>
<h3>{t('Rule Options')}</h3>
<InputField id="name" label={t('Name')}/>
<ButtonRow>
<Button className="btn-primary" icon="chevron-left" label={t('Back')} onClickAsync={::this.onRuleTree}/>
<Button className="btn-primary" icon="chevron-left" label={t('Back')} onClickAsync={::this.hideRuleOptions}/>
</ButtonRow>
</div>
</div>

View file

@ -21,7 +21,23 @@ $desktopAnimationStartPosition: 300px;
.leftPane {
display: inline-block;
width: 0px;
width: 100%;
margin-right: -100%;
.leftPaneInner {
.ruleTree {
background: #fbfbfb;
border: #cfcfcf 1px solid;
border-radius: 3px;
padding: 10px 0px;
margin-top: 15px;
margin-bottom: 30px;
// Without this, the placeholders when rearranging the tree are not shown
position: relative;
z-index: 0;
}
}
.leftPaneOverlay {
display: none;
@ -81,7 +97,7 @@ $desktopAnimationStartPosition: 300px;
opacity: 0;
visibility: hidden;
.rulePaneRightInner {
.rightPaneInner {
margin-right: $mobileLeftPaneResidualWidth;
@media (min-width: $desktopMinWidth) {
margin-right: $desktopLeftPaneResidualWidth;

View file

@ -18,7 +18,7 @@ module.exports = {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(disposables)/ /* https://github.com/react-dnd/react-dnd/issues/407 */,
exclude: /(disposables|react-dnd-touch-backend)/ /* https://github.com/react-dnd/react-dnd/issues/407 */,
use: [ 'babel-loader' ]
},
{