diff --git a/app/models/app.rb b/app/models/app.rb index f07752558c..7c0643a107 100644 --- a/app/models/app.rb +++ b/app/models/app.rb @@ -3,5 +3,5 @@ class App < ApplicationRecord has_many :data_queries has_many :app_users has_many :app_versions - belongs_to :current_version, class_name: 'AppVersion' + belongs_to :current_version, class_name: 'AppVersion', optional: true end diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f6dbbc5e1b..cff54d34c0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2661,6 +2661,22 @@ "indent-string": "^4.0.0" } }, + "airbnb-prop-types": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", + "requires": { + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.13.1" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2840,6 +2856,15 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.find": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz", + "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.4" + } + }, "array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", @@ -3659,6 +3684,11 @@ } } }, + "brcast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brcast/-/brcast-2.0.2.tgz", + "integrity": "sha512-Tfn5JSE7hrUlFcOoaLzVvkbgIemIorMIyoMr3TgvszWW7jFt2C9PdeMLtysYD9RU0MmU17b69+XJG1eRY2OBRg==" + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -4388,6 +4418,11 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "consolidated-events": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/consolidated-events/-/consolidated-events-2.0.2.tgz", + "integrity": "sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ==" + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -4933,6 +4968,11 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==" + }, "default-gateway": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", @@ -5152,6 +5192,11 @@ } } }, + "direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==" + }, "dnd-core": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-14.0.0.tgz", @@ -5192,6 +5237,14 @@ "esutils": "^2.0.2" } }, + "document.contains": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/document.contains/-/document.contains-1.0.2.tgz", + "integrity": "sha512-YcvYFs15mX8m3AO1QNQy3BlIpSMfNRj3Ujk2BEJxsZG+HZf7/hZ6jr7mDpXrF8q+ff95Vef5yjhiZxm8CGJr6Q==", + "requires": { + "define-properties": "^1.1.3" + } + }, "dom-accessibility-api": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz", @@ -5409,6 +5462,15 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, + "enzyme-shallow-equal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", + "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==", + "requires": { + "has": "^1.0.3", + "object-is": "^1.1.2" + } + }, "errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -6771,11 +6833,27 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.4.tgz", + "integrity": "sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "functions-have-names": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", + "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==" + }, "fuse.js": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz", @@ -6882,6 +6960,15 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" }, + "global-cache": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/global-cache/-/global-cache-1.2.1.tgz", + "integrity": "sha512-EOeUaup5DgWKlCMhA9YFqNRIlZwoxt731jCh47WBV9fQqHgXhr3Fa55hfgIUqilIcPsfdNKN7LHjrNY+Km40KA==", + "requires": { + "define-properties": "^1.1.2", + "is-symbol": "^1.0.1" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -7983,6 +8070,11 @@ "has-symbols": "^1.0.1" } }, + "is-touch-device": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-touch-device/-/is-touch-device-1.0.1.tgz", + "integrity": "sha512-LAYzo9kMT1b2p19L/1ATGt2XcSilnzNlyvq6c0pbPRVisLbAPpLqr53tIJS00kvrTkj0HtR8U7+u8X0yR8lPSw==" + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -9431,6 +9523,11 @@ "minimist": "^1.2.5" } }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -11401,6 +11498,16 @@ "react-is": "^16.8.1" } }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, "prop-types-extra": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", @@ -11673,6 +11780,28 @@ "prop-types": "^15.5.8" } }, + "react-dates": { + "version": "21.8.0", + "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-21.8.0.tgz", + "integrity": "sha512-PPriGqi30CtzZmoHiGdhlA++YPYPYGCZrhydYmXXQ6RAvAsaONcPtYgXRTLozIOrsQ5mSo40+DiA5eOFHnZ6xw==", + "requires": { + "airbnb-prop-types": "^2.15.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "enzyme-shallow-equal": "^1.0.0", + "is-touch-device": "^1.0.1", + "lodash": "^4.1.1", + "object.assign": "^4.1.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "raf": "^3.4.1", + "react-moment-proptypes": "^1.6.0", + "react-outside-click-handler": "^1.2.4", + "react-portal": "^4.2.0", + "react-with-direction": "^1.3.1", + "react-with-styles": "^4.1.0", + "react-with-styles-interface-css": "^6.0.0" + } + }, "react-dev-utils": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz", @@ -11982,6 +12111,26 @@ "@emotion/core": "^10.0.22" } }, + "react-moment-proptypes": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/react-moment-proptypes/-/react-moment-proptypes-1.8.1.tgz", + "integrity": "sha512-Er940DxWoObfIqPrZNfwXKugjxMIuk1LAuEzn23gytzV6hKS/sw108wibi9QubfMN4h+nrlje8eUCSbQRJo2fQ==", + "requires": { + "moment": ">=1.6.0" + } + }, + "react-outside-click-handler": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.3.0.tgz", + "integrity": "sha512-Te/7zFU0oHpAnctl//pP3hEAeobfeHMyygHB8MnjP6sX5OR8KHT1G3jmLsV3U9RnIYo+Yn+peJYWu+D5tUS8qQ==", + "requires": { + "airbnb-prop-types": "^2.15.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "document.contains": "^1.0.1", + "object.values": "^1.1.0", + "prop-types": "^15.7.2" + } + }, "react-overlays": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.0.0.tgz", @@ -11997,6 +12146,14 @@ "warning": "^4.0.3" } }, + "react-portal": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.1.tgz", + "integrity": "sha512-fE9kOBagwmTXZ3YGRYb4gcMy+kSA+yLO0xnPankjRlfBv4uCpFXqKPfkpsGQQR15wkZ9EssnvTOl1yMzbkxhPQ==", + "requires": { + "prop-types": "^15.5.8" + } + }, "react-resizable": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.11.1.tgz", @@ -12181,6 +12338,42 @@ "prop-types": "^15.6.2" } }, + "react-with-direction": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz", + "integrity": "sha512-aGcM21ZzhqeXFvDCfPj0rVNYuaVXfTz5D3Rbn0QMz/unZe+CCiLHthrjQWO7s6qdfXORgYFtmS7OVsRgSk5LXQ==", + "requires": { + "airbnb-prop-types": "^2.10.0", + "brcast": "^2.0.2", + "deepmerge": "^1.5.2", + "direction": "^1.0.2", + "hoist-non-react-statics": "^3.3.0", + "object.assign": "^4.1.0", + "object.values": "^1.0.4", + "prop-types": "^15.6.2" + } + }, + "react-with-styles": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-with-styles/-/react-with-styles-4.2.0.tgz", + "integrity": "sha512-tZCTY27KriRNhwHIbg1NkSdTTOSfXDg6Z7s+Q37mtz0Ym7Sc7IOr3PzVt4qJhJMW6Nkvfi3g34FuhtiGAJCBQA==", + "requires": { + "airbnb-prop-types": "^2.14.0", + "hoist-non-react-statics": "^3.2.1", + "object.assign": "^4.1.0", + "prop-types": "^15.7.2", + "react-with-direction": "^1.3.1" + } + }, + "react-with-styles-interface-css": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/react-with-styles-interface-css/-/react-with-styles-interface-css-6.0.0.tgz", + "integrity": "sha512-6khSG1Trf4L/uXOge/ZAlBnq2O2PEXlQEqAhCRbvzaQU4sksIkdwpCPEl6d+DtP3+IdhyffTWuHDO9lhe1iYvA==", + "requires": { + "array.prototype.flat": "^1.2.1", + "global-cache": "^1.2.1" + } + }, "reactcss": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", @@ -12264,6 +12457,11 @@ "symbol-observable": "^1.2.0" } }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index e926ca5b58..243df64757 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,7 @@ "dompurify": "^2.2.7", "history": "^4.9.0", "immutability-helper": "^3.1.1", + "moment": "^2.29.1", "node-sass": "^4.14.1", "query-string": "^6.13.6", "re-resizable": "^6.9.0", @@ -21,6 +22,7 @@ "react-bootstrap": "^1.5.2", "react-color": "^2.19.3", "react-copy-to-clipboard": "^5.0.3", + "react-dates": "^21.8.0", "react-dnd": "^14.0.2", "react-dnd-html5-backend": "^14.0.0", "react-dom": "^16.13.1", diff --git a/frontend/src/Editor/Box.jsx b/frontend/src/Editor/Box.jsx index 95cc9f0371..b3ed39452c 100644 --- a/frontend/src/Editor/Box.jsx +++ b/frontend/src/Editor/Box.jsx @@ -9,6 +9,7 @@ import { Container } from './Components/Container'; import { RichTextEditor } from './Components/RichTextEditor'; import { DropDown } from './Components/DropDown'; import { Checkbox } from './Components/Checkbox'; +import { Datepicker } from './Components/Datepicker'; const AllComponents = { Button, @@ -20,7 +21,8 @@ const AllComponents = { Container, RichTextEditor, DropDown, - Checkbox + Checkbox, + Datepicker } let styles = { diff --git a/frontend/src/Editor/Components/Datepicker.jsx b/frontend/src/Editor/Components/Datepicker.jsx new file mode 100644 index 0000000000..4f3f04b8d9 --- /dev/null +++ b/frontend/src/Editor/Components/Datepicker.jsx @@ -0,0 +1,19 @@ +import React from 'react'; +import Datetime from 'react-datetime'; +import "react-datetime/css/react-datetime.css"; + + +export const Datepicker = function Datepicker({ id, width, height, component, onComponentClick, currentState, onComponentOptionChanged }) { + + console.log('currentState', currentState); + + function onDateChange(event) { + onComponentOptionChanged(component, 'value', event.format()) + } + + return ( + + ); +}; diff --git a/frontend/src/Editor/Components/components.js b/frontend/src/Editor/Components/components.js index 7585ff8722..a8120f5900 100644 --- a/frontend/src/Editor/Components/components.js +++ b/frontend/src/Editor/Components/components.js @@ -153,6 +153,38 @@ export const componentTypes = [ } } }, + { + icon: 'https://www.svgrepo.com/show/14690/calendar.svg', + name: 'Datepicker', + description: 'Select a date and time', + component: 'Datepicker', + defaultSize: { + width: 100, + height: 60 + }, + properties: { + + }, + events: [ + + ], + styles: { + + }, + exposedVariables: {}, + definition: { + properties: { + + }, + events: { + + }, + styles: { + + } + } + }, + { icon: 'https://www.svgrepo.com/show/309414/checkbox-checked.svg', name: 'Checkbox',