Stubs for adding and deleting a rule
This commit is contained in:
parent
e5cf2962dc
commit
6fbbe9a497
4 changed files with 117 additions and 25 deletions
|
@ -45,6 +45,8 @@
|
||||||
"css-loader": "^0.28.4",
|
"css-loader": "^0.28.4",
|
||||||
"i18next-conv": "^3.0.3",
|
"i18next-conv": "^3.0.3",
|
||||||
"node-sass": "^4.5.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",
|
"sass-loader": "^6.0.6",
|
||||||
"style-loader": "^0.18.2",
|
"style-loader": "^0.18.2",
|
||||||
"url-loader": "^0.5.9",
|
"url-loader": "^0.5.9",
|
||||||
|
|
|
@ -12,11 +12,16 @@ import {DeleteModalDialog} from "../../lib/delete";
|
||||||
import interoperableErrors from '../../../../shared/interoperable-errors';
|
import interoperableErrors from '../../../../shared/interoperable-errors';
|
||||||
|
|
||||||
import styles from './CUD.scss';
|
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 SortableTree from 'react-sortable-tree';
|
||||||
import {ActionLink, Icon} from "../../lib/bootstrap-components";
|
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()
|
@translate()
|
||||||
@withForm
|
@withForm
|
||||||
@withPageHelpers
|
@withPageHelpers
|
||||||
|
@ -28,6 +33,7 @@ export default class CUD extends Component {
|
||||||
|
|
||||||
this.compoundRuleTypes = [ 'all', 'some', 'one', 'none' ];
|
this.compoundRuleTypes = [ 'all', 'some', 'one', 'none' ];
|
||||||
|
|
||||||
|
/*
|
||||||
const allRule = {
|
const allRule = {
|
||||||
type: 'all'
|
type: 'all'
|
||||||
};
|
};
|
||||||
|
@ -69,11 +75,11 @@ export default class CUD extends Component {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
rules: sampleRules,
|
rules: [],
|
||||||
rulesTree: this.getTreeFromRules(sampleRules)
|
rulesTree: this.getTreeFromRules([])
|
||||||
};
|
};
|
||||||
|
|
||||||
this.initForm();
|
this.initForm();
|
||||||
|
@ -89,7 +95,7 @@ export default class CUD extends Component {
|
||||||
getRulesFromTree(tree) {
|
getRulesFromTree(tree) {
|
||||||
const rules = [];
|
const rules = [];
|
||||||
for (const node of tree) {
|
for (const node of tree) {
|
||||||
const rule = Object.assign({}, node.rule);
|
const rule = node.rule;
|
||||||
rule.rules = this.getRulesFromTree(node.children);
|
rule.rules = this.getRulesFromTree(node.children);
|
||||||
rules.push(rule);
|
rules.push(rule);
|
||||||
}
|
}
|
||||||
|
@ -185,16 +191,49 @@ export default class CUD extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onRuleDelete(data) {
|
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({
|
this.setState({
|
||||||
ruleOptionsVisible: true
|
ruleOptionsVisible: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async onRuleTree() {
|
async hideRuleOptions() {
|
||||||
this.setState({
|
this.setState({
|
||||||
ruleOptionsVisible: false
|
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() {
|
render() {
|
||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
const isEdit = !!this.props.entity;
|
const isEdit = !!this.props.entity;
|
||||||
|
@ -251,18 +312,31 @@ export default class CUD extends Component {
|
||||||
|
|
||||||
<div className={styles.rulePane + ruleOptionsVisibilityClass}>
|
<div className={styles.rulePane + ruleOptionsVisibilityClass}>
|
||||||
<div className={styles.leftPane}>
|
<div className={styles.leftPane}>
|
||||||
<SortableTree
|
<div className={styles.leftPaneInner}>
|
||||||
treeData={this.state.rulesTree}
|
<Toolbar>
|
||||||
onChange={rulesTree => this.onRulesChanged(rulesTree)}
|
<Button className="btn-primary" label={t('Add Composite Rule')} onClickAsync={::this.addCompositeRule}/>
|
||||||
isVirtualized={false}
|
<Button className="btn-primary" label={t('Add Rule')} onClickAsync={::this.addRule}/>
|
||||||
canDrop={ data => !data.nextParent || this.compoundRuleTypes.includes(data.nextParent.rule.type) }
|
</Toolbar>
|
||||||
generateNodeProps={data => ({
|
|
||||||
buttons: [
|
<h3>{t('Rules')}</h3>
|
||||||
<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="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} />
|
<div className={styles.leftPaneOverlay} />
|
||||||
|
|
||||||
|
@ -272,13 +346,13 @@ export default class CUD extends Component {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.rightPane}>
|
<div className={styles.rightPane}>
|
||||||
<div className={styles.rulePaneRightInner}>
|
<div className={styles.rightPaneInner}>
|
||||||
<div className={styles.ruleOptions}>
|
<div className={styles.ruleOptions}>
|
||||||
<h3>{t('Rule Options')}</h3>
|
<h3>{t('Rule Options')}</h3>
|
||||||
<InputField id="name" label={t('Name')}/>
|
<InputField id="name" label={t('Name')}/>
|
||||||
|
|
||||||
<ButtonRow>
|
<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>
|
</ButtonRow>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,7 +21,23 @@ $desktopAnimationStartPosition: 300px;
|
||||||
|
|
||||||
.leftPane {
|
.leftPane {
|
||||||
display: inline-block;
|
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 {
|
.leftPaneOverlay {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -81,7 +97,7 @@ $desktopAnimationStartPosition: 300px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
||||||
.rulePaneRightInner {
|
.rightPaneInner {
|
||||||
margin-right: $mobileLeftPaneResidualWidth;
|
margin-right: $mobileLeftPaneResidualWidth;
|
||||||
@media (min-width: $desktopMinWidth) {
|
@media (min-width: $desktopMinWidth) {
|
||||||
margin-right: $desktopLeftPaneResidualWidth;
|
margin-right: $desktopLeftPaneResidualWidth;
|
||||||
|
|
|
@ -18,7 +18,7 @@ module.exports = {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(js|jsx)$/,
|
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' ]
|
use: [ 'babel-loader' ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue