From 32c625ea4aa844fac06317da47afcf360e04e9a5 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Fri, 17 Jul 2020 17:47:42 +1000 Subject: [PATCH 01/14] add basic react-hook-form implementation with basic autosave --- www/package.json | 1 + .../SideDrawer/Form/Fields/Text.tsx | 21 +- www/src/components/SideDrawer/Form/index.tsx | 228 +++++++++++++++++- www/yarn.lock | 5 + 4 files changed, 238 insertions(+), 17 deletions(-) diff --git a/www/package.json b/www/package.json index 792fec89..dce75d4e 100644 --- a/www/package.json +++ b/www/package.json @@ -51,6 +51,7 @@ "react-div-100vh": "^0.3.8", "react-dom": "^16.9.0", "react-dropzone": "^10.1.8", + "react-hook-form": "^6.0.6", "react-json-view": "^1.19.1", "react-router-dom": "^5.0.1", "react-scripts": "^3.3.0", diff --git a/www/src/components/SideDrawer/Form/Fields/Text.tsx b/www/src/components/SideDrawer/Form/Fields/Text.tsx index 04bf34e0..49999a5a 100644 --- a/www/src/components/SideDrawer/Form/Fields/Text.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Text.tsx @@ -1,7 +1,11 @@ import React from "react"; -import { makeStyles, createStyles } from "@material-ui/core"; -import { TextField, TextFieldProps } from "formik-material-ui"; +import { + makeStyles, + createStyles, + TextField, + FilledTextFieldProps, +} from "@material-ui/core"; const useStyles = makeStyles(theme => createStyles({ @@ -9,7 +13,7 @@ const useStyles = makeStyles(theme => }) ); -export interface ITextProps extends TextFieldProps { +export interface ITextProps extends Omit { fieldVariant?: "short" | "long" | "email" | "phone" | "number" | "url"; } @@ -27,7 +31,10 @@ export default function Text({ fieldVariant = "short", ...props }: ITextProps) { break; case "email": - variantProps = { type: "email", inputProps: { autoComplete: "email" } }; + variantProps = { + // type: "email", + inputProps: { autoComplete: "email" }, + }; break; case "phone": @@ -45,14 +52,14 @@ export default function Text({ fieldVariant = "short", ...props }: ITextProps) { } return ( { + console.log("SUBMIT", data); + }; + + // const watchAllFields = watch(); + + // useEffect(() => {console.log(watchAllFields)}, [watchAllFields]); + + // const { sideDrawerRef } = useFiretableContext(); // useEffect(() => { // const column = sideDrawerRef?.current?.cell?.column; // if (!column) return; @@ -159,15 +173,203 @@ export default function Form({ fields, values }: IFormProps) { return ( - { - // Mark as submitted. We use Autosave instead. - actions.setSubmitting(false); - }} +
{ + // // Mark as submitted. We use Autosave instead. + // actions.setSubmitting(false); + // }} > - {({ values, errors }) => ( + + + + + + {fields.map((_field, i) => { + // Call the field function with values if necessary + // Otherwise, just use the field object + const field: Field = _isFunction(_field) ? _field(values) : _field; + const { type, ...fieldProps } = field; + let _type = type; + if (field.config && field.config.renderFieldType) { + _type = field.config.renderFieldType; + } + // TODO: handle get initial field value for when a field is later + // shown to prevent uncontrolled components becoming controlled + + let renderedField: React.ReactNode = null; + + switch (_type) { + case FieldType.shortText: + case FieldType.longText: + case FieldType.email: + case FieldType.phone: + case FieldType.number: + renderedField = ( + + ); + break; + + // case FieldType.url: + // renderedField = ( + // + // ); + // break; + + // case FieldType.percentage: + // renderedField = ( + // + // ); + // break; + + // case FieldType.singleSelect: + // renderedField = ( + // + // ); + // break; + + // case FieldType.multiSelect: + // renderedField = ( + // + // ); + // break; + + // case FieldType.date: + // renderedField = ( + // + // ); + // break; + + // case FieldType.dateTime: + // renderedField = ( + // + // ); + // break; + + // case FieldType.checkbox: + // renderedField = ( + // + // ); + // break; + + // case FieldType.color: + // renderedField = ; + // break; + + // case FieldType.slider: + // renderedField = ( + // + // ); + // break; + + // case FieldType.richText: + // renderedField = ( + // + // ); + // break; + + // case FieldType.image: + // renderedField = ( + // + // ); + // break; + + // case FieldType.file: + // renderedField = ( + // + // ); + // break; + + // case FieldType.rating: + // renderedField = ( + // + // ); + // break; + + // case FieldType.connectTable: + // renderedField = ( + // + // ); + // break; + + // case FieldType.subTable: + // renderedField = ( + // + // ); + // break; + + // case FieldType.action: + // renderedField = ( + // + // ); + // break; + + // case FieldType.json: + // renderedField = ( + // + // ); + // break; + // case FieldType.code: + // renderedField = ; + // break; + case undefined: + default: + return null; + + // default: + // break; + } + + return ( + + {renderedField} + + ); + })} + + + + + {/* {({ values, errors }) => ( @@ -357,7 +559,13 @@ export default function Form({ fields, values }: IFormProps) { )} -
+ */}
); } + +function AutosaveTwo({ control }: any) { + const watchAll = useWatch({ control }); + console.log(watchAll); + return <>autosave2; +} diff --git a/www/yarn.lock b/www/yarn.lock index a8d3dbaf..c4a44b95 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -11946,6 +11946,11 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== +react-hook-form@^6.0.6: + version "6.0.6" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.0.6.tgz#72ac1668aeaddfd642bcfb324cebe1ba237fb13e" + integrity sha512-qxWhV++1V7SKKlr2hHFsessGwATCdexgVsByxOHltDyO9F0VWB1WN4ZvxnKuHTVGwjj6CLZo0mL+Hgy0QH1sAw== + react-input-autosize@^2.1.2: version "2.2.2" resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2" From a8513c3cdd63a227e5698c42c29ebb84f6cf7634 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Tue, 21 Jul 2020 16:45:20 +1000 Subject: [PATCH 02/14] fix SideDrawer nav buttons not selecting new cell --- www/src/components/SideDrawer/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/www/src/components/SideDrawer/index.tsx b/www/src/components/SideDrawer/index.tsx index 893399e6..042fc119 100644 --- a/www/src/components/SideDrawer/index.tsx +++ b/www/src/components/SideDrawer/index.tsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react"; import clsx from "clsx"; import _isNil from "lodash/isNil"; import _sortBy from "lodash/sortBy"; -import _findIndex from "lodash/findIndex"; import { Drawer, Fab } from "@material-ui/core"; import ChevronIcon from "@material-ui/icons/KeyboardArrowLeft"; @@ -49,7 +48,7 @@ export default function SideDrawer() { setCell!(cell => ({ column: cell!.column, row })); - const idx = _findIndex(tableState?.columns, ["key", cell!.column]); + const idx = tableState?.columns[cell!.column]?.index; dataGridRef?.current?.selectCell({ rowIdx: row, idx }); }; From 1a9f1989e6ac8dec122afec164ba8d6d28b4de69 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Tue, 21 Jul 2020 19:12:30 +1000 Subject: [PATCH 03/14] migrate more fields to react-hook-form --- www/package.json | 6 +- .../SideDrawer/Form/Fields/Checkbox.tsx | 43 ++- .../SideDrawer/Form/Fields/DatePicker.tsx | 75 ++-- .../SideDrawer/Form/Fields/DateTimePicker.tsx | 77 ++-- .../SideDrawer/Form/Fields/MultiSelect.tsx | 120 ++++--- .../SideDrawer/Form/Fields/Percentage.tsx | 56 +-- .../SideDrawer/Form/Fields/SingleSelect.tsx | 76 ++-- .../SideDrawer/Form/Fields/Text.tsx | 11 +- .../components/SideDrawer/Form/Fields/Url.tsx | 68 ++-- www/src/components/SideDrawer/Form/index.tsx | 336 +++--------------- www/src/components/Table/formatters/index.tsx | 5 +- www/yarn.lock | 259 +++++++------- 12 files changed, 521 insertions(+), 611 deletions(-) diff --git a/www/package.json b/www/package.json index dce75d4e..bf24b338 100644 --- a/www/package.json +++ b/www/package.json @@ -3,12 +3,12 @@ "version": "0.1.0", "private": true, "dependencies": { - "@antlerengineering/components": "^0.3.10", + "@antlerengineering/components": "^0.4.1", "@antlerengineering/multiselect": "^0.3.14", "@date-io/date-fns": "1.x", - "@material-ui/core": "^4.9.13", + "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "^4.0.0-alpha.52", + "@material-ui/lab": "^4.0.0-alpha.56", "@material-ui/pickers": "^3.2.10", "@mdi/js": "^4.9.95", "@tinymce/tinymce-react": "^3.4.0", diff --git a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx index 3f30aa40..fd0caf7e 100644 --- a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx @@ -1,15 +1,14 @@ import React from "react"; -import { Field } from "formik"; +import { Controller, Control } from "react-hook-form"; import { makeStyles, createStyles, ButtonBase, FormControlLabel, + Switch, SwitchProps as MuiSwitchProps, } from "@material-ui/core"; -import { Switch } from "formik-material-ui"; -import ErrorMessage from "../ErrorMessage"; const useStyles = makeStyles(theme => createStyles({ @@ -40,11 +39,19 @@ const useStyles = makeStyles(theme => ); export interface ICheckboxProps extends MuiSwitchProps { + control: Control; name: string; label?: React.ReactNode; + editable?: boolean; } -export default function Checkbox({ label, ...props }: ICheckboxProps) { +export default function Checkbox({ + control, + label, + name, + editable, + ...props +}: ICheckboxProps) { const classes = useStyles(); return ( @@ -52,11 +59,27 @@ export default function Checkbox({ label, ...props }: ICheckboxProps) { { + const handleChange = ( + event: React.ChangeEvent + ) => { + onChange(event.target.checked); + }; + + return ( + + ); + }} /> } label={label} @@ -64,8 +87,6 @@ export default function Checkbox({ label, ...props }: ICheckboxProps) { classes={{ root: classes.formControlLabel, label: classes.label }} /> - - ); } diff --git a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx index ab62ef27..f59c0ac6 100644 --- a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx @@ -1,42 +1,59 @@ import React from "react"; +import { Controller, Control } from "react-hook-form"; import { useTheme } from "@material-ui/core"; -import { KeyboardDatePicker } from "@material-ui/pickers"; import { - fieldToKeyboardDatePicker, + KeyboardDatePicker, KeyboardDatePickerProps, -} from "formik-material-ui-pickers"; +} from "@material-ui/pickers"; import { DATE_FORMAT } from "constants/dates"; -export default function DatePicker(props: KeyboardDatePickerProps) { +export interface IDatePickerProps + extends Omit { + control: Control; + name: string; +} + +export default function DatePicker({ + control, + name, + ...props +}: IDatePickerProps) { const theme = useTheme(); - let transformedValue = null; - if (props.field.value && "toDate" in props.field.value) - transformedValue = props.field.value.toDate(); - else if (props.field.value !== undefined) - transformedValue = props.field.value; - - const handleChange = (date: Date | null) => { - if (isNaN(date?.valueOf() ?? 0)) return; - props.form.setFieldValue(props.field.name, date); - }; - return ( - { + let transformedValue = null; + if (value && "toDate" in value) transformedValue = value.toDate(); + else if (value !== undefined) transformedValue = value; + + const handleChange = (date: Date | null) => { + if (isNaN(date?.valueOf() ?? 0)) return; + onChange(date); + }; + + return ( + + ); + }} /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx index e7fe1d4a..aa26b1f0 100644 --- a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx @@ -1,45 +1,62 @@ import React from "react"; +import { Controller, Control } from "react-hook-form"; import { useTheme } from "@material-ui/core"; -import { KeyboardDateTimePicker } from "@material-ui/pickers"; import { - fieldToKeyboardDateTimePicker, + KeyboardDateTimePicker, KeyboardDateTimePickerProps, -} from "formik-material-ui-pickers"; +} from "@material-ui/pickers"; import { DATE_TIME_FORMAT } from "constants/dates"; import AccessTimeIcon from "@material-ui/icons/AccessTime"; -export default function DateTimePicker(props: KeyboardDateTimePickerProps) { +export interface IDateTimePickerProps + extends Omit { + control: Control; + name: string; +} + +export default function DateTimePicker({ + control, + name, + ...props +}: IDateTimePickerProps) { const theme = useTheme(); - let transformedValue = null; - if (props.field.value && "toDate" in props.field.value) - transformedValue = props.field.value.toDate(); - else if (props.field.value !== undefined) - transformedValue = props.field.value; - - const handleChange = (date: Date | null) => { - if (isNaN(date?.valueOf() ?? 0)) return; - props.form.setFieldValue(props.field.name, date); - }; - return ( - } - {...fieldToKeyboardDateTimePicker(props)} - value={transformedValue} - onChange={handleChange} - label="" - hiddenLabel - id={`sidedrawer-field-${props.field.name}`} + { + let transformedValue = null; + if (value && "toDate" in value) transformedValue = value.toDate(); + else if (value !== undefined) transformedValue = value; + + const handleChange = (date: Date | null) => { + if (isNaN(date?.valueOf() ?? 0)) return; + onChange(date); + }; + + return ( + } + {...props} + value={transformedValue} + onChange={handleChange} + onBlur={onBlur} + label="" + hiddenLabel + id={`sidedrawer-field-${name}`} + /> + ); + }} /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx b/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx index 45f94936..02b5989d 100644 --- a/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx +++ b/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx @@ -1,67 +1,85 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { useTheme, Grid } from "@material-ui/core"; -import MultiSelectA, { MultiSelectProps } from "@antlerengineering/multiselect"; +import MultiSelect_, { MultiSelectProps } from "@antlerengineering/multiselect"; import FormattedChip from "components/FormattedChip"; +export type IMultiSelectProps = Omit< + MultiSelectProps, + "multiple" | "value" | "onChange" | "options" +> & { + control: Control; + name: string; + + config?: { options: string[] }; + editable?: boolean; +}; + export default function MultiSelect({ - field, - form, + control, + name, editable, config, ...props -}: FieldProps & - MultiSelectProps & { - config: { options: string[] }; - editable?: boolean; - }) { +}: IMultiSelectProps) { const theme = useTheme(); - const handleDelete = (index: number) => () => { - const newValues = [...field.value]; - newValues.splice(index, 1); - form.setFieldValue(field.name, newValues); - }; - return ( - <> - form.setFieldValue(field.name, value)} - disabled={editable === false} - TextFieldProps={{ - label: "", - hiddenLabel: true, - error: !!(form.touched[field.name] && form.errors[field.name]), - helperText: - (form.touched[field.name] && form.errors[field.name]) || "", - onBlur: () => form.setFieldTouched(field.name), - }} - searchable - freeText={false} - /> + { + const handleDelete = (index: number) => () => { + const newValues = [...value]; + newValues.splice(index, 1); + onChange(newValues); + }; - {field.value && Array.isArray(field.value) && ( - - {field.value.map( - (item, i) => - item?.length > 0 && ( - - - - ) - )} - - )} - + return ( + <> + + + {value && Array.isArray(value) && ( + + {value.map( + (item, i) => + item?.length > 0 && ( + + + + ) + )} + + )} + + ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Percentage.tsx b/www/src/components/SideDrawer/Form/Fields/Percentage.tsx index d0bca0d9..5c84c2a6 100644 --- a/www/src/components/SideDrawer/Form/Fields/Percentage.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Percentage.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { makeStyles, createStyles, Typography } from "@material-ui/core"; import { resultColorsScale } from "util/color"; @@ -41,27 +41,43 @@ const useStyles = makeStyles(theme => }) ); -export default function Percentage({ field }: FieldProps) { +export interface IPercentageProps { + control: Control; + name: string; +} + +/** + * TODO: Fix cell not updating properly when switching between rows + */ +export default function Percentage({ control, name }: IPercentageProps) { const classes = useStyles(); - if (!field.value) - return ( -
-
-
- ); - return ( -
-
- - {Math.round(field.value * 100)}% - -
+ { + if (!value) + return ( +
+
+
+ ); + + return ( +
+
+ + {Math.round(value * 100)}% + +
+ ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/SingleSelect.tsx b/www/src/components/SideDrawer/Form/Fields/SingleSelect.tsx index 99a459b4..55b8b924 100644 --- a/www/src/components/SideDrawer/Form/Fields/SingleSelect.tsx +++ b/www/src/components/SideDrawer/Form/Fields/SingleSelect.tsx @@ -1,56 +1,64 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { useTheme } from "@material-ui/core"; import MultiSelect, { MultiSelectProps } from "@antlerengineering/multiselect"; import FormattedChip from "components/FormattedChip"; +export type ISingleSelectProps = Omit< + MultiSelectProps, + "multiple" | "value" | "onChange" | "options" +> & { + control: Control; + name: string; + + config?: { options: string[] }; + editable?: boolean; +}; + /** * Uses the MultiSelect UI, but writes values as a string, * not an array of strings */ export default function SingleSelect({ - field, - form, + control, + name, editable, config, ...props -}: FieldProps & - MultiSelectProps & { - config: { options: string[] }; - editable: boolean; - }) { +}: ISingleSelectProps) { const theme = useTheme(); - const handleChange = value => form.setFieldValue(field.name, value); - return ( - <> - form.setFieldTouched(field.name), - }} - searchable - freeText={false} - /> + ( + <> + - {field.value?.length > 0 && ( -
- -
+ {value?.length > 0 && ( +
+ +
+ )} + )} - + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Text.tsx b/www/src/components/SideDrawer/Form/Fields/Text.tsx index 49999a5a..80fcf79d 100644 --- a/www/src/components/SideDrawer/Form/Fields/Text.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Text.tsx @@ -15,9 +15,14 @@ const useStyles = makeStyles(theme => export interface ITextProps extends Omit { fieldVariant?: "short" | "long" | "email" | "phone" | "number" | "url"; + editable?: boolean; } -export default function Text({ fieldVariant = "short", ...props }: ITextProps) { +export default function Text({ + fieldVariant = "short", + editable, + ...props +}: ITextProps) { const classes = useStyles(); let variantProps = {}; @@ -50,10 +55,11 @@ export default function Text({ fieldVariant = "short", ...props }: ITextProps) { default: break; } + return ( ); diff --git a/www/src/components/SideDrawer/Form/Fields/Url.tsx b/www/src/components/SideDrawer/Form/Fields/Url.tsx index 1eca7d69..ae228701 100644 --- a/www/src/components/SideDrawer/Form/Fields/Url.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Url.tsx @@ -1,34 +1,54 @@ import React from "react"; +import { Controller, Control } from "react-hook-form"; -import { Grid, IconButton } from "@material-ui/core"; -import { TextField, TextFieldProps } from "formik-material-ui"; - +import { + Grid, + TextField, + FilledTextFieldProps, + IconButton, +} from "@material-ui/core"; import LaunchIcon from "@material-ui/icons/Launch"; -export default function Url(props: TextFieldProps) { +export interface IUrlProps extends Omit { + control: Control; + name: string; +} + +export default function Url({ control, name, ...props }: IUrlProps) { return ( - ( + <> + + + + + + )} /> - - - ); } diff --git a/www/src/components/SideDrawer/Form/index.tsx b/www/src/components/SideDrawer/Form/index.tsx index e4dec95d..194e6bd6 100644 --- a/www/src/components/SideDrawer/Form/index.tsx +++ b/www/src/components/SideDrawer/Form/index.tsx @@ -1,6 +1,5 @@ import React, { lazy, useEffect } from "react"; -import { Formik, Form as FormikForm, Field } from "formik"; -import { useForm, useWatch } from "react-hook-form"; +import { useForm, useWatch, Control } from "react-hook-form"; import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import DateFnsUtils from "@date-io/date-fns"; import _isFunction from "lodash/isFunction"; @@ -19,9 +18,6 @@ import { FieldType } from "constants/fields"; const Url = lazy(() => import("./Fields/Url" /* webpackChunkName: "SideDrawer-Url" */) ); -const Percentage = lazy(() => - import("./Fields/Percentage" /* webpackChunkName: "SideDrawer-Percentage" */) -); const SingleSelect = lazy(() => import( "./Fields/SingleSelect" /* webpackChunkName: "SideDrawer-SingleSelect" */ @@ -46,6 +42,9 @@ const Checkbox = lazy(() => const Rating = lazy(() => import("./Fields/Rating" /* webpackChunkName: "SideDrawer-Rating" */) ); +const Percentage = lazy(() => + import("./Fields/Percentage" /* webpackChunkName: "SideDrawer-Percentage" */) +); const Color = lazy(() => import("./Fields/Color" /* webpackChunkName: "SideDrawer-Color" */) ); @@ -86,8 +85,8 @@ const Action = lazy(() => export type Values = { [key: string]: any }; export type Field = { type?: FieldType; - name?: string; - label?: React.ReactNode; + name: string; + label?: string; [key: string]: any; }; export type Fields = (Field | ((values: Values) => Field))[]; @@ -111,7 +110,6 @@ const initializeValue = type => { case FieldType.json: return {}; - break; case FieldType.shortText: case FieldType.longText: @@ -145,9 +143,10 @@ export interface IFormProps { export default function Form({ fields, values }: IFormProps) { const initialValues = getInitialValues(fields); - const defaultValues = { ...initialValues, ...values }; + const { ref: firestoreRef, ...rowValues } = values; + const defaultValues = { ...initialValues, ...rowValues }; - const { register, handleSubmit, watch, errors, control } = useForm({ + const { register, handleSubmit, control, reset } = useForm({ mode: "onBlur", defaultValues, }); @@ -155,9 +154,11 @@ export default function Form({ fields, values }: IFormProps) { console.log("SUBMIT", data); }; - // const watchAllFields = watch(); - - // useEffect(() => {console.log(watchAllFields)}, [watchAllFields]); + // Update field values when Firestore document updates + // useEffect(() => { + // console.log("RESET", defaultValues); + // reset(defaultValues); + // }, [reset, JSON.stringify(rowValues)]); // const { sideDrawerRef } = useFiretableContext(); // useEffect(() => { @@ -173,19 +174,10 @@ export default function Form({ fields, values }: IFormProps) { return ( -
{ - // // Mark as submitted. We use Autosave instead. - // actions.setSubmitting(false); - // }} - > + - - {fields.map((_field, i) => { // Call the field function with values if necessary // Otherwise, just use the field object @@ -195,8 +187,6 @@ export default function Form({ fields, values }: IFormProps) { if (field.config && field.config.renderFieldType) { _type = field.config.renderFieldType; } - // TODO: handle get initial field value for when a field is later - // shown to prevent uncontrolled components becoming controlled let renderedField: React.ReactNode = null; @@ -211,67 +201,37 @@ export default function Form({ fields, values }: IFormProps) { ); break; - // case FieldType.url: - // renderedField = ( - // - // ); - // break; + case FieldType.url: + renderedField = ; + break; - // case FieldType.percentage: - // renderedField = ( - // - // ); - // break; + case FieldType.singleSelect: + renderedField = ( + + ); + break; - // case FieldType.singleSelect: - // renderedField = ( - // - // ); - // break; + case FieldType.multiSelect: + renderedField = ( + + ); + break; - // case FieldType.multiSelect: - // renderedField = ( - // - // ); - // break; + case FieldType.date: + renderedField = ( + + ); + break; - // case FieldType.date: - // renderedField = ( - // - // ); - // break; + case FieldType.dateTime: + renderedField = ( + + ); + break; - // case FieldType.dateTime: - // renderedField = ( - // - // ); - // break; - - // case FieldType.checkbox: - // renderedField = ( - // - // ); - // break; + case FieldType.checkbox: + renderedField = ; + break; // case FieldType.color: // renderedField = ; @@ -315,6 +275,12 @@ export default function Form({ fields, values }: IFormProps) { // ); // break; + case FieldType.percentage: + renderedField = ( + + ); + break; + // case FieldType.connectTable: // renderedField = ( // @@ -342,11 +308,11 @@ export default function Form({ fields, values }: IFormProps) { // renderedField = ; // break; case undefined: - default: + // default: return null; - // default: - // break; + default: + break; } return ( @@ -369,203 +335,17 @@ export default function Form({ fields, values }: IFormProps) { /> - {/* {({ values, errors }) => ( - - - - - {fields.map((_field, i) => { - // Call the field function with values if necessary - // Otherwise, just use the field object - const field: Field = _isFunction(_field) - ? _field(values) - : _field; - const { type, ...fieldProps } = field; - let _type = type; - if (field.config && field.config.renderFieldType) { - _type = field.config.renderFieldType; - } - // TODO: handle get initial field value for when a field is later - // shown to prevent uncontrolled components becoming controlled - - let renderedField: React.ReactNode = null; - - switch (_type) { - case FieldType.shortText: - case FieldType.longText: - case FieldType.email: - case FieldType.phone: - case FieldType.number: - renderedField = ( - - ); - break; - - case FieldType.url: - renderedField = ( - - ); - break; - - case FieldType.percentage: - renderedField = ( - - ); - break; - - case FieldType.singleSelect: - renderedField = ( - - ); - break; - - case FieldType.multiSelect: - renderedField = ( - - ); - break; - - case FieldType.date: - renderedField = ( - - ); - break; - - case FieldType.dateTime: - renderedField = ( - - ); - break; - - case FieldType.checkbox: - renderedField = ( - - ); - break; - - case FieldType.color: - renderedField = ; - break; - - case FieldType.slider: - renderedField = ( - - ); - break; - - case FieldType.richText: - renderedField = ( - - ); - break; - - case FieldType.image: - renderedField = ( - - ); - break; - - case FieldType.file: - renderedField = ( - - ); - break; - - case FieldType.rating: - renderedField = ( - - ); - break; - - case FieldType.connectTable: - renderedField = ( - - ); - break; - - case FieldType.subTable: - renderedField = ( - - ); - break; - - case FieldType.action: - renderedField = ( - - ); - break; - - case FieldType.json: - renderedField = ( - - ); - break; - case FieldType.code: - renderedField = ; - break; - case undefined: - return null; - - default: - break; - } - - return ( - - {renderedField} - - ); - })} - - - - - )} - */}
); } -function AutosaveTwo({ control }: any) { +function AutosaveTwo({ + control, +}: { + control: Control; + defaultValues: { [key: string]: any }; +}) { const watchAll = useWatch({ control }); - console.log(watchAll); - return <>autosave2; + console.log("FORM VALUES", watchAll); + return null; } diff --git a/www/src/components/Table/formatters/index.tsx b/www/src/components/Table/formatters/index.tsx index 8c7fcc87..e19f1b07 100644 --- a/www/src/components/Table/formatters/index.tsx +++ b/www/src/components/Table/formatters/index.tsx @@ -48,9 +48,8 @@ const Percentage = lazy(() => */ export const getFormatter = (column: any) => { let _type = column.type; - if (column.config.renderFieldType) { - _type = column.config.renderFieldType; - } + if (column.config?.renderFieldType) _type = column.config.renderFieldType; + switch (_type) { case FieldType.date: case FieldType.dateTime: diff --git a/www/yarn.lock b/www/yarn.lock index c4a44b95..8974df98 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -106,10 +106,10 @@ "@algolia/logger-common" "4.1.0" "@algolia/requester-common" "4.1.0" -"@antlerengineering/components@^0.3.10": - version "0.3.10" - resolved "https://registry.yarnpkg.com/@antlerengineering/components/-/components-0.3.10.tgz#4ae9fde94587dbff7bbc96e21c645965614d775b" - integrity sha512-f3t9Eruxj7qfwuisr5xjzdocmPSEcN58uXlJHKZhMtBDMqzA/x1FiwcG79j7trxAxhlewxJ/fUo7jOTTh4L/JQ== +"@antlerengineering/components@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@antlerengineering/components/-/components-0.4.1.tgz#68955a5eebac4f3022442f6c148ed5aa0d7b6e48" + integrity sha512-7MMP75dMrfx/OrQk3lL4/3wWhYCvTeyGuhqTbohpWG7FSS513YBoh7Q7wly0XASB0Shz5gzuFrDZ5s4WfpSf9Q== dependencies: dompurify "^2.0.10" lodash "^4.17.15" @@ -1071,13 +1071,20 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.8.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d" integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.8.3": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.5.tgz#303d8bd440ecd5a491eae6117fd3367698674c5c" + integrity sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.4.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" @@ -1569,6 +1576,24 @@ "@babel/traverse" "^7.6.2" jscodeshift-add-imports "^1.0.1" +"@material-ui/core@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" + integrity sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g== + dependencies: + "@babel/runtime" "^7.4.4" + "@material-ui/styles" "^4.10.0" + "@material-ui/system" "^4.9.14" + "@material-ui/types" "^5.1.0" + "@material-ui/utils" "^4.10.2" + "@types/react-transition-group" "^4.2.0" + clsx "^1.0.4" + hoist-non-react-statics "^3.3.2" + popper.js "1.16.1-lts" + prop-types "^15.7.2" + react-is "^16.8.0" + react-transition-group "^4.4.0" + "@material-ui/core@^4.7.1": version "4.9.7" resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.9.7.tgz#0c1caf123278770f34c5d8e9ecd9e1314f87a621" @@ -1587,25 +1612,6 @@ react-is "^16.8.0" react-transition-group "^4.3.0" -"@material-ui/core@^4.9.13": - version "4.9.13" - resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.9.13.tgz#024962bcdda05139e1bad17a1815bf4088702b15" - integrity sha512-GEXNwUr+laZ0N+F1efmHB64Fyg+uQIRXLqbSejg3ebSXgLYNpIjnMOPRfWdu4rICq0dAIgvvNXGkKDMcf3AMpA== - dependencies: - "@babel/runtime" "^7.4.4" - "@material-ui/react-transition-group" "^4.3.0" - "@material-ui/styles" "^4.9.13" - "@material-ui/system" "^4.9.13" - "@material-ui/types" "^5.0.1" - "@material-ui/utils" "^4.9.12" - "@types/react-transition-group" "^4.2.0" - clsx "^1.0.4" - hoist-non-react-statics "^3.3.2" - popper.js "^1.16.1-lts" - prop-types "^15.7.2" - react-is "^16.8.0" - react-transition-group "^4.3.0" - "@material-ui/icons@^4.5.1", "@material-ui/icons@^4.9.1": version "4.9.1" resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665" @@ -1613,13 +1619,13 @@ dependencies: "@babel/runtime" "^7.4.4" -"@material-ui/lab@^4.0.0-alpha.52": - version "4.0.0-alpha.52" - resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.52.tgz#a868d8c772a90db091a6bfc89aed21a0e2c486bf" - integrity sha512-aDoRWA+q3/T2spvvQrxPz8qjtf9l8NhaG9ZISBy9zD3cJ05s3KfEP2nrsoBOBgonlSMFQQzUTnxAwThwsJfllw== +"@material-ui/lab@^4.0.0-alpha.56": + version "4.0.0-alpha.56" + resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34" + integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/utils" "^4.9.6" + "@material-ui/utils" "^4.10.2" clsx "^1.0.4" prop-types "^15.7.2" react-is "^16.8.0" @@ -1636,24 +1642,14 @@ react-transition-group "^4.0.0" rifm "^0.7.0" -"@material-ui/react-transition-group@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@material-ui/react-transition-group/-/react-transition-group-4.3.0.tgz#92529142addb5cc179dbf42d246c7e3fe4d6104b" - integrity sha512-CwQ0aXrlUynUTY6sh3UvKuvye1o92en20VGAs6TORnSxUYeRmkX8YeTUN3lAkGiBX1z222FxLFO36WWh6q73rQ== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - -"@material-ui/styles@^4.9.13": - version "4.9.13" - resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.9.13.tgz#08b3976bdd21c38bc076693d95834f97539f3b15" - integrity sha512-lWlXJanBdHQ18jW/yphedRokHcvZD1GdGzUF/wQxKDsHwDDfO45ZkAxuSBI202dG+r1Ph483Z3pFykO2obeSRA== +"@material-ui/styles@^4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071" + integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.8.0" - "@material-ui/types" "^5.0.1" + "@material-ui/types" "^5.1.0" "@material-ui/utils" "^4.9.6" clsx "^1.0.4" csstype "^2.5.2" @@ -1690,13 +1686,14 @@ jss-plugin-vendor-prefixer "^10.0.3" prop-types "^15.7.2" -"@material-ui/system@^4.9.13": - version "4.9.13" - resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.9.13.tgz#adefb3b6a5ddf0b00fe4e82ac63bb48276e9749d" - integrity sha512-6AlpvdW6KJJ5bF1Xo2OD13sCN8k+nlL36412/bWnWZOKIfIMo/Lb8c8d1DOIaT/RKWxTEUaWnKZjabVnA3eZjA== +"@material-ui/system@^4.9.14": + version "4.9.14" + resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.9.14.tgz#4b00c48b569340cefb2036d0596b93ac6c587a5f" + integrity sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w== dependencies: "@babel/runtime" "^7.4.4" "@material-ui/utils" "^4.9.6" + csstype "^2.5.2" prop-types "^15.7.2" "@material-ui/system@^4.9.6": @@ -1713,24 +1710,15 @@ resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.0.0.tgz#26d6259dc6b39f4c2e1e9aceff7a11e031941741" integrity sha512-UeH2BuKkwDndtMSS0qgx1kCzSMw+ydtj0xx/XbFtxNSTlXydKwzs5gVW5ZKsFlAkwoOOQ9TIsyoCC8hq18tOwg== -"@material-ui/types@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.0.1.tgz#c4954063cdc196eb327ee62c041368b1aebb6d61" - integrity sha512-wURPSY7/3+MAtng3i26g+WKwwNE3HEeqa/trDBR5+zWKmcjO+u9t7Npu/J1r+3dmIa/OeziN9D/18IrBKvKffw== +"@material-ui/types@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" + integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== -"@material-ui/utils@^4.9.12": - version "4.9.12" - resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.9.12.tgz#0d639f1c1ed83fffb2ae10c21d15a938795d9e65" - integrity sha512-/0rgZPEOcZq5CFA4+4n6Q6zk7fi8skHhH2Bcra8R3epoJEYy5PL55LuMazPtPH1oKeRausDV/Omz4BbgFsn1HQ== - dependencies: - "@babel/runtime" "^7.4.4" - prop-types "^15.7.2" - react-is "^16.8.0" - -"@material-ui/utils@^4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.9.6.tgz#5f1f9f6e4df9c8b6a263293b68c94834248ff157" - integrity sha512-gqlBn0JPPTUZeAktn1rgMcy9Iczrr74ecx31tyZLVGdBGGzsxzM6PP6zeS7FuoLS6vG4hoZP7hWnOoHtkR0Kvw== +"@material-ui/utils@^4.10.2", "@material-ui/utils@^4.9.6": + version "4.10.2" + resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.10.2.tgz#3fd5470ca61b7341f1e0468ac8f29a70bf6df321" + integrity sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw== dependencies: "@babel/runtime" "^7.4.4" prop-types "^15.7.2" @@ -2164,13 +2152,21 @@ "@types/react" "*" "@types/react-transition-group@^4.2.0": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.2.4.tgz#c7416225987ccdb719262766c1483da8f826838d" - integrity sha512-8DMUaDqh0S70TjkqU0DxOu80tFUiiaS9rxkWip/nb7gtvAsbqOXm02UCmR8zdcjWujgeYPiPNTVpVpKzUDotwA== + version "4.4.0" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" + integrity sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.9.2": +"@types/react@*": + version "16.9.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.43.tgz#c287f23f6189666ee3bebc2eb8d0f84bcb6cdb6b" + integrity sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@types/react@^16.9.2": version "16.9.23" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c" integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw== @@ -3965,9 +3961,9 @@ clone@^1.0.2: integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= clsx@^1.0.2, clsx@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" - integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== co@^4.6.0: version "4.6.0" @@ -4550,12 +4546,12 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-vendor@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.7.tgz#4e6d53d953c187981576d6a542acc9fb57174bda" - integrity sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg== +css-vendor@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" + integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== dependencies: - "@babel/runtime" "^7.6.2" + "@babel/runtime" "^7.8.3" is-in-browser "^1.0.2" css-what@2.1: @@ -4681,9 +4677,9 @@ cssstyle@^1.0.0, cssstyle@^1.1.1: cssom "0.3.x" csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.5, csstype@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" - integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + version "2.6.11" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.11.tgz#452f4d024149ecf260a852b025e36562a253ffc5" + integrity sha512-l8YyEC9NBkSm783PFTvh0FmJy7s5pFKrDp49ZL7zBGX3fWkO+N4EEyan1qqp8cwPLDcD0OSdyY6hAMoxp34JFw== csv-parse@^4.4.6: version "4.8.8" @@ -5036,11 +5032,11 @@ dom-converter@^0.2: utila "~0.4" dom-helpers@^5.0.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821" - integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw== + version "5.1.4" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b" + integrity sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A== dependencies: - "@babel/runtime" "^7.6.3" + "@babel/runtime" "^7.8.7" csstype "^2.6.7" dom-serializer@0, dom-serializer@^0.2.1: @@ -7269,9 +7265,9 @@ husky@^3.0.5: slash "^3.0.0" hyphenate-style-name@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" - integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" @@ -8668,68 +8664,69 @@ jsprim@^1.2.2: verror "1.10.0" jss-plugin-camel-case@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz#8e73ecc4f1d0f8dfe4dd31f6f9f2782588970e78" - integrity sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.3.0.tgz#ae4da53b39a6e3ea94b70a20fc41c11f0b87386a" + integrity sha512-tadWRi/SLWqLK3EUZEdDNJL71F3ST93Zrl9JYMjV0QDqKPAl0Liue81q7m/nFUpnSTXczbKDy4wq8rI8o7WFqA== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.1.1" + jss "^10.3.0" jss-plugin-default-unit@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz#2df86016dfe73085eead843f5794e3890e9c5c47" - integrity sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.3.0.tgz#cd74cf5088542620a82591f76c62c6b43a7e50a6" + integrity sha512-tT5KkIXAsZOSS9WDSe8m8lEHIjoEOj4Pr0WrG0WZZsMXZ1mVLFCSsD2jdWarQWDaRNyMj/I4d7czRRObhOxSuw== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "^10.3.0" jss-plugin-global@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz#36b0d6d9facb74dfd99590643708a89260747d14" - integrity sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.3.0.tgz#6b883e74900bb71f65ac2b19bea78f7d1e85af3f" + integrity sha512-etYTG/y3qIR/vxZnKY+J3wXwObyBDNhBiB3l/EW9/pE3WHE//BZdK8LFvQcrCO48sZW1Z6paHo6klxUPP7WbzA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "^10.3.0" jss-plugin-nested@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz#5c3de2b8bda344de1ebcef3a4fd30870a29a8a8c" - integrity sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.3.0.tgz#ae8aceac95e09c3d40c991ea32403fb647d9e0a8" + integrity sha512-qWiEkoXNEkkZ+FZrWmUGpf+zBsnEOmKXhkjNX85/ZfWhH9dfGxUCKuJFuOWFM+rjQfxV4csfesq4hY0jk8Qt0w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "^10.3.0" tiny-warning "^1.0.2" jss-plugin-props-sort@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz#34bddcbfaf9430ec8ccdf92729f03bb10caf1785" - integrity sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.3.0.tgz#5b0625f87b6431a7969c56b0d8c696525969bfe4" + integrity sha512-boetORqL/lfd7BWeFD3K+IyPqyIC+l3CRrdZr+NPq7Noqp+xyg/0MR7QisgzpxCEulk+j2CRcEUoZsvgPC4nTg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "^10.3.0" jss-plugin-rule-value-function@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz#be00dac6fc394aaddbcef5860b9eca6224d96382" - integrity sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.3.0.tgz#498b0e2bae16cb316a6bdb73fd783cf9604ba747" + integrity sha512-7WiMrKIHH3rwxTuJki9+7nY11r1UXqaUZRhHvqTD4/ZE+SVhvtD5Tx21ivNxotwUSleucA/8boX+NF21oXzr5Q== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "^10.3.0" + tiny-warning "^1.0.2" jss-plugin-vendor-prefixer@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz#8348b20749f790beebab3b6a8f7075b07c2cfcfd" - integrity sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw== + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.3.0.tgz#b09c13a4d05a055429d8a24e19cc01ce049f0ed4" + integrity sha512-sZQbrcZyP5V0ADjCLwUA1spVWoaZvM7XZ+2fSeieZFBj31cRsnV7X70FFDerMHeiHAXKWzYek+67nMDjhrZAVQ== dependencies: "@babel/runtime" "^7.3.1" - css-vendor "^2.0.7" - jss "10.1.1" + css-vendor "^2.0.8" + jss "^10.3.0" -jss@10.1.1, jss@^10.0.3: - version "10.1.1" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.1.1.tgz#450b27d53761af3e500b43130a54cdbe157ea332" - integrity sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ== +jss@^10.0.3, jss@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.3.0.tgz#2cf7be265f72b59c1764d816fdabff1c5dd18326" + integrity sha512-B5sTRW9B6uHaUVzSo9YiMEOEp3UX8lWevU0Fsv+xtRnsShmgCfIYX44bTH8bPJe6LQKqEXku3ulKuHLbxBS97Q== dependencies: "@babel/runtime" "^7.3.1" csstype "^2.6.5" @@ -10770,7 +10767,12 @@ pnp-webpack-plugin@1.6.0: dependencies: ts-pnp "^1.1.2" -popper.js@^1.14.1, popper.js@^1.16.1-lts: +popper.js@1.16.1-lts: + version "1.16.1-lts" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" + integrity sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA== + +popper.js@^1.14.1: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== @@ -11958,11 +11960,16 @@ react-input-autosize@^2.1.2: dependencies: prop-types "^15.5.8" -react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@^16.12.0, react-is@^16.6.0, react-is@^16.8.4: version "16.13.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== +react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-json-view@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c" @@ -12083,10 +12090,10 @@ react-textarea-autosize@^6.1.0: dependencies: prop-types "^15.6.0" -react-transition-group@^4.0.0, react-transition-group@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683" - integrity sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw== +react-transition-group@^4.0.0, react-transition-group@^4.3.0, react-transition-group@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" + integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== dependencies: "@babel/runtime" "^7.5.5" dom-helpers "^5.0.1" From 356ed725e00dbb98edd69457c3673a2c49bfabfb Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Mon, 3 Aug 2020 14:18:39 +1000 Subject: [PATCH 04/14] add comment --- www/src/components/SideDrawer/Form/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/www/src/components/SideDrawer/Form/index.tsx b/www/src/components/SideDrawer/Form/index.tsx index 194e6bd6..f7bb23d6 100644 --- a/www/src/components/SideDrawer/Form/index.tsx +++ b/www/src/components/SideDrawer/Form/index.tsx @@ -184,6 +184,8 @@ export default function Form({ fields, values }: IFormProps) { const field: Field = _isFunction(_field) ? _field(values) : _field; const { type, ...fieldProps } = field; let _type = type; + + // Derivative field support if (field.config && field.config.renderFieldType) { _type = field.config.renderFieldType; } From 9c50512a7c697983be848ebc82bcd3d2ab2ef87f Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Fri, 21 Aug 2020 16:48:38 +1000 Subject: [PATCH 05/14] update firestore console url --- www/src/components/SideDrawer/Form/FieldWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/src/components/SideDrawer/Form/FieldWrapper.tsx b/www/src/components/SideDrawer/Form/FieldWrapper.tsx index 2292b242..3e5df0a9 100644 --- a/www/src/components/SideDrawer/Form/FieldWrapper.tsx +++ b/www/src/components/SideDrawer/Form/FieldWrapper.tsx @@ -96,7 +96,7 @@ export default function FieldWrapper({ component="a" href={`https://console.firebase.google.com/project/${ process.env.REACT_APP_FIREBASE_PROJECT_ID - }/database/firestore/data~2F${(debugText as string).replace( + }/firestore/data~2F${(debugText as string).replace( /\//g, "~2F" )}`} From 7b58721bbb412d2caf1535d0857a3b9334741366 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Fri, 21 Aug 2020 17:19:19 +1000 Subject: [PATCH 06/14] fix Form not updating values when navigating up/down --- www/src/components/SideDrawer/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/src/components/SideDrawer/index.tsx b/www/src/components/SideDrawer/index.tsx index 042fc119..4a9a0d67 100644 --- a/www/src/components/SideDrawer/index.tsx +++ b/www/src/components/SideDrawer/index.tsx @@ -115,7 +115,11 @@ export default function SideDrawer() {
{open && fields && cell && ( -
+ )}
From 90cdd14cb7383875f91a857b367afee0fcbfaad5 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Fri, 21 Aug 2020 17:42:38 +1000 Subject: [PATCH 07/14] enable Autosave --- .../components/SideDrawer/Form/Autosave.tsx | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/www/src/components/SideDrawer/Form/Autosave.tsx b/www/src/components/SideDrawer/Form/Autosave.tsx index 49597eb1..99170454 100644 --- a/www/src/components/SideDrawer/Form/Autosave.tsx +++ b/www/src/components/SideDrawer/Form/Autosave.tsx @@ -4,22 +4,30 @@ import _isEqual from "lodash/isEqual"; import _pick from "lodash/pick"; import _omitBy from "lodash/omitBy"; import _isUndefined from "lodash/isUndefined"; +import _reduce from "lodash/reduce"; -import { FormikErrors } from "formik"; +import { Control, useWatch } from "react-hook-form"; import { Values } from "."; import { useAppContext } from "contexts/appContext"; import { useFiretableContext, firetableUser } from "contexts/firetableContext"; export interface IAutosaveProps { - values: Values; - errors: FormikErrors; + control: Control; + defaultValues: Values; + docRef: firebase.firestore.DocumentReference; } -export default function Autosave({ values, errors }: IAutosaveProps) { +export default function Autosave({ + control, + defaultValues, + docRef, +}: IAutosaveProps) { const { currentUser } = useAppContext(); const { tableState, sideDrawerRef } = useFiretableContext(); + const values = useWatch({ control }); + const getEditables = value => _pick( value, @@ -41,21 +49,29 @@ export default function Autosave({ values, errors }: IAutosaveProps) { useEffect(() => { if (!row || !row.ref) return; - if (_isEqual(getEditables(row), debouncedValue)) return; - if (row.ref.id !== values.ref.id) return; + if (row.ref.id !== docRef.id) return; + // Get only fields that have changed and // Remove undefined value to prevent Firestore crash - const updatedValues = _omitBy(debouncedValue, _isUndefined); + const updatedValues = _omitBy( + _omitBy(debouncedValue, _isUndefined), + (value, key) => _isEqual(value, row[key]) + ); + console.log(updatedValues); + + if (Object.keys(updatedValues).length === 0) return; const _ft_updatedAt = new Date(); const _ft_updatedBy = firetableUser(currentUser); - row.ref.update({ - ...updatedValues, - _ft_updatedAt, - updatedAt: _ft_updatedAt, - _ft_updatedBy, - updatedBy: _ft_updatedBy, - }); + row.ref + .update({ + ...updatedValues, + _ft_updatedAt, + updatedAt: _ft_updatedAt, + _ft_updatedBy, + updatedBy: _ft_updatedBy, + }) + .then(() => console.log("Updated row", row.ref.id, updatedValues)); }, [debouncedValue]); return null; From d7bb345f9f1b952ce7f4da2253933dbb7f8cb676 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Fri, 21 Aug 2020 21:52:18 +1000 Subject: [PATCH 08/14] migrate remaining fields to react-hook-form --- .../SideDrawer/Form/Fields/Action.tsx | 170 +++++----- .../SideDrawer/Form/Fields/Checkbox.tsx | 60 ++-- .../SideDrawer/Form/Fields/Code.tsx | 48 ++- .../SideDrawer/Form/Fields/Color.tsx | 91 +++--- .../SideDrawer/Form/Fields/ConnectTable.tsx | 102 +++--- .../SideDrawer/Form/Fields/DatePicker.tsx | 69 ++-- .../SideDrawer/Form/Fields/DateTimePicker.tsx | 71 ++-- .../SideDrawer/Form/Fields/FileUploader.tsx | 65 ++-- .../SideDrawer/Form/Fields/ImageUploader.tsx | 63 ++-- .../SideDrawer/Form/Fields/JsonEditor.tsx | 88 ++--- .../SideDrawer/Form/Fields/Radio.tsx | 82 ----- .../SideDrawer/Form/Fields/Rating.tsx | 50 +-- .../SideDrawer/Form/Fields/RichText.tsx | 21 +- .../SideDrawer/Form/Fields/Slider.tsx | 117 ++++--- .../SideDrawer/Form/Fields/SubTable.tsx | 27 +- .../SideDrawer/Form/Fields/Text.tsx | 58 +++- .../SideDrawer/Form/Fields/TextMulti.tsx | 124 ------- .../components/SideDrawer/Form/Fields/Url.tsx | 2 +- www/src/components/SideDrawer/Form/index.tsx | 306 +++++++++--------- 19 files changed, 792 insertions(+), 822 deletions(-) delete mode 100644 www/src/components/SideDrawer/Form/Fields/Radio.tsx delete mode 100644 www/src/components/SideDrawer/Form/Fields/TextMulti.tsx diff --git a/www/src/components/SideDrawer/Form/Fields/Action.tsx b/www/src/components/SideDrawer/Form/Fields/Action.tsx index 16a8c025..eb799056 100644 --- a/www/src/components/SideDrawer/Form/Fields/Action.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Action.tsx @@ -1,5 +1,5 @@ import React, { useContext, useState } from "react"; -import { FieldProps } from "formik"; +import { Control, Controller, useWatch } from "react-hook-form"; import { createStyles, @@ -40,87 +40,109 @@ const useStyles = makeStyles(theme => }) ); -function Action({ - field, - form, - editable, - config, -}: FieldProps & { config: { callableName: string }; editable?: boolean }) { +export interface IActionProps { + control: Control; + name: string; + docRef: firebase.firestore.DocumentReference; + config: { callableName: string }; + editable?: boolean; +} + +function Action({ control, name, docRef, editable, config }: IActionProps) { const classes = useStyles(); - const { ref, ...docData } = form.values; + const docData = useWatch({ control }); const [isRunning, setIsRunning] = useState(false); const snack = useContext(SnackContext); - const handleRun = () => { - setIsRunning(true); - console.log("RUN"); - cloudFunction( - config.callableName, - { - ref: { path: ref.path, id: ref.id }, - row: sanitiseRowData(Object.assign({}, docData)), - }, - response => { - const { message, cellValue } = response.data; - setIsRunning(false); - snack.open({ message, severity: "success" }); - if (cellValue) form.setFieldValue(field.name, cellValue); - }, - error => { - console.error("ERROR", config.callableName, error); - setIsRunning(false); - snack.open({ message: JSON.stringify(error), severity: "error" }); - } - ); - }; - - const hasRan = field.value && field.value.status; const disabled = editable === false; - return ( - - - - - {hasRan && isUrl(field.value.status) ? ( - - {field.value.status} - - ) : hasRan ? ( - field.value.status - ) : ( - sanitiseCallableName(config.callableName) - )} - - - - - - {isRunning ? ( - - ) : hasRan ? ( - - ) : ( - - )} - - - + return ( + { + const handleRun = () => { + setIsRunning(true); + console.log("RUN"); + + cloudFunction( + config.callableName, + { + ref: { path: docRef.path, id: docRef.id }, + row: sanitiseRowData(Object.assign({}, docData)), + }, + response => { + const { message, cellValue } = response.data; + setIsRunning(false); + snack.open({ message, severity: "success" }); + if (cellValue) onChange(cellValue); + }, + error => { + console.error("ERROR", config.callableName, error); + setIsRunning(false); + snack.open({ message: JSON.stringify(error), severity: "error" }); + } + ); + }; + + const hasRan = value && value.status; + + return ( + + + + + {hasRan && isUrl(value.status) ? ( + + {value.status} + + ) : hasRan ? ( + value.status + ) : ( + sanitiseCallableName(config.callableName) + )} + + + + + + + {isRunning ? ( + + ) : hasRan ? ( + + ) : ( + + )} + + + + ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx index fd0caf7e..60413511 100644 --- a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx @@ -55,38 +55,36 @@ export default function Checkbox({ const classes = useStyles(); return ( - <> - - { - const handleChange = ( - event: React.ChangeEvent - ) => { - onChange(event.target.checked); - }; + { + const handleChange = (event: React.ChangeEvent) => { + onChange(event.target.checked); + }; - return ( - - ); - }} + const handleClick = () => onChange(!value); + + return ( + + + } + label={label} + labelPlacement="start" + classes={{ root: classes.formControlLabel, label: classes.label }} /> - } - label={label} - labelPlacement="start" - classes={{ root: classes.formControlLabel, label: classes.label }} - /> - - + + ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Code.tsx b/www/src/components/SideDrawer/Form/Fields/Code.tsx index 5fa167a4..c2533dfd 100644 --- a/www/src/components/SideDrawer/Form/Fields/Code.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Code.tsx @@ -1,12 +1,11 @@ import React, { useState, useEffect, useRef } from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import AceEditor from "react-ace"; import "ace-builds/src-noconflict/mode-javascript"; -import "ace-builds/src-noconflict/theme-monokai"; +import "ace-builds/src-noconflict/theme-github"; import { makeStyles, createStyles, Button } from "@material-ui/core"; -import ErrorMessage from "../ErrorMessage"; import CornerResizeIcon from "assets/icons/CornerResize"; const useStyles = makeStyles(theme => @@ -35,17 +34,23 @@ const useStyles = makeStyles(theme => }) ); -export default function Code({ form, field }: FieldProps) { +export interface IControlledCodeProps { + onChange: (...event: any[]) => void; + onBlur: () => void; + value: any; +} + +function ControlledCode({ onChange, onBlur, value }: IControlledCodeProps) { const classes = useStyles(); - const [localValue, setLocalValue] = useState(field.value); + const [localValue, setLocalValue] = useState(value); useEffect(() => { - if (field.value !== localValue) setLocalValue(field.value); - }, [field.value]); + if (value !== localValue) setLocalValue(value); + }, [value]); const autoSave = false; const handleChange = autoSave - ? value => form.setFieldValue(field.name, value) + ? value => onChange(value) : value => setLocalValue(value); const editor = useRef(null); @@ -58,11 +63,9 @@ export default function Code({ form, field }: FieldProps) { <>
- {!autoSave && field.value !== localValue && ( + {!autoSave && value !== localValue && ( )} - - ); } + +export interface ICodeProps { + control: Control; + name: string; +} + +export default function Code({ control, name, ...props }: ICodeProps) { + return ( + } + /> + ); +} diff --git a/www/src/components/SideDrawer/Form/Fields/Color.tsx b/www/src/components/SideDrawer/Form/Fields/Color.tsx index a2b290d7..2dabde02 100644 --- a/www/src/components/SideDrawer/Form/Fields/Color.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Color.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { ChromePicker } from "react-color"; import { @@ -18,7 +18,16 @@ const useStyles = makeStyles(theme => cursor: "pointer", textAlign: "left", borderRadius: theme.shape.borderRadius, + + backgroundColor: + theme.palette.type === "light" + ? "rgba(0, 0, 0, 0.09)" + : "rgba(255, 255, 255, 0.09)", + margin: 0, + width: "100%", + padding: theme.spacing(0, 0.75), }, + colorIndicator: { width: 20, height: 20, @@ -30,51 +39,57 @@ const useStyles = makeStyles(theme => }) ); -export interface IColorProps extends FieldProps {} +export interface IColorProps { + control: Control; + name: string; +} -export default function Color({ field, form }: IColorProps) { +export default function Color({ control, name }: IColorProps) { const classes = useStyles(); const [showPicker, setShowPicker] = useState(false); const toggleOpen = () => setShowPicker(s => !s); - const handleChangeComplete = color => { - form.setFieldValue(field.name, color); - }; - return ( - <> - - -
- - - - ( + <> + { + toggleOpen(); + onBlur(); + }} + component={ButtonBase} + focusRipple > - {field.value.hex ?? "Choose a color…"} - - - + +
+ - - - - + + + {value?.hex ?? "Choose a color…"} + + + + + + + + + )} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx b/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx index ee9e457a..b383b957 100644 --- a/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx +++ b/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx @@ -1,63 +1,75 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Control, Controller } from "react-hook-form"; import { useTheme, Grid, Chip } from "@material-ui/core"; import ConnectTableSelect, { - ConnectTableValue, IConnectTableSelectProps, } from "components/ConnectTableSelect"; +export interface IConnectTableProps extends Partial { + control: Control; + name: string; +} + export default function ConnectTable({ - field, - form, + control, + name, editable, ...props -}: FieldProps & IConnectTableSelectProps) { +}: IConnectTableProps) { const theme = useTheme(); - const handleDelete = (hit: any) => () => { - // if (multiple) - form.setFieldValue( - field.name, - field.value.filter(v => v.snapshot.objectID !== hit.objectID) - ); - // else form.setFieldValue(field.name, []); - }; const disabled = editable === false; - return ( - <> - {!disabled && ( - form.setFieldValue(field.name, value)} - TextFieldProps={{ - fullWidth: true, - error: !!(form.touched[field.name] && form.errors[field.name]), - helperText: - (form.touched[field.name] && form.errors[field.name]) || "", - onBlur: () => form.setFieldTouched(field.name), - }} - /> - )} - {Array.isArray(field.value) && ( - - {field.value.map(({ snapshot }) => ( - - snapshot[key]) - .join(" ")} - onDelete={disabled ? undefined : handleDelete(snapshot)} + return ( + { + const handleDelete = (hit: any) => () => { + // if (multiple) + onChange(value.filter(v => v.snapshot.objectID !== hit.objectID)); + // else form.setFieldValue(field.name, []); + }; + + return ( + <> + {!disabled && ( + - - ))} - - )} - + )} + + {Array.isArray(value) && ( + + {value.map(({ snapshot }) => ( + + snapshot[key]) + .join(" ")} + onDelete={disabled ? undefined : handleDelete(snapshot)} + /> + + ))} + + )} + + ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx index f59c0ac6..2cf36fd0 100644 --- a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx @@ -8,6 +8,9 @@ import { } from "@material-ui/pickers"; import { DATE_FORMAT } from "constants/dates"; +import { MuiPickersUtilsProvider } from "@material-ui/pickers"; +import DateFnsUtils from "@date-io/date-fns"; + export interface IDatePickerProps extends Omit { control: Control; @@ -22,38 +25,42 @@ export default function DatePicker({ const theme = useTheme(); return ( - { - let transformedValue = null; - if (value && "toDate" in value) transformedValue = value.toDate(); - else if (value !== undefined) transformedValue = value; + + { + let transformedValue = null; + if (value && "toDate" in value) transformedValue = value.toDate(); + else if (value !== undefined) transformedValue = value; - const handleChange = (date: Date | null) => { - if (isNaN(date?.valueOf() ?? 0)) return; - onChange(date); - }; + const handleChange = (date: Date | null) => { + if (isNaN(date?.valueOf() ?? 0)) return; + onChange(date); + }; - return ( - - ); - }} - /> + return ( + + ); + }} + /> + ); } diff --git a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx index aa26b1f0..f52ed273 100644 --- a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx @@ -10,6 +10,9 @@ import { DATE_TIME_FORMAT } from "constants/dates"; import AccessTimeIcon from "@material-ui/icons/AccessTime"; +import { MuiPickersUtilsProvider } from "@material-ui/pickers"; +import DateFnsUtils from "@date-io/date-fns"; + export interface IDateTimePickerProps extends Omit { control: Control; @@ -24,39 +27,43 @@ export default function DateTimePicker({ const theme = useTheme(); return ( - { - let transformedValue = null; - if (value && "toDate" in value) transformedValue = value.toDate(); - else if (value !== undefined) transformedValue = value; + + { + let transformedValue = null; + if (value && "toDate" in value) transformedValue = value.toDate(); + else if (value !== undefined) transformedValue = value; - const handleChange = (date: Date | null) => { - if (isNaN(date?.valueOf() ?? 0)) return; - onChange(date); - }; + const handleChange = (date: Date | null) => { + if (isNaN(date?.valueOf() ?? 0)) return; + onChange(date); + }; - return ( - } - {...props} - value={transformedValue} - onChange={handleChange} - onBlur={onBlur} - label="" - hiddenLabel - id={`sidedrawer-field-${name}`} - /> - ); - }} - /> + return ( + } + {...props} + value={transformedValue} + onChange={handleChange} + onBlur={onBlur} + label="" + hiddenLabel + id={`sidedrawer-field-${name}`} + /> + ); + }} + /> + ); } diff --git a/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx b/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx index 7eb59de4..fcd43519 100644 --- a/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx +++ b/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from "react"; import clsx from "clsx"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { useDropzone } from "react-dropzone"; import useUploader, { FileValue } from "hooks/useFiretable/useUploader"; @@ -19,7 +19,6 @@ import { import UploadIcon from "assets/icons/Upload"; import { FileIcon } from "constants/fields"; -import ErrorMessage from "../ErrorMessage"; import Confirmation from "components/Confirmation"; const useStyles = makeStyles(theme => @@ -55,17 +54,21 @@ const useStyles = makeStyles(theme => }) ); -export interface IFileUploaderProps extends FieldProps { - editable?: boolean; - docRef?: firebase.firestore.DocumentReference; +export interface IControlledFileUploaderProps + extends Pick { + onChange: (...event: any[]) => void; + onBlur: () => void; + value: any; } -export default function FileUploader({ - form, - field, +export function ControlledFileUploader({ + onChange, + onBlur, + value, + name, docRef, editable, -}: IFileUploaderProps) { +}: IControlledFileUploaderProps) { const classes = useStyles(); const { uploaderState, upload, deleteUpload } = useUploader(); @@ -81,25 +84,25 @@ export default function FileUploader({ if (docRef && file) { upload({ docRef, - fieldName: field.name, + fieldName: name, files: [file], - previousValue: field.value ?? [], + previousValue: value ?? [], onComplete: newValue => { - form.setFieldValue(field.name, newValue); + onChange(newValue); setLocalFile(""); }, }); setLocalFile(file.name); } }, - [docRef, field.value] + [docRef, value] ); const handleDelete = (index: number) => { - const newValue = [...field.value]; + const newValue = [...value]; const toBeDeleted = newValue.splice(index, 1); toBeDeleted.length && deleteUpload(toBeDeleted[0]); - form.setFieldValue(field.name, newValue); + onChange(newValue); }; const { getRootProps, getInputProps, isDragActive } = useDropzone({ @@ -117,7 +120,7 @@ export default function FileUploader({ )} {...getRootProps()} > - + Upload file @@ -126,8 +129,8 @@ export default function FileUploader({ )} - {Array.isArray(field.value) && - field.value.map((file: FileValue, i) => ( + {Array.isArray(value) && + value.map((file: FileValue, i) => ( )} - - ); } + +export interface IFileUploaderProps { + control: Control; + name: string; + + editable?: boolean; + docRef?: firebase.firestore.DocumentReference; +} + +export default function FileUploader({ + control, + name, + ...props +}: IFileUploaderProps) { + return ( + ( + + )} + /> + ); +} diff --git a/www/src/components/SideDrawer/Form/Fields/ImageUploader.tsx b/www/src/components/SideDrawer/Form/Fields/ImageUploader.tsx index 9b5c741b..020d85eb 100644 --- a/www/src/components/SideDrawer/Form/Fields/ImageUploader.tsx +++ b/www/src/components/SideDrawer/Form/Fields/ImageUploader.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from "react"; import clsx from "clsx"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { useDropzone } from "react-dropzone"; import useUploader from "hooks/useFiretable/useUploader"; @@ -91,17 +91,21 @@ const useStyles = makeStyles(theme => }) ); -export interface IImageUploaderProps extends FieldProps { - docRef?: firebase.firestore.DocumentReference; - editable?: boolean; +export interface IControlledImageUploaderProps + extends Pick { + onChange: (...event: any[]) => void; + onBlur: () => void; + value: any; } -export default function ImageUploader({ - form, - field, +export function ControlledImageUploader({ + onChange, + onBlur, + value, + name, editable, docRef, -}: IImageUploaderProps) { +}: IControlledImageUploaderProps) { const disabled = editable === false; const classes = useStyles(); @@ -118,25 +122,25 @@ export default function ImageUploader({ if (docRef && imageFile) { upload({ docRef, - fieldName: field.name, + fieldName: name, files: [imageFile], - previousValue: field.value ?? [], + previousValue: value ?? [], onComplete: newValue => { - form.setFieldValue(field.name, newValue); + onChange(newValue); setLocalImage(""); }, }); setLocalImage(URL.createObjectURL(imageFile)); } }, - [docRef, field.value] + [docRef, value] ); const handleDelete = (index: number) => { - const newValue = [...field.value]; + const newValue = [...value]; const toBeDeleted = newValue.splice(index, 1); toBeDeleted.length && deleteUpload(toBeDeleted[0]); - form.setFieldValue(field.name, newValue); + onChange(newValue); }; const { getRootProps, getInputProps, isDragActive } = useDropzone({ @@ -155,7 +159,7 @@ export default function ImageUploader({ )} {...getRootProps()} > - + {isDragActive ? "Drop your image here" : "Upload image"} @@ -164,8 +168,8 @@ export default function ImageUploader({ )} - {Array.isArray(field.value) && - field.value.map((image, i) => ( + {Array.isArray(value) && + value.map((image, i) => ( {disabled ? ( @@ -246,8 +250,29 @@ export default function ImageUploader({ )} - - ); } +export interface IImageUploaderProps { + control: Control; + name: string; + + docRef?: firebase.firestore.DocumentReference; + editable?: boolean; +} + +export default function ImageUploader({ + control, + name, + ...props +}: IImageUploaderProps) { + return ( + ( + + )} + /> + ); +} diff --git a/www/src/components/SideDrawer/Form/Fields/JsonEditor.tsx b/www/src/components/SideDrawer/Form/Fields/JsonEditor.tsx index 2681261d..ed20898c 100644 --- a/www/src/components/SideDrawer/Form/Fields/JsonEditor.tsx +++ b/www/src/components/SideDrawer/Form/Fields/JsonEditor.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Control, Controller } from "react-hook-form"; import ReactJson from "react-json-view"; import { makeStyles, createStyles, useTheme } from "@material-ui/core"; @@ -32,45 +32,59 @@ const isValidJson = (val: any) => { return true; }; -export default function JsonEditor({ form, field }: FieldProps) { +export interface IJsonEditorProps { + control: Control; + name: string; +} + +export default function JsonEditor({ control, name }: IJsonEditorProps) { const classes = useStyles(); const theme = useTheme(); - const handleEdit = edit => { - form.setFieldValue(field.name, edit.updated_src); - }; - return ( -
- -
+ { + const handleEdit = edit => { + onChange(edit.updated_src); + }; + + return ( +
+ +
+ ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Radio.tsx b/www/src/components/SideDrawer/Form/Fields/Radio.tsx deleted file mode 100644 index fde558b5..00000000 --- a/www/src/components/SideDrawer/Form/Fields/Radio.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from "react"; - -import { - makeStyles, - createStyles, - FormControl, - FormControlLabel, - Radio as MuiRadio, - Divider, -} from "@material-ui/core"; -import { RadioGroup, RadioGroupProps } from "formik-material-ui"; - -import Label from "../Label"; -import ErrorMessage from "../ErrorMessage"; - -const useStyles = makeStyles(theme => - createStyles({ - root: { display: "flex" }, - - formControlLabel: { - padding: theme.spacing(1.25, 0), - marginLeft: theme.spacing(1), - }, - - divider: { marginLeft: theme.spacing(5) }, - }) -); - -export interface IRadioProps extends RadioGroupProps { - options: (string | { value: string; label: React.ReactNode })[]; - label?: React.ReactNode; -} - -export default function Radio({ options, label, ...props }: IRadioProps) { - const classes = useStyles(); - - return ( - - - - - {options.map(item => { - let option: { label: React.ReactNode; value: string } = { - label: "", - value: "", - }; - if (typeof item === "object") option = item; - if (typeof item === "string") option = { label: item, value: item }; - - return ( - - - } - classes={{ label: classes.formControlLabel }} - //disabled={isSubmitting} - /> - - - ); - })} - - - - - ); -} diff --git a/www/src/components/SideDrawer/Form/Fields/Rating.tsx b/www/src/components/SideDrawer/Form/Fields/Rating.tsx index dc7a7ce7..f092e952 100644 --- a/www/src/components/SideDrawer/Form/Fields/Rating.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Rating.tsx @@ -1,12 +1,10 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { makeStyles, createStyles, Grid } from "@material-ui/core"; import { Rating as MuiRating } from "@material-ui/lab"; import StarBorderIcon from "@material-ui/icons/StarBorder"; -import ErrorMessage from "../ErrorMessage"; - const useStyles = makeStyles(theme => createStyles({ root: { @@ -27,32 +25,36 @@ const useStyles = makeStyles(theme => }) ); -export interface IRatingProps extends FieldProps { +export interface IRatingProps { + control: Control; + name: string; editable?: boolean; } -export default function Rating(props: IRatingProps) { +export default function Rating({ control, name, editable }: IRatingProps) { const classes = useStyles(); return ( - <> - - { - props.form.setFieldValue(props.field.name, newValue); - }} - emptyIcon={} - classes={{ root: classes.rating, iconEmpty: classes.iconEmpty }} - // TODO: Make this customisable in column settings - max={4} - /> - - - - + ( + + { + onChange(newValue); + }} + emptyIcon={} + classes={{ root: classes.rating, iconEmpty: classes.iconEmpty }} + // TODO: Make this customisable in column settings + max={4} + /> + + )} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/RichText.tsx b/www/src/components/SideDrawer/Form/Fields/RichText.tsx index ecaf2f72..696380b4 100644 --- a/www/src/components/SideDrawer/Form/Fields/RichText.tsx +++ b/www/src/components/SideDrawer/Form/Fields/RichText.tsx @@ -1,16 +1,21 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Control, Controller } from "react-hook-form"; import _RichText from "components/RichText"; -import ErrorMessage from "../ErrorMessage"; -export default function RichText({ form, field }: FieldProps) { - const handleChange = value => form.setFieldValue(field.name, value); +export interface IRichTextProps { + control: Control; + name: string; +} +export default function RichText({ control, name }: IRichTextProps) { return ( - <> - <_RichText value={field.value} onChange={handleChange} /> - - + ( + <_RichText value={value} onChange={onChange} /> + )} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/Slider.tsx b/www/src/components/SideDrawer/Form/Fields/Slider.tsx index b53a47d3..139403db 100644 --- a/www/src/components/SideDrawer/Form/Fields/Slider.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Slider.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Controller, Control } from "react-hook-form"; import { makeStyles, @@ -11,8 +11,6 @@ import { Typography, } from "@material-ui/core"; -import ErrorMessage from "../ErrorMessage"; - const useStyles = makeStyles(theme => createStyles({ root: { display: "flex" }, @@ -45,17 +43,17 @@ const useStyles = makeStyles(theme => }) ); -export interface ISliderProps extends FieldProps, SliderProps { - label: React.ReactNode; +export interface ISliderProps extends SliderProps { + control: Control; + name: string; units?: string; minLabel?: React.ReactNode; maxLabel?: React.ReactNode; } export default function Slider({ - field, - form, - label, + control, + name, units, minLabel, maxLabel, @@ -65,54 +63,67 @@ export default function Slider({ }: ISliderProps) { const classes = useStyles(); - const handleClick = () => form.setFieldTouched(field.name); - const handleChange = (event: any, value: number | number[]) => { - form.setFieldValue(field.name, value); - form.setFieldTouched(field.name); - }; - - const getAriaValueText = (value: number) => - `${value}${units ? " " + units : ""}`; - - const getValueLabelFormat = (value: number) => - `${value}${units ? " " + units : ""}`; - return ( - - - - - {minLabel ?? `${min}${units ? " " + units : ""}`} - - + { + const handleChange = (_: any, value: number | number[]) => { + onChange(value); + onBlur(); + }; - - - + const getAriaValueText = (value: number) => + `${value}${units ? " " + units : ""}`; - - - {maxLabel ?? `${max}${units ? " " + units : ""}`} - - - + const getValueLabelFormat = (value: number) => + `${value}${units ? " " + units : ""}`; - - + return ( + + + + + {minLabel ?? `${min}${units ? " " + units : ""}`} + + + + + + + + + + {maxLabel ?? `${max}${units ? " " + units : ""}`} + + + + + ); + }} + /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/SubTable.tsx b/www/src/components/SideDrawer/Form/Fields/SubTable.tsx index d86b2743..1303db65 100644 --- a/www/src/components/SideDrawer/Form/Fields/SubTable.tsx +++ b/www/src/components/SideDrawer/Form/Fields/SubTable.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FieldProps } from "formik"; +import { Control, useWatch } from "react-hook-form"; import { Link } from "react-router-dom"; import queryString from "query-string"; @@ -31,30 +31,41 @@ const useStyles = makeStyles(theme => }) ); +export interface ISubTableProps { + control: Control; + name: string; + docRef: firebase.firestore.DocumentReference; + config: { parentLabel?: string[] }; + label: string; +} + export default function SubTable({ - form, - field, + control, + name, + docRef, label, config, -}: FieldProps & { config: { parentLabel?: string[] }; label: string }) { +}: ISubTableProps) { const classes = useStyles(); + const values = useWatch({ control }); + const router = useRouter(); const parentLabels = queryString.parse(router.location.search).parentLabel; const _label = config?.parentLabel ? config.parentLabel.reduce((acc, curr) => { - if (acc !== "") return `${acc} - ${form.values[curr]}`; - else return form.values[curr]; + if (acc !== "") return `${acc} - ${values[curr]}`; + else return values[curr]; }, "") : ""; let subTablePath = ""; if (parentLabels) subTablePath = - encodeURIComponent(`${form.values.ref.path}/${field.name}`) + + encodeURIComponent(`${docRef.path}/${name}`) + `?parentLabel=${parentLabels},${label}`; else subTablePath = - encodeURIComponent(`${form.values.ref.path}/${field.name}`) + + encodeURIComponent(`${docRef.path}/${name}`) + `?parentLabel=${encodeURIComponent(_label)}`; return ( diff --git a/www/src/components/SideDrawer/Form/Fields/Text.tsx b/www/src/components/SideDrawer/Form/Fields/Text.tsx index 80fcf79d..242a47b6 100644 --- a/www/src/components/SideDrawer/Form/Fields/Text.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Text.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { Controller, Control } from "react-hook-form"; import { makeStyles, @@ -13,12 +14,23 @@ const useStyles = makeStyles(theme => }) ); -export interface ITextProps extends Omit { - fieldVariant?: "short" | "long" | "email" | "phone" | "number" | "url"; +export interface IFieldProps { + control: Control; + name: string; + docRef: firebase.firestore.DocumentReference; editable?: boolean; } +export interface ITextProps + extends IFieldProps, + Omit { + fieldVariant?: "short" | "long" | "email" | "phone" | "number" | "url"; +} + export default function Text({ + control, + name, + docRef, fieldVariant = "short", editable, ...props @@ -48,7 +60,7 @@ export default function Text({ break; case "number": - variantProps = { type: "number" }; + variantProps = { inputmode: "numeric", pattern: "[0-9]*" }; break; case "short": @@ -57,19 +69,33 @@ export default function Text({ } return ( - { + const handleChange = e => { + if (fieldVariant === "number") onChange(parseInt(e.target.value, 10)); + else onChange(e.target.value); + }; + + return ( + + ); + }} /> ); } diff --git a/www/src/components/SideDrawer/Form/Fields/TextMulti.tsx b/www/src/components/SideDrawer/Form/Fields/TextMulti.tsx deleted file mode 100644 index a819c77d..00000000 --- a/www/src/components/SideDrawer/Form/Fields/TextMulti.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import React, { useState } from "react"; -import { FieldProps } from "formik"; - -import { - makeStyles, - createStyles, - FormControl, - Grid, - TextField, - IconButton, - List, - ListItem, - ListItemText, - ListItemSecondaryAction, - Divider, -} from "@material-ui/core"; -import AddIcon from "@material-ui/icons/Add"; -import DeleteIcon from "@material-ui/icons/Cancel"; - -import Label from "../Label"; -import ErrorMessage from "../ErrorMessage"; - -const useStyles = makeStyles(theme => - createStyles({ - root: { display: "flex" }, - list: { marginBottom: theme.spacing(2) }, - }) -); - -export interface ITextMultiProps extends FieldProps { - label: React.ReactNode; - addItemLabel?: string; - addItemPlaceholder?: string; -} - -export default function TextMulti({ - form, - field, - label, - addItemLabel, - addItemPlaceholder, -}: ITextMultiProps) { - const classes = useStyles(); - const [itemToAdd, setItemToAdd] = useState(""); - - const handleAddToList = () => { - if (Array.isArray(field.value)) - form.setFieldValue(field.name, [...field.value, itemToAdd]); - else form.setFieldValue(field.name, [itemToAdd]); - setItemToAdd(""); - }; - const handleDeleteFromList = (i: number) => { - if (!Array.isArray(field.value)) form.setFieldValue(field.name, []); - const newValues = [...field.value]; - newValues.splice(i, 1); - form.setFieldValue(field.name, newValues); - }; - - return ( - - - - - {Array.isArray(field.value) && - field.value.map((item: string, i: number) => ( - - - - - { - handleDeleteFromList(i); - form.setFieldTouched(field.name); - }} - size="small" - > - - - - - - - ))} - - - - - { - handleAddToList(); - form.setFieldTouched(field.name); - }} - > - - - - - - setItemToAdd(e.target.value)} - variant="filled" - fullWidth - value={itemToAdd} - label={addItemLabel || `Add ${label}`} - placeholder={addItemPlaceholder} - onKeyPress={e => { - if (e.key === "Enter") handleAddToList(); - }} - // NOTE: Field is not automatically touched, has to be set here - onBlur={() => form.setFieldTouched(field.name)} - /> - - - - - - ); -} diff --git a/www/src/components/SideDrawer/Form/Fields/Url.tsx b/www/src/components/SideDrawer/Form/Fields/Url.tsx index ae228701..f7bb23fa 100644 --- a/www/src/components/SideDrawer/Form/Fields/Url.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Url.tsx @@ -31,7 +31,7 @@ export default function Url({ control, name, ...props }: IUrlProps) { {...props} onChange={onChange} onBlur={onBlur} - value={value} + value={value || ""} id={`sidedrawer-field-${name}`} label="" hiddenLabel diff --git a/www/src/components/SideDrawer/Form/index.tsx b/www/src/components/SideDrawer/Form/index.tsx index f7bb23d6..e096c1ce 100644 --- a/www/src/components/SideDrawer/Form/index.tsx +++ b/www/src/components/SideDrawer/Form/index.tsx @@ -1,11 +1,9 @@ -import React, { lazy, useEffect } from "react"; -import { useForm, useWatch, Control } from "react-hook-form"; -import { MuiPickersUtilsProvider } from "@material-ui/pickers"; -import DateFnsUtils from "@date-io/date-fns"; +import React, { lazy } from "react"; +import { useForm } from "react-hook-form"; import _isFunction from "lodash/isFunction"; import _isEmpty from "lodash/isEmpty"; -import { useFiretableContext } from "contexts/firetableContext"; +// import { useFiretableContext } from "contexts/firetableContext"; import { Grid } from "@material-ui/core"; @@ -143,16 +141,13 @@ export interface IFormProps { export default function Form({ fields, values }: IFormProps) { const initialValues = getInitialValues(fields); - const { ref: firestoreRef, ...rowValues } = values; + const { ref: docRef, ...rowValues } = values; const defaultValues = { ...initialValues, ...rowValues }; - const { register, handleSubmit, control, reset } = useForm({ + const { register, control } = useForm({ mode: "onBlur", defaultValues, }); - const onSubmit = data => { - console.log("SUBMIT", data); - }; // Update field values when Firestore document updates // useEffect(() => { @@ -173,181 +168,168 @@ export default function Form({ fields, values }: IFormProps) { // }, [sideDrawerRef?.current]); return ( - - - + + - - {fields.map((_field, i) => { - // Call the field function with values if necessary - // Otherwise, just use the field object - const field: Field = _isFunction(_field) ? _field(values) : _field; - const { type, ...fieldProps } = field; - let _type = type; + + {fields.map((_field, i) => { + // Call the field function with values if necessary + // Otherwise, just use the field object + const field: Field = _isFunction(_field) ? _field(values) : _field; + const { type, ...fieldProps } = field; + let _type = type; - // Derivative field support - if (field.config && field.config.renderFieldType) { - _type = field.config.renderFieldType; - } + // Derivative field support + if (field.config && field.config.renderFieldType) { + _type = field.config.renderFieldType; + } - let renderedField: React.ReactNode = null; + let renderedField: React.ReactNode = null; - switch (_type) { - case FieldType.shortText: - case FieldType.longText: - case FieldType.email: - case FieldType.phone: - case FieldType.number: - renderedField = ( - - ); - break; + switch (_type) { + case FieldType.shortText: + case FieldType.longText: + case FieldType.email: + case FieldType.phone: + case FieldType.number: + renderedField = ( + + ); + break; - case FieldType.url: - renderedField = ; - break; + case FieldType.url: + renderedField = ; + break; - case FieldType.singleSelect: - renderedField = ( - - ); - break; + case FieldType.singleSelect: + renderedField = ( + + ); + break; - case FieldType.multiSelect: - renderedField = ( - - ); - break; + case FieldType.multiSelect: + renderedField = ; + break; - case FieldType.date: - renderedField = ( - - ); - break; + case FieldType.date: + renderedField = ; + break; - case FieldType.dateTime: - renderedField = ( - - ); - break; + case FieldType.dateTime: + renderedField = ( + + ); + break; - case FieldType.checkbox: - renderedField = ; - break; + case FieldType.checkbox: + renderedField = ; + break; - // case FieldType.color: - // renderedField = ; - // break; + case FieldType.color: + renderedField = ; + break; - // case FieldType.slider: - // renderedField = ( - // - // ); - // break; + case FieldType.slider: + renderedField = ; + break; - // case FieldType.richText: - // renderedField = ( - // - // ); - // break; + case FieldType.richText: + renderedField = ; + break; - // case FieldType.image: - // renderedField = ( - // - // ); - // break; + case FieldType.image: + renderedField = ( + + ); + break; - // case FieldType.file: - // renderedField = ( - // - // ); - // break; + case FieldType.file: + renderedField = ( + + ); + break; - // case FieldType.rating: - // renderedField = ( - // - // ); - // break; + case FieldType.rating: + renderedField = ; + break; - case FieldType.percentage: - renderedField = ( - - ); - break; + case FieldType.percentage: + renderedField = ; + break; - // case FieldType.connectTable: - // renderedField = ( - // - // ); - // break; + case FieldType.connectTable: + renderedField = ( + + ); + break; - // case FieldType.subTable: - // renderedField = ( - // - // ); - // break; + case FieldType.subTable: + renderedField = ( + + ); + break; - // case FieldType.action: - // renderedField = ( - // - // ); - // break; + case FieldType.action: + renderedField = ( + + ); + break; - // case FieldType.json: - // renderedField = ( - // - // ); - // break; - // case FieldType.code: - // renderedField = ; - // break; - case undefined: - // default: - return null; + case FieldType.json: + renderedField = ; + break; - default: - break; - } + case FieldType.code: + renderedField = ; + break; - return ( - - {renderedField} - - ); - })} + case undefined: + // default: + return null; - - - - + default: + break; + } + + return ( + + {renderedField} + + ); + })} + + +
+ ); } - -function AutosaveTwo({ - control, -}: { - control: Control; - defaultValues: { [key: string]: any }; -}) { - const watchAll = useWatch({ control }); - console.log("FORM VALUES", watchAll); - return null; -} From 74d76be37ee12b2b341fa0a5c94d9488775a7446 Mon Sep 17 00:00:00 2001 From: Shams mosowi Date: Fri, 21 Aug 2020 21:55:11 +1000 Subject: [PATCH 09/14] discord shield --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5185b0ca..da774559 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Cloud. ![Commit](https://img.shields.io/github/last-commit/AntlerVC/firetable?color=%23ed4747) +[![Discord Shield](https://discordapp.com/api/guilds/746329234720686132/widget.png?style=shield)](https://discord.gg/Vdshr9E) + ### Firetable UI Supports fields such as images, files, single/multi select, in addition to From 8aef9b112c1c7d31c2019a59badbd2e2901eb16d Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Sat, 22 Aug 2020 16:25:34 +1000 Subject: [PATCH 10/14] consolidate all field props to IFieldProps --- .../components/SideDrawer/Form/Autosave.tsx | 2 +- .../SideDrawer/Form/Fields/Action.tsx | 9 +- .../SideDrawer/Form/Fields/Checkbox.tsx | 10 +- .../SideDrawer/Form/Fields/Code.tsx | 10 +- .../SideDrawer/Form/Fields/Color.tsx | 10 +- .../SideDrawer/Form/Fields/ConnectTable.tsx | 11 +- .../SideDrawer/Form/Fields/DatePicker.tsx | 10 +- .../SideDrawer/Form/Fields/DateTimePicker.tsx | 10 +- .../SideDrawer/Form/Fields/FileUploader.tsx | 19 +-- .../SideDrawer/Form/Fields/ImageUploader.tsx | 16 +- .../SideDrawer/Form/Fields/JsonEditor.tsx | 10 +- .../SideDrawer/Form/Fields/MultiSelect.tsx | 21 ++- .../SideDrawer/Form/Fields/Percentage.tsx | 13 +- .../SideDrawer/Form/Fields/Rating.tsx | 11 +- .../SideDrawer/Form/Fields/RichText.tsx | 10 +- .../SideDrawer/Form/Fields/SingleSelect.tsx | 21 ++- .../SideDrawer/Form/Fields/Slider.tsx | 8 +- .../SideDrawer/Form/Fields/SubTable.tsx | 8 +- .../SideDrawer/Form/Fields/Text.tsx | 12 +- .../components/SideDrawer/Form/Fields/Url.tsx | 12 +- www/src/components/SideDrawer/Form/index.tsx | 147 ++++-------------- www/src/components/SideDrawer/Form/utils.ts | 65 ++++++++ www/src/components/SideDrawer/index.tsx | 3 +- 23 files changed, 189 insertions(+), 259 deletions(-) create mode 100644 www/src/components/SideDrawer/Form/utils.ts diff --git a/www/src/components/SideDrawer/Form/Autosave.tsx b/www/src/components/SideDrawer/Form/Autosave.tsx index 99170454..7e32c69f 100644 --- a/www/src/components/SideDrawer/Form/Autosave.tsx +++ b/www/src/components/SideDrawer/Form/Autosave.tsx @@ -7,7 +7,7 @@ import _isUndefined from "lodash/isUndefined"; import _reduce from "lodash/reduce"; import { Control, useWatch } from "react-hook-form"; -import { Values } from "."; +import { Values } from "./utils"; import { useAppContext } from "contexts/appContext"; import { useFiretableContext, firetableUser } from "contexts/firetableContext"; diff --git a/www/src/components/SideDrawer/Form/Fields/Action.tsx b/www/src/components/SideDrawer/Form/Fields/Action.tsx index eb799056..b099ee0b 100644 --- a/www/src/components/SideDrawer/Form/Fields/Action.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Action.tsx @@ -1,5 +1,6 @@ import React, { useContext, useState } from "react"; -import { Control, Controller, useWatch } from "react-hook-form"; +import { Controller, useWatch } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { createStyles, @@ -40,12 +41,8 @@ const useStyles = makeStyles(theme => }) ); -export interface IActionProps { - control: Control; - name: string; - docRef: firebase.firestore.DocumentReference; +export interface IActionProps extends IFieldProps { config: { callableName: string }; - editable?: boolean; } function Action({ control, name, docRef, editable, config }: IActionProps) { diff --git a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx index 60413511..ffee1758 100644 --- a/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Checkbox.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { makeStyles, @@ -38,15 +39,16 @@ const useStyles = makeStyles(theme => }) ); -export interface ICheckboxProps extends MuiSwitchProps { - control: Control; - name: string; +export interface ICheckboxProps + extends IFieldProps, + Omit { label?: React.ReactNode; editable?: boolean; } export default function Checkbox({ control, + docRef, label, name, editable, diff --git a/www/src/components/SideDrawer/Form/Fields/Code.tsx b/www/src/components/SideDrawer/Form/Fields/Code.tsx index c2533dfd..dced6179 100644 --- a/www/src/components/SideDrawer/Form/Fields/Code.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Code.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect, useRef } from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import AceEditor from "react-ace"; import "ace-builds/src-noconflict/mode-javascript"; @@ -101,12 +102,7 @@ function ControlledCode({ onChange, onBlur, value }: IControlledCodeProps) { ); } -export interface ICodeProps { - control: Control; - name: string; -} - -export default function Code({ control, name, ...props }: ICodeProps) { +export default function Code({ control, docRef, name, ...props }: IFieldProps) { return ( }) ); -export interface IColorProps { - control: Control; - name: string; -} - -export default function Color({ control, name }: IColorProps) { +export default function Color({ control, name }: IFieldProps) { const classes = useStyles(); const [showPicker, setShowPicker] = useState(false); diff --git a/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx b/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx index b383b957..39a848fb 100644 --- a/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx +++ b/www/src/components/SideDrawer/Form/Fields/ConnectTable.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Control, Controller } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { useTheme, Grid, Chip } from "@material-ui/core"; @@ -7,13 +8,13 @@ import ConnectTableSelect, { IConnectTableSelectProps, } from "components/ConnectTableSelect"; -export interface IConnectTableProps extends Partial { - control: Control; - name: string; -} +export interface IConnectTableProps + extends IFieldProps, + Partial {} export default function ConnectTable({ control, + docRef, name, editable, ...props diff --git a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx index 2cf36fd0..ac9a8170 100644 --- a/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DatePicker.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { useTheme } from "@material-ui/core"; import { @@ -12,13 +13,12 @@ import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import DateFnsUtils from "@date-io/date-fns"; export interface IDatePickerProps - extends Omit { - control: Control; - name: string; -} + extends IFieldProps, + Omit {} export default function DatePicker({ control, + docRef, name, ...props }: IDatePickerProps) { diff --git a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx index f52ed273..3d8247f4 100644 --- a/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx +++ b/www/src/components/SideDrawer/Form/Fields/DateTimePicker.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { useTheme } from "@material-ui/core"; import { @@ -14,13 +15,12 @@ import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import DateFnsUtils from "@date-io/date-fns"; export interface IDateTimePickerProps - extends Omit { - control: Control; - name: string; -} + extends IFieldProps, + Omit {} export default function DateTimePicker({ control, + docRef, name, ...props }: IDateTimePickerProps) { diff --git a/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx b/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx index fcd43519..f3581734 100644 --- a/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx +++ b/www/src/components/SideDrawer/Form/Fields/FileUploader.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useState } from "react"; import clsx from "clsx"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { useDropzone } from "react-dropzone"; import useUploader, { FileValue } from "hooks/useFiretable/useUploader"; @@ -55,7 +56,7 @@ const useStyles = makeStyles(theme => ); export interface IControlledFileUploaderProps - extends Pick { + extends Pick { onChange: (...event: any[]) => void; onBlur: () => void; value: any; @@ -173,19 +174,7 @@ export function ControlledFileUploader({ ); } -export interface IFileUploaderProps { - control: Control; - name: string; - - editable?: boolean; - docRef?: firebase.firestore.DocumentReference; -} - -export default function FileUploader({ - control, - name, - ...props -}: IFileUploaderProps) { +export default function FileUploader({ control, name, ...props }: IFieldProps) { return ( ); export interface IControlledImageUploaderProps - extends Pick { + extends Pick { onChange: (...event: any[]) => void; onBlur: () => void; value: any; @@ -253,19 +253,11 @@ export function ControlledImageUploader({ ); } -export interface IImageUploaderProps { - control: Control; - name: string; - - docRef?: firebase.firestore.DocumentReference; - editable?: boolean; -} - export default function ImageUploader({ control, name, ...props -}: IImageUploaderProps) { +}: IFieldProps) { return ( { return true; }; -export interface IJsonEditorProps { - control: Control; - name: string; -} - -export default function JsonEditor({ control, name }: IJsonEditorProps) { +export default function JsonEditor({ control, name }: IFieldProps) { const classes = useStyles(); const theme = useTheme(); diff --git a/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx b/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx index 02b5989d..431426c5 100644 --- a/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx +++ b/www/src/components/SideDrawer/Form/Fields/MultiSelect.tsx @@ -1,25 +1,24 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { useTheme, Grid } from "@material-ui/core"; import MultiSelect_, { MultiSelectProps } from "@antlerengineering/multiselect"; import FormattedChip from "components/FormattedChip"; -export type IMultiSelectProps = Omit< - MultiSelectProps, - "multiple" | "value" | "onChange" | "options" -> & { - control: Control; - name: string; - - config?: { options: string[] }; - editable?: boolean; -}; +export type IMultiSelectProps = IFieldProps & + Omit< + MultiSelectProps, + "name" | "multiple" | "value" | "onChange" | "options" + > & { + config?: { options: string[] }; + }; export default function MultiSelect({ control, name, + docRef, editable, config, ...props diff --git a/www/src/components/SideDrawer/Form/Fields/Percentage.tsx b/www/src/components/SideDrawer/Form/Fields/Percentage.tsx index 5c84c2a6..64248978 100644 --- a/www/src/components/SideDrawer/Form/Fields/Percentage.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Percentage.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { makeStyles, createStyles, Typography } from "@material-ui/core"; import { resultColorsScale } from "util/color"; @@ -41,15 +42,7 @@ const useStyles = makeStyles(theme => }) ); -export interface IPercentageProps { - control: Control; - name: string; -} - -/** - * TODO: Fix cell not updating properly when switching between rows - */ -export default function Percentage({ control, name }: IPercentageProps) { +export default function Percentage({ control, name }: IFieldProps) { const classes = useStyles(); return ( diff --git a/www/src/components/SideDrawer/Form/Fields/Rating.tsx b/www/src/components/SideDrawer/Form/Fields/Rating.tsx index f092e952..8e3c73a3 100644 --- a/www/src/components/SideDrawer/Form/Fields/Rating.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Rating.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { makeStyles, createStyles, Grid } from "@material-ui/core"; import { Rating as MuiRating } from "@material-ui/lab"; @@ -25,13 +26,7 @@ const useStyles = makeStyles(theme => }) ); -export interface IRatingProps { - control: Control; - name: string; - editable?: boolean; -} - -export default function Rating({ control, name, editable }: IRatingProps) { +export default function Rating({ control, name, editable }: IFieldProps) { const classes = useStyles(); return ( diff --git a/www/src/components/SideDrawer/Form/Fields/RichText.tsx b/www/src/components/SideDrawer/Form/Fields/RichText.tsx index 696380b4..7c16c1dc 100644 --- a/www/src/components/SideDrawer/Form/Fields/RichText.tsx +++ b/www/src/components/SideDrawer/Form/Fields/RichText.tsx @@ -1,14 +1,10 @@ import React from "react"; -import { Control, Controller } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import _RichText from "components/RichText"; -export interface IRichTextProps { - control: Control; - name: string; -} - -export default function RichText({ control, name }: IRichTextProps) { +export default function RichText({ control, name }: IFieldProps) { return ( , - "multiple" | "value" | "onChange" | "options" -> & { - control: Control; - name: string; - - config?: { options: string[] }; - editable?: boolean; -}; +export type ISingleSelectProps = IFieldProps & + Omit< + MultiSelectProps, + "name" | "multiple" | "value" | "onChange" | "options" + > & { + config?: { options: string[] }; + }; /** * Uses the MultiSelect UI, but writes values as a string, @@ -23,6 +21,7 @@ export type ISingleSelectProps = Omit< */ export default function SingleSelect({ control, + docRef, name, editable, config, diff --git a/www/src/components/SideDrawer/Form/Fields/Slider.tsx b/www/src/components/SideDrawer/Form/Fields/Slider.tsx index 139403db..ae450822 100644 --- a/www/src/components/SideDrawer/Form/Fields/Slider.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Slider.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { makeStyles, @@ -43,9 +44,7 @@ const useStyles = makeStyles(theme => }) ); -export interface ISliderProps extends SliderProps { - control: Control; - name: string; +export interface ISliderProps extends IFieldProps, Omit { units?: string; minLabel?: React.ReactNode; maxLabel?: React.ReactNode; @@ -53,6 +52,7 @@ export interface ISliderProps extends SliderProps { export default function Slider({ control, + docRef, name, units, minLabel, diff --git a/www/src/components/SideDrawer/Form/Fields/SubTable.tsx b/www/src/components/SideDrawer/Form/Fields/SubTable.tsx index 1303db65..d83e6591 100644 --- a/www/src/components/SideDrawer/Form/Fields/SubTable.tsx +++ b/www/src/components/SideDrawer/Form/Fields/SubTable.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Control, useWatch } from "react-hook-form"; +import { Controller, useWatch } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { Link } from "react-router-dom"; import queryString from "query-string"; @@ -31,10 +32,7 @@ const useStyles = makeStyles(theme => }) ); -export interface ISubTableProps { - control: Control; - name: string; - docRef: firebase.firestore.DocumentReference; +export interface ISubTableProps extends IFieldProps { config: { parentLabel?: string[] }; label: string; } diff --git a/www/src/components/SideDrawer/Form/Fields/Text.tsx b/www/src/components/SideDrawer/Form/Fields/Text.tsx index 242a47b6..25fd4ab8 100644 --- a/www/src/components/SideDrawer/Form/Fields/Text.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Text.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { makeStyles, @@ -14,13 +15,6 @@ const useStyles = makeStyles(theme => }) ); -export interface IFieldProps { - control: Control; - name: string; - docRef: firebase.firestore.DocumentReference; - editable?: boolean; -} - export interface ITextProps extends IFieldProps, Omit { @@ -60,7 +54,7 @@ export default function Text({ break; case "number": - variantProps = { inputmode: "numeric", pattern: "[0-9]*" }; + variantProps = { inputMode: "numeric", pattern: "[0-9]*" }; break; case "short": diff --git a/www/src/components/SideDrawer/Form/Fields/Url.tsx b/www/src/components/SideDrawer/Form/Fields/Url.tsx index f7bb23fa..ae7015f5 100644 --- a/www/src/components/SideDrawer/Form/Fields/Url.tsx +++ b/www/src/components/SideDrawer/Form/Fields/Url.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { Controller, Control } from "react-hook-form"; +import { Controller } from "react-hook-form"; +import { IFieldProps } from "../utils"; import { Grid, @@ -9,12 +10,11 @@ import { } from "@material-ui/core"; import LaunchIcon from "@material-ui/icons/Launch"; -export interface IUrlProps extends Omit { - control: Control; - name: string; -} +export interface IUrlProps + extends IFieldProps, + Omit {} -export default function Url({ control, name, ...props }: IUrlProps) { +export default function Url({ control, name, docRef, ...props }: IUrlProps) { return ( import("./Fields/Url" /* webpackChunkName: "SideDrawer-Url" */) ); @@ -80,60 +77,6 @@ const Action = lazy(() => import("./Fields/Action" /* webpackChunkName: "SideDrawer-Action" */) ); -export type Values = { [key: string]: any }; -export type Field = { - type?: FieldType; - name: string; - label?: string; - [key: string]: any; -}; -export type Fields = (Field | ((values: Values) => Field))[]; - -const initializeValue = type => { - switch (type) { - case FieldType.singleSelect: - case FieldType.multiSelect: - case FieldType.image: - case FieldType.file: - return []; - case FieldType.date: - case FieldType.dateTime: - return null; - - case FieldType.checkbox: - return false; - - case FieldType.number: - return 0; - - case FieldType.json: - return {}; - - case FieldType.shortText: - case FieldType.longText: - case FieldType.email: - case FieldType.phone: - case FieldType.url: - case FieldType.code: - case FieldType.richText: - default: - break; - } -}; - -const getInitialValues = (fields: Fields): Values => - fields.reduce((acc, _field) => { - const field = _isFunction(_field) ? _field({}) : _field; - if (!field.name) return acc; - let _type = field.type; - if (field.config && field.config.renderFieldType) { - _type = field.config.renderFieldType; - } - const value = initializeValue(_type); - - return { ...acc, [field.name]: value }; - }, {}); - export interface IFormProps { fields: Fields; values: Values; @@ -188,7 +131,7 @@ export default function Form({ fields, values }: IFormProps) { _type = field.config.renderFieldType; } - let renderedField: React.ReactNode = null; + let fieldComponent: React.ComponentType | null = null; switch (_type) { case FieldType.shortText: @@ -196,111 +139,79 @@ export default function Form({ fields, values }: IFormProps) { case FieldType.email: case FieldType.phone: case FieldType.number: - renderedField = ( - - ); + fieldComponent = Text; break; case FieldType.url: - renderedField = ; + fieldComponent = Url; break; case FieldType.singleSelect: - renderedField = ( - - ); + fieldComponent = SingleSelect; break; case FieldType.multiSelect: - renderedField = ; + fieldComponent = MultiSelect; break; case FieldType.date: - renderedField = ; + fieldComponent = DatePicker; break; case FieldType.dateTime: - renderedField = ( - - ); + fieldComponent = DateTimePicker; break; case FieldType.checkbox: - renderedField = ; + fieldComponent = Checkbox; break; case FieldType.color: - renderedField = ; + fieldComponent = Color; break; case FieldType.slider: - renderedField = ; + fieldComponent = Slider; break; case FieldType.richText: - renderedField = ; + fieldComponent = RichText; break; case FieldType.image: - renderedField = ( - - ); + fieldComponent = ImageUploader; break; case FieldType.file: - renderedField = ( - - ); + fieldComponent = FileUploader; break; case FieldType.rating: - renderedField = ; + fieldComponent = Rating; break; case FieldType.percentage: - renderedField = ; + fieldComponent = Percentage; break; case FieldType.connectTable: - renderedField = ( - - ); + fieldComponent = ConnectTable; break; case FieldType.subTable: - renderedField = ( - - ); + fieldComponent = SubTable; break; case FieldType.action: - renderedField = ( - - ); + fieldComponent = Action; break; case FieldType.json: - renderedField = ; + fieldComponent = JsonEditor; break; case FieldType.code: - renderedField = ; + fieldComponent = Code; break; case undefined: @@ -311,6 +222,12 @@ export default function Form({ fields, values }: IFormProps) { break; } + // Should not reach this state + if (fieldComponent === null) { + console.error("`fieldComponent` is null"); + return null; + } + return ( - {renderedField} + {React.createElement(fieldComponent, { + ...fieldProps, + control, + docRef, + })} ); })} diff --git a/www/src/components/SideDrawer/Form/utils.ts b/www/src/components/SideDrawer/Form/utils.ts new file mode 100644 index 00000000..66ff555c --- /dev/null +++ b/www/src/components/SideDrawer/Form/utils.ts @@ -0,0 +1,65 @@ +import { Control } from "react-hook-form"; +import _isFunction from "lodash/isFunction"; + +import { FieldType } from "constants/fields"; + +export interface IFieldProps { + control: Control; + name: string; + docRef: firebase.firestore.DocumentReference; + editable?: boolean; +} + +export type Values = { [key: string]: any }; +export type Field = { + type?: FieldType; + name: string; + label?: string; + [key: string]: any; +}; +export type Fields = (Field | ((values: Values) => Field))[]; + +export const initializeValue = type => { + switch (type) { + case FieldType.singleSelect: + case FieldType.multiSelect: + case FieldType.image: + case FieldType.file: + return []; + case FieldType.date: + case FieldType.dateTime: + return null; + + case FieldType.checkbox: + return false; + + case FieldType.number: + return 0; + + case FieldType.json: + return {}; + + case FieldType.shortText: + case FieldType.longText: + case FieldType.email: + case FieldType.phone: + case FieldType.url: + case FieldType.code: + case FieldType.richText: + default: + break; + } +}; + +export const getInitialValues = (fields: Fields): Values => + fields.reduce((acc, _field) => { + const field = _isFunction(_field) ? _field({}) : _field; + if (!field.name) return acc; + let _type = field.type; + if (field.config && field.config.renderFieldType) { + _type = field.config.renderFieldType; + } + const value = initializeValue(_type); + + return { ...acc, [field.name]: value }; + }, {}); diff --git a/www/src/components/SideDrawer/index.tsx b/www/src/components/SideDrawer/index.tsx index 4a9a0d67..77fff889 100644 --- a/www/src/components/SideDrawer/index.tsx +++ b/www/src/components/SideDrawer/index.tsx @@ -8,7 +8,8 @@ import ChevronIcon from "@material-ui/icons/KeyboardArrowLeft"; import ChevronUpIcon from "@material-ui/icons/KeyboardArrowUp"; import ChevronDownIcon from "@material-ui/icons/KeyboardArrowDown"; -import Form, { Field } from "./Form"; +import Form from "./Form"; +import { Field } from "./Form/utils"; import ErrorBoundary from "components/ErrorBoundary"; import { useStyles } from "./useStyles"; From 3072a8bfde381d5f9565f6ca410535cb7bdc1558 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Sun, 23 Aug 2020 11:51:04 +1000 Subject: [PATCH 11/14] fix Table crashing if no user hidden fields --- www/src/components/Table/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/src/components/Table/index.tsx b/www/src/components/Table/index.tsx index 4852a82c..b38d8baf 100644 --- a/www/src/components/Table/index.tsx +++ b/www/src/components/Table/index.tsx @@ -58,7 +58,7 @@ export default function Table() { } = useFiretableContext(); const { userDoc } = useAppContext(); const userDocHiddenFields = - userDoc.state.doc?.tables[`${tableState?.tablePath}`]?.hiddenFields ?? []; + userDoc.state.doc?.tables?.[`${tableState?.tablePath}`]?.hiddenFields ?? []; const rowsContainerRef = useRef(null); // Gets more rows when scrolled down. @@ -108,7 +108,7 @@ export default function Table() { ...column, width: column.width ? (column.width > 380 ? 380 : column.width) : 150, })) - .filter((column) => !userDocHiddenFields.includes(column.key)); + .filter(column => !userDocHiddenFields.includes(column.key)); columns.push({ isNew: true, key: "new", @@ -167,7 +167,7 @@ export default function Table() { rowGetter={rowGetter} rowsCount={rows.length} rowKey={"id" as "id"} - onGridRowsUpdated={(event) => { + onGridRowsUpdated={event => { const { action, cellKey, updated } = event; if (action === "CELL_UPDATE" && updated !== null) updateCell!(rows[event.toRow].ref, cellKey as string, updated); @@ -199,7 +199,7 @@ export default function Table() { enableCellSelect onScroll={handleScroll} ref={dataGridRef} - RowsContainer={(props) => ( + RowsContainer={props => ( <>
Date: Sun, 23 Aug 2020 11:53:14 +1000 Subject: [PATCH 12/14] upgrade react-hook-form --- www/package.json | 2 +- www/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/www/package.json b/www/package.json index 3f9885c9..c0d30f38 100644 --- a/www/package.json +++ b/www/package.json @@ -52,7 +52,7 @@ "react-div-100vh": "^0.3.8", "react-dom": "^16.9.0", "react-dropzone": "^10.1.8", - "react-hook-form": "^6.0.6", + "react-hook-form": "^6.5.0", "react-image": "^4.0.3", "react-json-view": "^1.19.1", "react-router-dom": "^5.0.1", diff --git a/www/yarn.lock b/www/yarn.lock index 2025ed65..81660498 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -11962,10 +11962,10 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-hook-form@^6.0.6: - version "6.0.6" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.0.6.tgz#72ac1668aeaddfd642bcfb324cebe1ba237fb13e" - integrity sha512-qxWhV++1V7SKKlr2hHFsessGwATCdexgVsByxOHltDyO9F0VWB1WN4ZvxnKuHTVGwjj6CLZo0mL+Hgy0QH1sAw== +react-hook-form@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.5.0.tgz#9442797f9f05644829125772b2656d3da19f732e" + integrity sha512-DRziWoDvmwNIwBk6tkBN/fPeCgbtYHr1tIlVVd0ihmQg9Fv+gjOs0BU0D3o7HrKDeKwDA8pnp4tuEwxe8qg9TA== react-image@^4.0.3: version "4.0.3" From 40122f054ae1d4cd496ac62404277fdcd53ebd9f Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Sun, 23 Aug 2020 11:54:39 +1000 Subject: [PATCH 13/14] move all @types packages to devDependencies --- www/package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/www/package.json b/www/package.json index c0d30f38..dcc8c9d7 100644 --- a/www/package.json +++ b/www/package.json @@ -13,19 +13,6 @@ "@mdi/js": "^4.9.95", "@monaco-editor/react": "^3.5.5", "@tinymce/tinymce-react": "^3.4.0", - "@types/backbone": "^1.4.1", - "@types/cash": "^0.0.3", - "@types/chroma-js": "^2.0.0", - "@types/dompurify": "^2.0.1", - "@types/file-saver": "^2.0.1", - "@types/lodash": "^4.14.138", - "@types/node": "12.7.4", - "@types/ramda": "^0.26.21", - "@types/react": "^16.9.2", - "@types/react-color": "^3.0.1", - "@types/react-div-100vh": "^0.3.0", - "@types/react-dom": "16.9.0", - "@types/react-router-dom": "^4.3.5", "ace-builds": "^1.4.11", "algoliasearch": "^4.1.0", "chroma-js": "^2.1.0", @@ -96,6 +83,19 @@ }, "devDependencies": { "@material-ui/codemod": "^4.3.0", + "@types/backbone": "^1.4.1", + "@types/cash": "^0.0.3", + "@types/chroma-js": "^2.0.0", + "@types/dompurify": "^2.0.1", + "@types/file-saver": "^2.0.1", + "@types/lodash": "^4.14.138", + "@types/node": "12.7.4", + "@types/ramda": "^0.26.21", + "@types/react": "^16.9.2", + "@types/react-color": "^3.0.1", + "@types/react-div-100vh": "^0.3.0", + "@types/react-dom": "16.9.0", + "@types/react-router-dom": "^4.3.5", "firebase-tools": "^7.16.1", "husky": "^3.0.5", "prettier": "^1.18.2", From bfa6333007bf711a18b5d1973675a5c7c4e69ebd Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Sun, 23 Aug 2020 12:02:46 +1000 Subject: [PATCH 14/14] remove formik, other unused dependencies --- www/package.json | 7 - .../SideDrawer/Form/ErrorMessage.tsx | 24 -- www/src/hooks/useFiretable/useUploader.ts | 2 +- www/yarn.lock | 220 ++---------------- 4 files changed, 17 insertions(+), 236 deletions(-) delete mode 100644 www/src/components/SideDrawer/Form/ErrorMessage.tsx diff --git a/www/package.json b/www/package.json index dcc8c9d7..caef8d6b 100644 --- a/www/package.json +++ b/www/package.json @@ -21,9 +21,6 @@ "dompurify": "^2.0.8", "file-saver": "^2.0.2", "firebase": "^6.6.0", - "formik": "^2.1.4", - "formik-material-ui": "^2.0.0-beta.1", - "formik-material-ui-pickers": "^0.0.8", "grapesjs-react": "^2.0.2", "hotkeys-js": "^3.7.2", "json-format": "^1.0.1", @@ -82,14 +79,10 @@ ] }, "devDependencies": { - "@material-ui/codemod": "^4.3.0", - "@types/backbone": "^1.4.1", - "@types/cash": "^0.0.3", "@types/chroma-js": "^2.0.0", "@types/dompurify": "^2.0.1", "@types/file-saver": "^2.0.1", "@types/lodash": "^4.14.138", - "@types/node": "12.7.4", "@types/ramda": "^0.26.21", "@types/react": "^16.9.2", "@types/react-color": "^3.0.1", diff --git a/www/src/components/SideDrawer/Form/ErrorMessage.tsx b/www/src/components/SideDrawer/Form/ErrorMessage.tsx deleted file mode 100644 index 24605c1d..00000000 --- a/www/src/components/SideDrawer/Form/ErrorMessage.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; -import { ErrorMessage as FormikErrorMessage, ErrorMessageProps } from "formik"; - -import { makeStyles, createStyles, FormHelperText } from "@material-ui/core"; - -const useStyles = makeStyles(theme => - createStyles({ - root: { marginTop: theme.spacing(0.5) }, - }) -); - -export default function ErrorMessage(props: ErrorMessageProps) { - const classes = useStyles(); - - return ( - - {msg => ( - - {msg} - - )} - - ); -} diff --git a/www/src/hooks/useFiretable/useUploader.ts b/www/src/hooks/useFiretable/useUploader.ts index 9f03a410..f4aac9d4 100644 --- a/www/src/hooks/useFiretable/useUploader.ts +++ b/www/src/hooks/useFiretable/useUploader.ts @@ -112,7 +112,7 @@ const useUploader = () => { if (docRef && docRef.update) docRef.update({ [fieldName]: newValue }); // Also call callback if it exists - // IMPORTANT: Formik may not update its local values after this + // IMPORTANT: SideDrawer form may not update its local values after this // function updates the doc, so you MUST update it manually // using this callback if (onComplete) onComplete(newValue); diff --git a/www/yarn.lock b/www/yarn.lock index 81660498..b084f85d 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -157,7 +157,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.4.5": +"@babel/core@^7.1.0", "@babel/core@^7.4.5": version "7.8.7" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.7.tgz#b69017d221ccdeb203145ae9da269d72cf102f3b" integrity sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA== @@ -402,7 +402,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.4.3", "@babel/parser@^7.8.4", "@babel/parser@^7.8.6", "@babel/parser@^7.8.7": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.8.4", "@babel/parser@^7.8.6", "@babel/parser@^7.8.7": version "7.8.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.8.tgz#4c3b7ce36db37e0629be1f0d50a571d2f86f6cd4" integrity sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA== @@ -416,7 +416,7 @@ "@babel/helper-remap-async-to-generator" "^7.8.3" "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@7.8.3", "@babel/plugin-proposal-class-properties@^7.1.0": +"@babel/plugin-proposal-class-properties@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== @@ -465,7 +465,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-numeric-separator" "^7.8.3" -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.8.3": +"@babel/plugin-proposal-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== @@ -670,7 +670,7 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-flow-strip-types@7.8.3", "@babel/plugin-transform-flow-strip-types@^7.8.3": +"@babel/plugin-transform-flow-strip-types@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.8.3.tgz#da705a655466b2a9b36046b57bf0cbcd53551bd4" integrity sha512-g/6WTWG/xbdd2exBBzMfygjX/zw4eyNC4X8pRaq7aRHRoDUCzAIu3kGYIXviOv8BjCuWm8vDBwjHcjiRNgXrPA== @@ -963,7 +963,7 @@ levenary "^1.1.1" semver "^5.5.0" -"@babel/preset-env@^7.1.6", "@babel/preset-env@^7.4.5": +"@babel/preset-env@^7.4.5": version "7.8.7" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.8.7.tgz#1fc7d89c7f75d2d70c2b6768de6c2e049b3cb9db" integrity sha512-BYftCVOdAYJk5ASsznKAUl53EMhfBbr8CJ1X+AJLfGPscQkwJFiaV/Wn9DPH/7fzm2v6iRYJKYHSqyynTGw0nw== @@ -1026,14 +1026,6 @@ levenary "^1.1.1" semver "^5.5.0" -"@babel/preset-flow@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.8.3.tgz#52af74c6a4e80d889bd9436e8e278d0fecac6e18" - integrity sha512-iCXFk+T4demnq+dNLLvlGOgvYF6sPZ/hS1EmswugOqh1Ysp2vuiqJzpgsnp5rW8+6dLJT/0CXDzye28ZH6BAfQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-transform-flow-strip-types" "^7.8.3" - "@babel/preset-react@7.8.3", "@babel/preset-react@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.8.3.tgz#23dc63f1b5b0751283e04252e78cf1d6589273d2" @@ -1045,7 +1037,7 @@ "@babel/plugin-transform-react-jsx-self" "^7.8.3" "@babel/plugin-transform-react-jsx-source" "^7.8.3" -"@babel/preset-typescript@7.8.3", "@babel/preset-typescript@^7.1.0": +"@babel/preset-typescript@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.8.3.tgz#90af8690121beecd9a75d0cc26c6be39d1595d13" integrity sha512-qee5LgPGui9zQ0jR1TeU5/fP9L+ovoArklEqY12ek8P/wV5ZeM/VYSQYwICeoT6FfpJTekG9Ilay5PhwsOpMHA== @@ -1053,17 +1045,6 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-typescript" "^7.8.3" -"@babel/register@^7.0.0": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.8.6.tgz#a1066aa6168a73a70c35ef28cc5865ccc087ea69" - integrity sha512-7IDO93fuRsbyml7bAafBQb3RcBGlCpU4hh5wADA2LJEEcYk92WkwFZ0pHyIi2fb5Auoz1714abETdZKCOxN0CQ== - dependencies: - find-cache-dir "^2.0.0" - lodash "^4.17.13" - make-dir "^2.1.0" - pirates "^4.0.0" - source-map-support "^0.5.16" - "@babel/runtime@7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" @@ -1101,7 +1082,7 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.6.2", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== @@ -1574,15 +1555,6 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@material-ui/codemod@^4.3.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@material-ui/codemod/-/codemod-4.5.0.tgz#e258a4865a7d68506579e046a6170fd742ffdf4f" - integrity sha512-qgx6I1T+kTL6TkbtTu+Bn4NIi5AgQ8SR8R/bXpivKPkrSADCsoanfJrS3atyCi8Sykl0DZiLdXxQOAcjP1rh4w== - dependencies: - "@babel/core" "^7.4.5" - "@babel/traverse" "^7.6.2" - jscodeshift-add-imports "^1.0.1" - "@material-ui/core@^4.11.0": version "4.11.0" resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" @@ -1952,14 +1924,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/backbone@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@types/backbone/-/backbone-1.4.1.tgz#aa03f9f69994bd96646c50cfc70b5f30d38aafaa" - integrity sha512-KYfGuQy4d2vvYXbn0uHFZ6brFLndatTMomxBlljpbWf4kFpA3BG/6LA3ec+J9iredrX6eAVI7sm9SVAvwiIM6g== - dependencies: - "@types/jquery" "*" - "@types/underscore" "*" - "@types/bytebuffer@^5.0.40": version "5.0.40" resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.40.tgz#d6faac40dcfb09cd856cdc4c01d3690ba536d3ee" @@ -1968,11 +1932,6 @@ "@types/long" "*" "@types/node" "*" -"@types/cash@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/cash/-/cash-0.0.3.tgz#770d6382c605bb4f8572f17cea6f40cec5832496" - integrity sha512-gS24kdFuVwfo5h7IlStnXyBSIH4e9aFIhNHb4w+o5DwbYDeQJv+i9heh7u7nSvqnOP3v34tQMTe7VoJp2US08w== - "@types/chroma-js@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/chroma-js/-/chroma-js-2.0.0.tgz#b0fc98c8625d963f14e8138e0a7961103303ab22" @@ -2053,13 +2012,6 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jquery@*": - version "3.3.33" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.33.tgz#61d9cbd4004ffcdf6cf7e34720a87a5625a7d8e9" - integrity sha512-U6IdXYGkfUI42SR79vB2Spj+h1Ly3J3UZjpd8mi943lh126TK7CB+HZOxGh2nM3IySor7wqVQdemD/xtydsBKA== - dependencies: - "@types/sizzle" "*" - "@types/js-yaml@^3.12.2": version "3.12.3" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.3.tgz#abf383c5b639d0aa8b8c4a420d6a85f703357d6c" @@ -2090,11 +2042,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== -"@types/node@12.7.4": - version "12.7.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" - integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== - "@types/node@^10.1.0": version "10.17.17" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" @@ -2188,11 +2135,6 @@ "@types/prop-types" "*" csstype "^2.2.0" -"@types/sizzle@*": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" - integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -2210,11 +2152,6 @@ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-1.0.4.tgz#922d092c84a776a59acb0bd6785fd82b59b9bad5" integrity sha512-6jtHrHpmiXOXoJ31Cg9R+iEVwuEKPf0XHwFUI93eEPXx492/J2JHyafkleKE2EYzZprayk9FSjTyK1GDqcwDng== -"@types/underscore@*": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.9.4.tgz#22d1a3e6b494608e430221ec085fa0b7ccee7f33" - integrity sha512-CjHWEMECc2/UxOZh0kpiz3lEyX2Px3rQS9HzD20lxMvx571ivOBQKeLnqEjxUY0BMgp6WJWo/pQLRBwMW5v4WQ== - "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -2899,11 +2836,6 @@ ast-types-flow@0.0.7, ast-types-flow@^0.0.7: resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= -ast-types@0.11.7: - version "0.11.7" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.7.tgz#f318bf44e339db6a320be0009ded64ec1471f46c" - integrity sha512-2mP3TwtkY/aTv5X3ZsMpNAbOnyoC/aMJwJSoaELPkHId0nSQgFcnU4dRW3isxiz7+zBexk0ym3WNVjMiQBnJSw== - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -3001,11 +2933,6 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^7.0.0-bridge.0: - version "7.0.0-bridge.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" - integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== - babel-eslint@10.0.3: version "10.0.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" @@ -4061,11 +3988,6 @@ colors@1.0.3, colors@1.0.x: resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= -colors@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - colour@~0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" @@ -4831,11 +4753,6 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deepmerge@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" - integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== - default-gateway@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" @@ -6182,11 +6099,6 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== -flow-parser@0.*: - version "0.121.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f" - integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg== - flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -6267,30 +6179,6 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -formik-material-ui-pickers@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/formik-material-ui-pickers/-/formik-material-ui-pickers-0.0.8.tgz#203e602b71eff4a1f28ef40c4c7989a63fc5ff07" - integrity sha512-4/5Fcxe+Bi/6g0nA+ZE1U/D+W8s8yEiictA5w/vLPDab9P9uoktXFjEy2TfKQhfeUP4krYIt6U2tNNZuhRwoIg== - -formik-material-ui@^2.0.0-beta.1: - version "2.0.0-beta.1" - resolved "https://registry.yarnpkg.com/formik-material-ui/-/formik-material-ui-2.0.0-beta.1.tgz#adf6321c97f8617aff00ed717daba8b66d436fd7" - integrity sha512-Zt2pHQzaU2f9reXLS0E85ddeU8aFFtVJV42IPfVdC3lLY+kf+PUdzSiyCHFbRFVniG7SGisEoOwOZFMpkA85Qw== - -formik@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/formik/-/formik-2.1.4.tgz#8deef07ec845ea98f75e03da4aad7aab4ac46570" - integrity sha512-oKz8S+yQBzuQVSEoxkqqJrKQS5XJASWGVn6mrs+oTWrBoHgByVwwI1qHiVc9GKDpZBU9vAxXYAKz2BvujlwunA== - dependencies: - deepmerge "^2.1.1" - hoist-non-react-statics "^3.3.0" - lodash "^4.17.14" - lodash-es "^4.17.14" - react-fast-compare "^2.0.1" - scheduler "^0.18.0" - tiny-warning "^1.0.2" - tslib "^1.10.0" - forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -7059,7 +6947,7 @@ hoist-non-react-statics@^2.1.0: resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -8430,45 +8318,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jscodeshift-add-imports@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/jscodeshift-add-imports/-/jscodeshift-add-imports-1.0.3.tgz#1e27ee28e284b3be3db22853738b5bcb04a6bf79" - integrity sha512-h7zZ6HS+k2hlXYtx3sFoMAOZq0yGnDfCAHudZqw0KnF1qV30wcXwN9bO5v8zRLUhoUibli8xx3wbT2QDGc+ung== - dependencies: - "@babel/traverse" "^7.4.5" - jscodeshift-find-imports "^1.0.2" - -jscodeshift-find-imports@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/jscodeshift-find-imports/-/jscodeshift-find-imports-1.1.1.tgz#2d4c0a96f1068dded688a8f59fa9470795fd8944" - integrity sha512-vjhUZbVRajqE5F1lonyZ0vy5ux/P+eHWTgdhAawDtsSvxPfwQAsygdBjvhEZZao0zF0gBJ3MPOZlXYEmT9UypQ== - dependencies: - jscodeshift "^0.6.4" - -jscodeshift@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.6.4.tgz#e19ab86214edac86a75c4557fc88b3937d558a8e" - integrity sha512-+NF/tlNbc2WEhXUuc4WEJLsJumF84tnaMUZW2hyJw3jThKKRvsPX4sPJVgO1lPE28z0gNL+gwniLG9d8mYvQCQ== - dependencies: - "@babel/core" "^7.1.6" - "@babel/parser" "^7.1.6" - "@babel/plugin-proposal-class-properties" "^7.1.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/preset-env" "^7.1.6" - "@babel/preset-flow" "^7.0.0" - "@babel/preset-typescript" "^7.1.0" - "@babel/register" "^7.0.0" - babel-core "^7.0.0-bridge.0" - colors "^1.1.2" - flow-parser "0.*" - graceful-fs "^4.1.11" - micromatch "^3.1.10" - neo-async "^2.5.0" - node-dir "^0.1.17" - recast "^0.16.1" - temp "^0.8.1" - write-file-atomic "^2.3.0" - jsdom@^11.5.1: version "11.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" @@ -9027,7 +8876,7 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash-es@^4.17.14, lodash-es@^4.17.15, lodash-es@^4.2.1: +lodash-es@^4.17.15, lodash-es@^4.2.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== @@ -9615,7 +9464,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -9884,13 +9733,6 @@ no-case@^3.0.3: lower-case "^2.0.1" tslib "^1.10.0" -node-dir@^0.1.17: - version "0.1.17" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU= - dependencies: - minimatch "^3.0.2" - node-emoji@^1.4.1: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -10706,7 +10548,7 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pirates@^4.0.0, pirates@^4.0.1: +pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== @@ -11516,7 +11358,7 @@ pretty-quick@^2.0.1: mri "^1.1.4" multimatch "^4.0.0" -private@^0.1.8, private@~0.1.5: +private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -11957,11 +11799,6 @@ react-error-overlay@^6.0.6: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.6.tgz#ac4d9dc4c1b5c536c2c312bf66aa2b09bfa384e2" integrity sha512-Yzpno3enVzSrSCnnljmr4b/2KUQSMZaPuqmS26t9k4nW7uwJk6STWmH9heNjPuvqUTO3jOSPkHoKgO4+Dw7uIw== -react-fast-compare@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" - integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== - react-hook-form@^6.5.0: version "6.5.0" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.5.0.tgz#9442797f9f05644829125772b2656d3da19f732e" @@ -12236,16 +12073,6 @@ realpath-native@^1.1.0: dependencies: util.promisify "^1.0.0" -recast@^0.16.1: - version "0.16.2" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.16.2.tgz#3796ebad5fe49ed85473b479cd6df554ad725dc2" - integrity sha512-O/7qXi51DPjRVdbrpNzoBQH5dnAPQNbfoOFyRiUwreTMJfIHYOEBzwuH+c0+/BTSJ3CQyKs6ILSWXhESH6Op3A== - dependencies: - ast-types "0.11.7" - esprima "~4.0.0" - private "~0.1.5" - source-map "~0.6.1" - recursive-readdir@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" @@ -12606,7 +12433,7 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2. dependencies: glob "^7.1.3" -rimraf@2.6.3, rimraf@~2.6.2: +rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -12742,14 +12569,6 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" -scheduler@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" - integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler@^0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d" @@ -13079,7 +12898,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12: +source-map-support@^0.5.6, source-map-support@~0.5.12: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== @@ -13614,13 +13433,6 @@ tcp-port-used@^1.0.1: debug "4.1.0" is2 "2.0.1" -temp@^0.8.1: - version "0.8.4" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.4.tgz#8c97a33a4770072e0a05f919396c7665a7dd59f2" - integrity sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg== - dependencies: - rimraf "~2.6.2" - term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -14768,7 +14580,7 @@ write-file-atomic@2.4.1: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: +write-file-atomic@^2.0.0: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==