From 3b9ee93eb32a2a12d8ac03237b750cd93bb840c7 Mon Sep 17 00:00:00 2001 From: Felix Henninger Date: Sat, 15 Aug 2020 09:51:18 +0200 Subject: [PATCH] Port factorial design generator --- .../Loop/DesignWizard/FactorialModal.js | 155 ++++++++++++++++++ .../components/Content/Loop/Grid/footer.js | 10 +- 2 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 packages/builder/src/components/ComponentOptions/components/Content/Loop/DesignWizard/FactorialModal.js diff --git a/packages/builder/src/components/ComponentOptions/components/Content/Loop/DesignWizard/FactorialModal.js b/packages/builder/src/components/ComponentOptions/components/Content/Loop/DesignWizard/FactorialModal.js new file mode 100644 index 000000000..1c2c28cd0 --- /dev/null +++ b/packages/builder/src/components/ComponentOptions/components/Content/Loop/DesignWizard/FactorialModal.js @@ -0,0 +1,155 @@ +import React, { Fragment, Component } from 'react' + +import { Formik, Form, Field } from 'formik' +import { ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap' + +import Modal from '../../../../../Modal' +import { Table, DefaultRow } from '../../../../../Form/table' +import { Input } from '../../../../../Form' + +// Logic ----------------------------------------------------------------------- +// (copied from the library combinatorics implementation) + +const product = function* (...sets) { + let thresholds = sets + .map(s => Math.max(s.length, 1)).reverse() + .reduce( + (acc, current, i) => acc.concat([ + (acc[i - 1] || 1) * current + ]), [] + ) + .reverse() + + for (let counter = 0; counter < thresholds[0]; counter++) { + yield sets.map( + (s, i) => s[Math.floor(counter / (thresholds[i + 1] || 1)) % s.length] + ) + } +} + +const generateTable = (factors) => { + const names = factors.map(f => f.name) + const levels = factors.map(f => f.levels.split('\n').filter(c => c !== '')) + + return { + columns: names.map(name => ({ name, type: 'string' })), + rows: Array.from(product(...levels)), + } +} + +// UI -------------------------------------------------------------------------- + +const TableRow = ({ name, arrayHelpers }) => + + + + + + + + + +const Header = () => + + + + Factor + Levels + + + + +class FactorialModal extends Component { + constructor(props) { + super(props) + this.state = { isOpen: false } + this.promiseHandlers = {} + } + + toggle() { + this.setState({ isOpen: !this.state.isOpen }) + } + + async show() { + this.toggle() + return new Promise( + (resolve, reject) => { + this.promiseHandlers = { + resolve: result => { + this.setState({ isOpen: false }) + return resolve(result) + }, + reject + } + } + ) + } + + render() { + return + { + console.log('in Onsubmit') + const table = generateTable(values.factors) + if (this.promiseHandlers.resolve) { + this.promiseHandlers.resolve(table) + } + } } + > +
+
+ + Generate factorial design + + +

Please specify the factors in your design, as well as their levels. The resulting design is fully crossed, meaning that in the loop, every level of a factor is combined with every level of every other factor.

+
+
+ + + + + + + + + + } +} + +export default FactorialModal diff --git a/packages/builder/src/components/ComponentOptions/components/Content/Loop/Grid/footer.js b/packages/builder/src/components/ComponentOptions/components/Content/Loop/Grid/footer.js index dd4fae61e..a6c1d68c7 100644 --- a/packages/builder/src/components/ComponentOptions/components/Content/Loop/Grid/footer.js +++ b/packages/builder/src/components/ComponentOptions/components/Content/Loop/Grid/footer.js @@ -1,11 +1,11 @@ -import React, { useState } from 'react' +import React, { useState, createRef } from 'react' import { ButtonDropdown, Button, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap' import { range } from 'lodash' import Icon from '../../../../../Icon' -//import FactorialModal from './components/FactorialModal' +import FactorialModal from '../DesignWizard/FactorialModal' import { useArrayContext } from '../../../../../Form/array' import Uploader from '../../../../../Uploader' @@ -29,7 +29,7 @@ const exportGrid = (data, columns) => { export default ({ addItem, columns }) => { const [dropdownOpen, setDropdownOpen] = useState(false) - //const factorialModal = createRef() + const factorialModal = createRef() const { dispatch, overwriteAll } = useArrayContext() return ( @@ -37,9 +37,7 @@ export default ({ addItem, columns }) => {
- { /* - */ } { }} /> - { /* Generate factorialModal.current.show().then(result => { @@ -76,7 +73,6 @@ export default ({ addItem, columns }) => { > Factorial design - */ } Repeat