From 2d6a20a7c7919a663d4e2e5762d786477dc118be Mon Sep 17 00:00:00 2001 From: Nikhil Nandagopal Date: Fri, 1 Nov 2019 17:23:24 +0530 Subject: [PATCH] added uppy filepicker --- app/client/package.json | 7 + .../src/assets/icons/widget/file-upload.svg | 3 - .../{file upload.svg => filepicker.svg} | 0 .../src/assets/icons/widget/rich text.svg | 8 - .../appsmith/FilePickerComponent.tsx | 51 ++++ .../blueprint/DropdownComponent.tsx | 1 - .../constants/PropertyControlConstants.tsx | 1 + app/client/src/constants/WidgetConstants.tsx | 1 + app/client/src/icons/WidgetIcons.tsx | 6 + .../PropertyPaneConfigResponse.tsx | 70 ++++++ .../mockResponses/WidgetConfigResponse.tsx | 5 + .../mockResponses/WidgetSidebarResponse.tsx | 6 + .../src/propertyControls/DropDownControl.tsx | 8 + .../propertyControls/MultiSelectControl.tsx | 100 ++++++++ .../src/propertyControls/StyledControls.tsx | 11 +- .../propertyPaneConfigReducer.tsx | 4 +- .../entityReducers/widgetConfigReducer.tsx | 2 + .../src/utils/PropertyControlRegistry.tsx | 8 + app/client/src/utils/WidgetRegistry.tsx | 8 + app/client/src/widgets/ButtonWidget.tsx | 2 +- app/client/src/widgets/FilepickerWidget.tsx | 88 +++++++ app/client/yarn.lock | 220 +++++++++++++++++- 22 files changed, 591 insertions(+), 19 deletions(-) delete mode 100644 app/client/src/assets/icons/widget/file-upload.svg rename app/client/src/assets/icons/widget/{file upload.svg => filepicker.svg} (100%) delete mode 100644 app/client/src/assets/icons/widget/rich text.svg create mode 100644 app/client/src/components/appsmith/FilePickerComponent.tsx create mode 100644 app/client/src/propertyControls/MultiSelectControl.tsx create mode 100644 app/client/src/widgets/FilepickerWidget.tsx diff --git a/app/client/package.json b/app/client/package.json index b14fe3cab6..6e211dec35 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -24,6 +24,13 @@ "@types/react-redux": "^7.0.1", "@types/react-router-dom": "^4.3.5", "@types/styled-components": "^4.1.8", + "@uppy/core": "^1.5.1", + "@uppy/file-input": "^1.3.1", + "@uppy/google-drive": "^1.3.2", + "@uppy/onedrive": "^0.1.1", + "@uppy/react": "^1.3.2", + "@uppy/url": "^1.3.2", + "@uppy/webcam": "^1.3.1", "axios": "^0.18.0", "eslint": "^6.4.0", "flow-bin": "^0.91.0", diff --git a/app/client/src/assets/icons/widget/file-upload.svg b/app/client/src/assets/icons/widget/file-upload.svg deleted file mode 100644 index 3339c43747..0000000000 --- a/app/client/src/assets/icons/widget/file-upload.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/client/src/assets/icons/widget/file upload.svg b/app/client/src/assets/icons/widget/filepicker.svg similarity index 100% rename from app/client/src/assets/icons/widget/file upload.svg rename to app/client/src/assets/icons/widget/filepicker.svg diff --git a/app/client/src/assets/icons/widget/rich text.svg b/app/client/src/assets/icons/widget/rich text.svg deleted file mode 100644 index 99149884a5..0000000000 --- a/app/client/src/assets/icons/widget/rich text.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/app/client/src/components/appsmith/FilePickerComponent.tsx b/app/client/src/components/appsmith/FilePickerComponent.tsx new file mode 100644 index 0000000000..e8d9a9d708 --- /dev/null +++ b/app/client/src/components/appsmith/FilePickerComponent.tsx @@ -0,0 +1,51 @@ +import * as React from "react"; +import { ComponentProps } from "../appsmith/BaseComponent"; +import "@uppy/core/dist/style.css"; +import "@uppy/dashboard/dist/style.css"; +import "@uppy/webcam/dist/style.css"; +import { Container } from "./ContainerComponent"; +import { BaseButton } from "../blueprint/ButtonComponent"; +import { DashboardModal } from "@uppy/react"; + +class FilePickerComponent extends React.Component< + FilePickerComponentProps, + FilePickerComponentState +> { + constructor(props: FilePickerComponentProps) { + super(props); + this.state = { + isOpen: false, + }; + } + + openModal = () => { + this.setState({ isOpen: true }); + }; + + render() { + return ( + + + this.setState({ isOpen: false })} + uppy={this.props.uppy} + /> + + ); + } +} + +export interface FilePickerComponentState { + isOpen: boolean; +} + +export interface FilePickerComponentProps extends ComponentProps { + label: string; + uppy: any; +} + +export default FilePickerComponent; diff --git a/app/client/src/components/blueprint/DropdownComponent.tsx b/app/client/src/components/blueprint/DropdownComponent.tsx index 2542c7e78f..2b2f7b50b9 100644 --- a/app/client/src/components/blueprint/DropdownComponent.tsx +++ b/app/client/src/components/blueprint/DropdownComponent.tsx @@ -86,7 +86,6 @@ class DropDownComponent extends React.Component { return null; } const isSelected: boolean = this.isOptionSelected(option); - console.log("is selected " + isSelected); return ( ), + FILE_PICKER_WIDGET: (props: IconProps) => ( + + + + ), }; export type WidgetIcon = (typeof WidgetIcons)[keyof typeof WidgetIcons]; diff --git a/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx b/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx index 62bd4e65ba..5acfd8e8e5 100644 --- a/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx +++ b/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx @@ -524,6 +524,76 @@ const PropertyPaneConfigResponse: PropertyPaneConfigState = { ], }, ], + FILE_PICKER_WIDGET: [ + { + sectionName: "General", + id: "18", + children: [ + { + id: "18.1", + propertyName: "label", + label: "Label", + inputType: "INTEGER", + placeholderText: "Enter Label", + controlType: "INPUT_TEXT", + }, + { + id: "18.2", + propertyName: "maxNumFiles", + label: "No. of files", + placeholderText: "Enter No. of files", + controlType: "INPUT_TEXT", + }, + { + id: "18.3", + propertyName: "allowedFileTypes", + label: "Allowed File Types", + placeholderText: "Enter No. of files", + options: [ + { + label: "Any File", + value: "*", + }, + { + label: "Images", + value: "image/*", + }, + { + label: "Videos", + value: "video/*", + }, + { + label: "Audio", + value: "audio/*", + }, + { + label: "Text", + value: "text/*", + }, + { + label: "JPEG", + value: "image/jpeg", + }, + { + label: "PNG", + value: "*.png", + }, + { + label: "GIF", + value: "*.gif", + }, + ], + controlType: "MULTI_SELECT", + }, + { + id: "18.4", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], + }, + ], }, configVersion: 1, }; diff --git a/app/client/src/mockResponses/WidgetConfigResponse.tsx b/app/client/src/mockResponses/WidgetConfigResponse.tsx index 86bc27203d..93f81bdcec 100644 --- a/app/client/src/mockResponses/WidgetConfigResponse.tsx +++ b/app/client/src/mockResponses/WidgetConfigResponse.tsx @@ -105,6 +105,11 @@ const WidgetConfigResponse: WidgetConfigReducerState = { message: "", widgetName: "Alert", }, + FILE_PICKER_WIDGET: { + rows: 3, + columns: 3, + widgetName: "FilePicker", + }, }, configVersion: 1, }; diff --git a/app/client/src/mockResponses/WidgetSidebarResponse.tsx b/app/client/src/mockResponses/WidgetSidebarResponse.tsx index 36af23f569..0071497082 100644 --- a/app/client/src/mockResponses/WidgetSidebarResponse.tsx +++ b/app/client/src/mockResponses/WidgetSidebarResponse.tsx @@ -68,6 +68,12 @@ const WidgetSidebarResponse: { widgetCardName: "DatePicker", key: generateReactKey(), }, + { + type: "FILE_PICKER_WIDGET", + icon: "icon-filepicker", + widgetCardName: "FilePicker", + key: generateReactKey(), + }, { type: "BUTTON_WIDGET", icon: "icon-button", diff --git a/app/client/src/propertyControls/DropDownControl.tsx b/app/client/src/propertyControls/DropDownControl.tsx index 278686a29b..8198bf4254 100644 --- a/app/client/src/propertyControls/DropDownControl.tsx +++ b/app/client/src/propertyControls/DropDownControl.tsx @@ -38,8 +38,10 @@ class DropDownControl extends BaseControl { if (!itemProps.modifiers.matchesPredicate) { return null; } + const isSelected: boolean = this.isOptionSelected(option); return ( { ); }; + isOptionSelected = (selectedOption: DropdownOption) => { + return selectedOption.value === this.props.propertyValue; + }; + getControlType(): ControlType { return "DROP_DOWN"; } @@ -55,6 +61,8 @@ class DropDownControl extends BaseControl { export interface DropDownControlProps extends ControlProps { options: DropdownOption[]; + placeholderText: string; + propertyValue: string; } export default DropDownControl; diff --git a/app/client/src/propertyControls/MultiSelectControl.tsx b/app/client/src/propertyControls/MultiSelectControl.tsx new file mode 100644 index 0000000000..7ddb66329d --- /dev/null +++ b/app/client/src/propertyControls/MultiSelectControl.tsx @@ -0,0 +1,100 @@ +import React from "react"; +import BaseControl, { ControlProps } from "./BaseControl"; +import { ControlType } from "../constants/PropertyControlConstants"; +import { MenuItem } from "@blueprintjs/core"; +import { IItemRendererProps } from "@blueprintjs/select"; +import { ControlWrapper, StyledMultiSelectDropDown } from "./StyledControls"; +import DropdownOption from "../common/DropdownOption"; +import _ from "lodash"; + +class MultiSelectControl extends BaseControl { + render() { + const selectedItems: DropdownOption[] = []; + _.map(this.props.propertyValue, value => { + const option = _.find(this.props.options, option => { + return option.value === value; + }); + if (option) selectedItems.push(option); + return option; + }); + return ( + + + { + } + /> + } + + ); + } + + onItemRemoved = (_tag: string, index: number) => { + const optionValues = this.props.propertyValue.filter( + (value: string, valueIndex: number) => { + return valueIndex !== index; + }, + ); + this.updateProperty(this.props.propertyName, optionValues); + }; + + renderTag = (option: DropdownOption) => { + return option.label; + }; + + onItemSelect = (option: DropdownOption): void => { + if (this.isOptionSelected(option)) { + const optionValues = this.props.propertyValue.filter((value: string) => { + return value !== option.value; + }); + this.updateProperty(this.props.propertyName, optionValues); + } else { + const optionValues = this.props.propertyValue || []; + optionValues.push(option.value); + this.updateProperty(this.props.propertyName, optionValues); + } + }; + + renderItem = (option: DropdownOption, itemProps: IItemRendererProps) => { + if (!itemProps.modifiers.matchesPredicate) { + return null; + } + const isSelected: boolean = this.isOptionSelected(option); + return ( + + ); + }; + + isOptionSelected = (selectedOption: DropdownOption) => { + return ( + _.findIndex(this.props.propertyValue, value => { + return value === selectedOption.value; + }) !== -1 + ); + }; + + getControlType(): ControlType { + return "MULTI_SELECT"; + } +} + +export interface MultiSelectControlProps extends ControlProps { + options: DropdownOption[]; + placeholderText: string; + propertyValue: string[]; +} + +export default MultiSelectControl; diff --git a/app/client/src/propertyControls/StyledControls.tsx b/app/client/src/propertyControls/StyledControls.tsx index c3eeebcdb2..efda40de93 100644 --- a/app/client/src/propertyControls/StyledControls.tsx +++ b/app/client/src/propertyControls/StyledControls.tsx @@ -1,5 +1,5 @@ import styled from "styled-components"; -import { Select } from "@blueprintjs/select"; +import { Select, MultiSelect } from "@blueprintjs/select"; import { Switch, InputGroup } from "@blueprintjs/core"; import { ContainerOrientation } from "../constants/WidgetConstants"; import DropdownOption from "../common/DropdownOption"; @@ -35,6 +35,15 @@ export const StyledDropDown = styled(DropDown)` } `; +const MultiSelectDropDown = MultiSelect.ofType(); +export const StyledMultiSelectDropDown = styled(MultiSelectDropDown)` + &&& button { + background: ${props => props.theme.colors.paneInputBG}; + color: ${props => props.theme.colors.textOnDarkBG}; + box-shadow: none; + } +`; + export const StyledSwitch = styled(Switch)` &&&&& input:checked ~ span { background: ${props => props.theme.colors.primary}; diff --git a/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx b/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx index 6b2c800c5c..834fcf0eef 100644 --- a/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx +++ b/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx @@ -36,6 +36,7 @@ export interface PropertyConfig { TABLE_WIDGET: PropertySection[]; DROP_DOWN_WIDGET: PropertySection[]; CHECKBOX_WIDGET: PropertySection[]; + FILE_PICKER_WIDGET: PropertySection[]; RADIO_GROUP_WIDGET: PropertySection[]; } @@ -43,16 +44,17 @@ export interface PropertyPaneConfigState { config: PropertyConfig; configVersion: number; } + /** * TODO: Remove hardcoding of config response */ - const propertyPaneConfigReducer = createReducer(initialState, { [ReduxActionTypes.FETCH_PROPERTY_PANE_CONFIGS_SUCCESS]: ( state: PropertyPaneConfigState, action: ReduxAction, ) => { return { ...PropertyPaneConfigResponse }; + return { ...action.payload }; }, }); diff --git a/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx b/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx index ebb0e12ee7..098d7e7265 100644 --- a/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx +++ b/app/client/src/reducers/entityReducers/widgetConfigReducer.tsx @@ -18,6 +18,7 @@ import { DropdownWidgetProps } from "../../widgets/DropdownWidget"; import { CheckboxWidgetProps } from "../../widgets/CheckboxWidget"; import { RadioGroupWidgetProps } from "../../widgets/RadioGroupWidget"; import { AlertWidgetProps } from "../../widgets/AlertWidget"; +import { FilePickerWidgetProps } from "../../widgets/FilepickerWidget"; const initialState: WidgetConfigReducerState = WidgetConfigResponse; @@ -42,6 +43,7 @@ export interface WidgetConfigReducerState { CHECKBOX_WIDGET: Partial & WidgetConfigProps; RADIO_GROUP_WIDGET: Partial & WidgetConfigProps; ALERT_WIDGET: Partial & WidgetConfigProps; + FILE_PICKER_WIDGET: Partial & WidgetConfigProps; }; configVersion: number; } diff --git a/app/client/src/utils/PropertyControlRegistry.tsx b/app/client/src/utils/PropertyControlRegistry.tsx index 0479db311d..c73bb60430 100644 --- a/app/client/src/utils/PropertyControlRegistry.tsx +++ b/app/client/src/utils/PropertyControlRegistry.tsx @@ -11,6 +11,9 @@ import SwitchControl, { } from "../propertyControls/SwitchControl"; import OptionControl from "../propertyControls/OptionControl"; import { ControlProps } from "../propertyControls/BaseControl"; +import MultiSelectControl, { + MultiSelectControlProps, +} from "../propertyControls/MultiSelectControl"; class PropertyControlRegistry { static registerPropertyControlBuilders() { @@ -24,6 +27,11 @@ class PropertyControlRegistry { return ; }, }); + PropertyControlFactory.registerControlBuilder("MULTI_SELECT", { + buildPropertyControl(controlProps: MultiSelectControlProps): JSX.Element { + return ; + }, + }); PropertyControlFactory.registerControlBuilder("SWITCH", { buildPropertyControl(controlProps: SwitchControlProps): JSX.Element { return ; diff --git a/app/client/src/utils/WidgetRegistry.tsx b/app/client/src/utils/WidgetRegistry.tsx index 89f28273ff..4d953f4464 100644 --- a/app/client/src/utils/WidgetRegistry.tsx +++ b/app/client/src/utils/WidgetRegistry.tsx @@ -15,6 +15,9 @@ import ButtonWidget, { ButtonWidgetProps } from "../widgets/ButtonWidget"; import DropdownWidget, { DropdownWidgetProps } from "../widgets/DropdownWidget"; import ImageWidget, { ImageWidgetProps } from "../widgets/ImageWidget"; import TableWidget, { TableWidgetProps } from "../widgets/TableWidget"; +import FilePickerWidget, { + FilePickerWidgetProps, +} from "../widgets/FilepickerWidget"; class WidgetBuilderRegistry { static registerWidgetBuilders() { WidgetFactory.registerWidgetBuilder("CONTAINER_WIDGET", { @@ -75,6 +78,11 @@ class WidgetBuilderRegistry { return ; }, }); + WidgetFactory.registerWidgetBuilder("FILE_PICKER_WIDGET", { + buildWidget(widgetData: FilePickerWidgetProps): JSX.Element { + return ; + }, + }); } } diff --git a/app/client/src/widgets/ButtonWidget.tsx b/app/client/src/widgets/ButtonWidget.tsx index 8ea024aa16..4b59d9043f 100644 --- a/app/client/src/widgets/ButtonWidget.tsx +++ b/app/client/src/widgets/ButtonWidget.tsx @@ -22,8 +22,8 @@ class ButtonWidget extends BaseWidget { style={this.getPositionStyle()} buttonStyle={this.props.buttonStyle} widgetId={this.props.widgetId} - widgetName={this.props.widgetName} key={this.props.widgetId} + widgetName={this.props.widgetName} text={this.props.text} disabled={this.props.isDisabled} onClick={this.onButtonClickBound} diff --git a/app/client/src/widgets/FilepickerWidget.tsx b/app/client/src/widgets/FilepickerWidget.tsx new file mode 100644 index 0000000000..4df4f412b1 --- /dev/null +++ b/app/client/src/widgets/FilepickerWidget.tsx @@ -0,0 +1,88 @@ +import * as React from "react"; +import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; +import { WidgetType } from "../constants/WidgetConstants"; +import FilePickerComponent from "../components/appsmith/FilePickerComponent"; +import Uppy from "@uppy/core"; +import GoogleDrive from "@uppy/google-drive"; +import Webcam from "@uppy/webcam"; +import Url from "@uppy/url"; +import OneDrive from "@uppy/onedrive"; + +class FilePickerWidget extends BaseWidget { + uppy: any; + + constructor(props: FilePickerWidgetProps) { + super(props); + this.refreshUppy(props); + } + + refreshUppy = (props: FilePickerWidgetProps) => { + this.uppy = Uppy({ + id: this.props.widgetId, + autoProceed: true, + allowMultipleUploads: true, + debug: false, + restrictions: { + maxFileSize: null, + maxNumberOfFiles: props.maxNumFiles, + minNumberOfFiles: null, + allowedFileTypes: props.allowedFileTypes, + }, + }) + .use(GoogleDrive, { companionUrl: "https://companion.uppy.io" }) + .use(Url, { companionUrl: "https://companion.uppy.io" }) + .use(OneDrive, { + companionUrl: "https://companion.uppy.io/", + }) + .use(Webcam, { + onBeforeSnapshot: () => Promise.resolve(), + countdown: false, + mirror: true, + facingMode: "user", + locale: {}, + }); + }; + + componentDidUpdate(prevProps: FilePickerWidgetProps) { + super.componentDidUpdate(prevProps); + if ( + prevProps.allowedFileTypes !== this.props.allowedFileTypes || + prevProps.maxNumFiles !== this.props.maxNumFiles + ) { + this.refreshUppy(this.props); + } + } + + componentDidMount() { + super.componentDidMount(); + this.refreshUppy(this.props); + } + + componentWillUnmount() { + this.uppy.close(); + } + + getPageView() { + return ( + + ); + } + + getWidgetType(): WidgetType { + return "FILE_PICKER_WIDGET"; + } +} + +export interface FilePickerWidgetProps extends WidgetProps { + label: string; + maxNumFiles?: number; + allowedFileTypes: string[]; +} + +export default FilePickerWidget; diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 0fc75a963f..abb6dbb278 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -1852,6 +1852,166 @@ lodash.unescape "4.0.1" semver "^6.3.0" +"@uppy/companion-client@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-1.4.1.tgz#138032c145ef0961f7f3a047b36b593d6fc772d2" + integrity sha512-ZQpEibQMDRwCzp3zugRHlCl/ne7UpCF+4ZfayhspGt7nz8tuUZXuDH15LhyMS06Y9S/kXTRMrA/w5bY42QtHDw== + dependencies: + namespace-emitter "^2.0.1" + +"@uppy/core@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@uppy/core/-/core-1.5.1.tgz#61a083ea18e35d53e37248db6a379d480abe39c1" + integrity sha512-8HyCSKxece1PyOCx2oiZ8M61+ci6WSvlVukztBaU2eV2wjVYM/Bqxdv3dQtcjLwV82+2LD+9pYp2mlvou4bP5A== + dependencies: + "@uppy/store-default" "^1.2.0" + "@uppy/utils" "^2.0.0" + cuid "^2.1.1" + lodash.throttle "^4.1.1" + mime-match "^1.0.2" + namespace-emitter "^2.0.1" + preact "8.2.9" + +"@uppy/dashboard@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@uppy/dashboard/-/dashboard-1.4.1.tgz#8b9c1841d4f2594fa998d1a95282dd3f907d009d" + integrity sha512-/JG5YTPOu2oz2qQNSPEnXFTY2S0YWxPiV7x5SCwqP3zMI2g/tlG5l8sYTN2+KCWS8JZZaqyEaSWIh8KKQULcTQ== + dependencies: + "@uppy/informer" "^1.3.1" + "@uppy/provider-views" "^1.4.0" + "@uppy/status-bar" "^1.3.1" + "@uppy/thumbnail-generator" "^1.4.0" + "@uppy/utils" "^2.0.0" + classnames "^2.2.6" + cuid "^2.1.1" + is-shallow-equal "^1.0.1" + lodash.debounce "^4.0.8" + lodash.throttle "^4.1.1" + memoize-one "^5.0.4" + preact "8.2.9" + preact-css-transition-group "^1.3.0" + resize-observer-polyfill "^1.5.0" + +"@uppy/drag-drop@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/drag-drop/-/drag-drop-1.3.1.tgz#d2af47a33d0f4eef7283dabcc174a782b3134a5f" + integrity sha512-0LOMG766h+E0QKuYy7IgMGXhODhBAIEA5IzBEGF9LWdaYvsAx1JM9Z+wMEn3egu2qFVTTSyhOojROoaV1yDHBg== + dependencies: + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/file-input@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/file-input/-/file-input-1.3.1.tgz#86e92fa1c7cd379a55b64a828df6369030366377" + integrity sha512-Z8Qvdbaaw0SzPwg0gSws2SYKdOS86QDHbRLnNJNEXRNrETlYjeqZvAOAtanQZhzkKkxXrpS1jr/VISjNS16f4A== + dependencies: + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/google-drive@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@uppy/google-drive/-/google-drive-1.3.2.tgz#473ab3cd44eb0df252e9b462c2b25cf31bbb4d7e" + integrity sha512-CezojbaXQomhdItkTPu9j7yguVjaX02kIfr3a6ojXBuFhMY2JVb7ef8EkfabAa28RwK+l8sqEkg/AQjVfqZI8w== + dependencies: + "@uppy/companion-client" "^1.4.1" + "@uppy/provider-views" "^1.4.0" + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/informer@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/informer/-/informer-1.3.1.tgz#ce9ac6fea1e695e5a38a65f2760ec1a4d522fde4" + integrity sha512-SuD686BxdEo4eAHSxjK0haPE0x8Pi2qsKUtRITx4CM+t4NKrg21/MRjD/dD4r4ydyYO5HhC5wTZfkAMA8BRVzQ== + dependencies: + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/onedrive@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@uppy/onedrive/-/onedrive-0.1.1.tgz#0874117b8e3c12bbdd86987cd24ba518b4a5721c" + integrity sha512-t9vwG+dmYJYa5JuPB05jQgV1V3mOgnVTSU5ScxloqI2O0FC9VFWh1P7M0A5AlwfO0BOrTU4oXRG9m6jWOdx2CA== + dependencies: + "@uppy/companion-client" "^1.4.1" + "@uppy/provider-views" "^1.4.0" + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/progress-bar@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/progress-bar/-/progress-bar-1.3.1.tgz#0b551fb4182abab9f587170d2ce5202928ab2c74" + integrity sha512-GlAfyXJWsY+9kpu1H2LCv/mDe6roNQAlznHPF1S6045NvxphQLIqebe9+ZK8nVhZKY6QnioXl57cay4N9cjvjQ== + dependencies: + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/provider-views@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@uppy/provider-views/-/provider-views-1.4.0.tgz#ffe4b9bb8424b96b9a5f49d65097992c8b9c2886" + integrity sha512-y9laKMGu4GshqMmsxCBovqBtNKl4FOvwZvfuZZ4QC71xpuGLrEi/Y21JMHkh0aVTWxN4AmlMkj5t9fDKuhAxXw== + dependencies: + "@uppy/utils" "^2.0.0" + classnames "^2.2.6" + preact "8.2.9" + +"@uppy/react@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@uppy/react/-/react-1.3.2.tgz#6c924ea19ed4cca7c4c46636b7e47085377b26fd" + integrity sha512-EzXDxyyMQZNoDwiUJwxRM9NNUppcFrqZ7aE2BZrGVBHKH0Rr9jSTDxkEts/kRQ+uUbsQhF3ppU6kYdR0H1bdbA== + dependencies: + "@uppy/dashboard" "^1.4.1" + "@uppy/drag-drop" "^1.3.1" + "@uppy/progress-bar" "^1.3.1" + "@uppy/status-bar" "^1.3.1" + "@uppy/utils" "^2.0.0" + prop-types "^15.6.1" + +"@uppy/status-bar@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/status-bar/-/status-bar-1.3.1.tgz#36525803d5a55e6c3043604cf429b21d8afbae86" + integrity sha512-bEHyQOFRnqPXbAjvbPHtCdlMzrT91lR/r+zL4hRHU+pAJLIebLlhsXcxkKrJWtho6s0TcKXq/KGUPRVFIPVYww== + dependencies: + "@uppy/utils" "^2.0.0" + classnames "^2.2.6" + lodash.throttle "^4.1.1" + preact "8.2.9" + +"@uppy/store-default@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.0.tgz#4007b84e6eef24b3f07b0fe5457548386cea77d9" + integrity sha512-mnkxdX4DJMP2nrBklh5MXdn31bAyBSlCcp4+BZanFwv4WiCEpg/ruYzNzaJ1nVyuINJEDj2nx/DWxo+1F6WuWw== + +"@uppy/thumbnail-generator@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@uppy/thumbnail-generator/-/thumbnail-generator-1.4.0.tgz#746e1b10a126b4b6992fe1bc5311f86c3c2321c0" + integrity sha512-Ftgr36xp6zS1Wh37ceURV/I9LiG7oI3F6YD0cviCI5dw8vYpjV8k9TvE6NBfZ3cnHk/+DAevaOR+pyjBIvQYHA== + dependencies: + "@uppy/utils" "^2.0.0" + exif-js "2.3.0" + +"@uppy/url@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@uppy/url/-/url-1.3.2.tgz#94a994585e7e744d146c20279da1aa06143bff6c" + integrity sha512-mvP+b4nFHHqcdQE6Wy+hDHIpZsUdffHWHLFOgvM/g7DIcyrqrlhBRCfXHPYI7kl8QWqg7IbWFrQ6OYeOI9AgAg== + dependencies: + "@uppy/companion-client" "^1.4.1" + "@uppy/utils" "^2.0.0" + preact "8.2.9" + +"@uppy/utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-2.0.0.tgz#f603458cedb3d86017e33f00cce32e20f690b6f5" + integrity sha512-FWuSmdCK+dB5ybGlTp5xx1C6hf9Tsdl58Lrfg9KUF/4ogkzupj/2uEYmcn26S0GZ8FJPWNG/858EeF/bZNFAQw== + dependencies: + lodash.throttle "^4.1.1" + +"@uppy/webcam@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@uppy/webcam/-/webcam-1.3.1.tgz#e9bb68eee6a3cdff11888705b7d35ab0a655e09b" + integrity sha512-9wo2cC2Vw1Rqc7IL1C8btT4BiB5DouLbIKJM/oSgmQ8SatwytMDPtAA0qgD0i/cC6rmGZh1J6W7IdnstJFoUSA== + dependencies: + "@uppy/utils" "^2.0.0" + preact "8.2.9" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -3110,7 +3270,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2, classnames@^2.2.5: +classnames@^2.2, classnames@^2.2.5, classnames@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== @@ -3787,6 +3947,11 @@ csstype@^2.2.0, csstype@^2.5.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5" integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ== +cuid@^2.1.1: + version "2.1.6" + resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.6.tgz#dc3a20b5a7497d36d32c0bf8a2997524c9c796c4" + integrity sha512-ZFp7PS6cSYMJNch9fc3tyHdE4T8TDo3Y5qAxb0KSA9mpiYDo7z9ql1CznFuuzxea9STVIDy0tJWm2lYiX2ZU1Q== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -4712,6 +4877,11 @@ execa@^2.0.3: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +exif-js@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/exif-js/-/exif-js-2.3.0.tgz#9d10819bf571f873813e7640241255ab9ce1a814" + integrity sha1-nRCBm/Vx+HOBPnZAJBJVq5zhqBQ= + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -6323,6 +6493,11 @@ is-root@2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-shallow-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shallow-equal/-/is-shallow-equal-1.0.1.tgz#c410b51eb1c12ee50cd02891d32d1691a132d73c" + integrity sha512-lq5RvK+85Hs5J3p4oA4256M1FEffzmI533ikeDHvJd42nouRRx5wBzt36JuviiGe5dIPyHON/d0/Up+PBo6XkQ== + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -7295,6 +7470,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.memoize@4.x, lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -7325,6 +7505,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + lodash.unescape@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" @@ -7494,7 +7679,7 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" -"memoize-one@>=3.1.1 <6", memoize-one@^5.0.0: +"memoize-one@>=3.1.1 <6", memoize-one@^5.0.0, memoize-one@^5.0.4: version "5.1.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== @@ -7622,6 +7807,13 @@ mime-db@1.40.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-match@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8" + integrity sha1-P4fDHprxpf1IX7nbE0Qosju7e6g= + dependencies: + wildcard "^1.1.0" + mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.24" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" @@ -7826,6 +8018,11 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +namespace-emitter@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c" + integrity sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g== + nan@^2.12.1, nan@^2.13.2: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -9452,6 +9649,16 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.1 source-map "^0.6.1" supports-color "^6.1.0" +preact-css-transition-group@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/preact-css-transition-group/-/preact-css-transition-group-1.3.0.tgz#06fe468b26f7802e95b829a762db0bc199aef399" + integrity sha1-Bv5Giyb3gC6VuCmnYtsLwZmu85k= + +preact@8.2.9: + version "8.2.9" + resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40" + integrity sha512-ThuGXBmJS3VsT+jIP+eQufD3L8pRw/PY3FoCys6O9Pu6aF12Pn9zAJDX99TfwRAFOCEKm/P0lwiPTbqKMJp0fA== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -9555,7 +9762,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.3" -prop-types@15.7.2, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.0, prop-types@^15.7.2: +prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.0, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -10402,7 +10609,7 @@ reselect@^4.0.0: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== -resize-observer-polyfill@^1.5.1: +resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== @@ -12479,6 +12686,11 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +wildcard@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5" + integrity sha1-pwIEUwhNjNLv5wup02liY94XEKU= + wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"