From f4183bcef40b7c8d69aec227ee6653f17bde9e3f Mon Sep 17 00:00:00 2001 From: Daniel Mason Date: Tue, 14 Jul 2020 16:38:22 +0800 Subject: [PATCH] feat: moving notes to other notebooks via drag and drop (#52) * cosmetic: show notes with children narrower. * feat: moving notes by dragging them to a different notebook * lock * version: electron * fix: case * chore: add deps Co-authored-by: Daniel Mason --- .github/workflows/master.yml | 3 + app/components/MainMenu/MainMenu.tsx | 2 + app/components/MainMenu/MenuItem.tsx | 33 +++++++++- app/components/MiddleMenu/MiddleMenu.tsx | 3 + .../MiddleMenu/NoteCard/NoteCard.style.js | 3 +- .../MiddleMenu/NoteCard/NoteCard.tsx | 26 ++++++-- app/containers/MainMenu/reducers.ts | 6 +- app/containers/MiddleMenu/MiddleMenuCont.tsx | 1 + app/containers/Root.tsx | 7 ++- app/containers/TreeMenuCont/TreeMenuCont.tsx | 19 ++++-- app/reducers/noteActions.ts | 21 +++++++ app/reducers/notes.ts | 58 +++++------------- app/utils/DragItemTypes.js | 3 + app/utils/utils.js | 60 +++++++++++++++++++ package.json | 4 +- yarn.lock | 52 ++++++++++++++-- 16 files changed, 236 insertions(+), 65 deletions(-) create mode 100644 app/utils/DragItemTypes.js diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 20cfc54..37de91a 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -122,6 +122,9 @@ jobs: - name: "[Docker Build] Build the tagged Docker image" if: matrix.os == 'ubuntu-18.04' && github.ref == 'refs/heads/master' run: docker build . --file Dockerfile.prod --tag danobot/notorious:${{ steps.pkg.outputs.version }} && docker tag danobot/notorious:${{ steps.pkg.outputs.version }} danobot/notorious:latest + - name: "[Docker Build] Build the tagged Docker image" + if: matrix.os == 'ubuntu-18.04' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/develop' + run: docker build . --file Dockerfile.prod --tag danobot/notorious:${{ steps.pkg.outputs.version }} && docker tag danobot/notorious:${{ steps.pkg.outputs.version }} danobot/notorious:latest - name: "[Docker Build] Push the tagged Docker image" if: matrix.os == 'ubuntu-18.04' && github.ref == 'refs/heads/master' run: docker push danobot/notorious:${{ steps.pkg.outputs.version }} diff --git a/app/components/MainMenu/MainMenu.tsx b/app/components/MainMenu/MainMenu.tsx index 69d378a..abd7ae2 100644 --- a/app/components/MainMenu/MainMenu.tsx +++ b/app/components/MainMenu/MainMenu.tsx @@ -1,5 +1,6 @@ import React, {useRef} from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { useDrop } from 'react-dnd' import { faPlusCircle, faFile, @@ -21,6 +22,7 @@ import Finder from '../util/Finder'; import TreeMenuCont from '../../containers/TreeMenuCont/TreeMenuCont'; import { Spin } from 'antd'; import { GlobalHotKeys } from 'react-hotkeys'; +import { DragItemTypes } from '../../utils/DragItemTypes'; export default function MainMenu({ notebooks, diff --git a/app/components/MainMenu/MenuItem.tsx b/app/components/MainMenu/MenuItem.tsx index 74d69ca..0cd7602 100644 --- a/app/components/MainMenu/MenuItem.tsx +++ b/app/components/MainMenu/MenuItem.tsx @@ -1,16 +1,20 @@ import React, {useState} from 'react'; import { MenuItemStyle, MenuItemIcon, MenuItemLabel, MenuItemNormal, MenuItemSelected } from './style'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; - +import { useDrop } from 'react-dnd' import { faCaretSquareRight, faCaretSquareDown } from '@fortawesome/free-solid-svg-icons'; +import { DragItemTypes } from '../../utils/DragItemTypes'; export default function MenuItem({ + noteId, onClickHandler = () => {}, + cacheParentId = () => {}, icon, label, compKey, right, indent, + droppable=false, collapsible=false, visible=false, skipIcon=false, @@ -19,15 +23,40 @@ export default function MenuItem({ }) { const MenuItemComponent = (selected) ? MenuItemSelected : MenuItemNormal; const [v, setVis] = useState(visible ) + const [id, setId] = useState( ) const handleClick = () => { setVis(!v) } + // console.log("MainItem "+noteId) + const [{ canDrop, isOver }, drop] = useDrop({ + accept: DragItemTypes.NOTE, + drop: (data) => { + cacheParentId() + return { name: id} + }, + collect: (monitor) => { + return { + isOver: monitor.isOver(), + canDrop: monitor.canDrop(), + } + }, + }) + // const isActive = canDrop && isOver + // let style = {} + // if (isActive) { + // style.backgroundColor = 'darkgreen' + // } else if (canDrop && droppable) { + // style.backgroundColor = 'darkkhaki' + // } return ( - + onClickHandler()} key={compKey} indent={indent} + > {!collapsible && !skipIcon && handleClick()}>{icon}} {collapsible && handleClick()}>{ moveNote(id, dropNoteCache)} handlers={notecardContextHandlers} /> )) diff --git a/app/components/MiddleMenu/NoteCard/NoteCard.style.js b/app/components/MiddleMenu/NoteCard/NoteCard.style.js index 7c6cca9..5b01afa 100644 --- a/app/components/MiddleMenu/NoteCard/NoteCard.style.js +++ b/app/components/MiddleMenu/NoteCard/NoteCard.style.js @@ -1,9 +1,10 @@ import styled from 'styled-components'; +import { hasChildren } from '../../../utils/utils'; export const NoteCardStyle = styled.div` // background-color: green; background-color: ${props => props.selected ? props.theme.colors.background.selected : 'inherit'}; - height: 100px; + height: ${props => hasChildren(props.note.children) ? '31px': '100px'}; padding: 5px; overflow: hidden; border-bottom: 1px solid ${props => props.theme.colors.background.lift}; diff --git a/app/components/MiddleMenu/NoteCard/NoteCard.tsx b/app/components/MiddleMenu/NoteCard/NoteCard.tsx index 6a8e629..78f0af4 100644 --- a/app/components/MiddleMenu/NoteCard/NoteCard.tsx +++ b/app/components/MiddleMenu/NoteCard/NoteCard.tsx @@ -4,7 +4,7 @@ import Truncate from 'react-truncate' import { Tag } from 'antd'; import Moment from 'react-moment'; import styled from 'styled-components'; - +import { useDrag } from 'react-dnd' import { ContextMenu, ContextMenuTrigger, @@ -19,6 +19,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faClock, faListAlt } from "@fortawesome/free-regular-svg-icons"; import { faFolderOpen, faInbox, faColumns, faTasks, faFile, faThumbtack, faTh, faStream, faTimesCircle, faExclamationTriangle , faStar} from "@fortawesome/free-solid-svg-icons"; +import { hasChildren } from '../../../utils/utils'; +import { DragItemTypes } from '../../../utils/DragItemTypes'; const removeMd = require('remove-markdown'); export const InlineItem = styled.div` @@ -41,6 +43,19 @@ export default function NoteCard(props) { cmSwitchEditorHandler } = props.handlers; const { title, content, tags, _id, createdAt, updatedAt,children, kind, pinned, showInMenu,starred, deleted} = props.note; + const [{ isDragging }, drag] = useDrag({ + item: { name: _id, type: DragItemTypes.NOTE }, + end: (item, monitor) => { + const dropResult = monitor.getDropResult() + if (item) { + props.handleDrag(item.name) + } + }, + collect: (monitor) => ({ + isDragging: monitor.isDragging(), + }), + }) + // console.log(children) return ( <> @@ -49,10 +64,11 @@ export default function NoteCard(props) { key={`${_id}style`} onClick={e => props.handleClick(props.note._id)} {...props} + ref={drag} >
{title || 'Untitled Note'}
- {children && children.length > 0 && {children.length}} + {hasChildren(children) && {children.length}} {createdAt} @@ -63,7 +79,7 @@ export default function NoteCard(props) { {kind === 'index' && } {kind === 'columns' && } {starred && } - {deleted && children.length > 0 && } + {deleted && hasChildren(children) && }
@@ -72,11 +88,11 @@ export default function NoteCard(props) { {tags && tags.length > 0 &&{ tags.map(t => {t}) }} -
+ {false &&
...}> {removeMd(content)} -
+
}
diff --git a/app/containers/MainMenu/reducers.ts b/app/containers/MainMenu/reducers.ts index a186182..4dfd54d 100644 --- a/app/containers/MainMenu/reducers.ts +++ b/app/containers/MainMenu/reducers.ts @@ -1,6 +1,6 @@ import { createReducer } from '../../utils/utils' import { configStorage } from '../../utils/localStorage'; -import { SEARCH_NOTES_RESULTS } from '../../reducers/noteActions'; +import { SEARCH_NOTES_RESULTS, CACHE_NOTE_PARENT_ID, MOVE_NOTE } from '../../reducers/noteActions'; import { SELECT_NOTEBOOK } from './actions'; @@ -10,6 +10,10 @@ const initialState = { } const mainMenuReducer = createReducer(initialState, { + [CACHE_NOTE_PARENT_ID]: (state, action) => { + return {...state, moveNoteDropTargetId: action.id} + }, + [SELECT_NOTEBOOK]: (state, action) => { return {...state, filter: action.filter} }, diff --git a/app/containers/MiddleMenu/MiddleMenuCont.tsx b/app/containers/MiddleMenu/MiddleMenuCont.tsx index 8b156cf..75088b1 100644 --- a/app/containers/MiddleMenu/MiddleMenuCont.tsx +++ b/app/containers/MiddleMenu/MiddleMenuCont.tsx @@ -97,6 +97,7 @@ function mapStateToProps(state) { addButtonDisabled: state.mainMenu.filter === "TRASH", selectedNote: state.contentArea.selectedNote, headerLabel: notebookLabelMaker(state.mainMenu.filter, state.notes, state.middleMenu), + dropNoteCache: state.mainMenu.moveNoteDropTargetId, sorter: state.middleMenu.sorter }; } diff --git a/app/containers/Root.tsx b/app/containers/Root.tsx index 42bd0df..4c906fa 100644 --- a/app/containers/Root.tsx +++ b/app/containers/Root.tsx @@ -7,7 +7,8 @@ import { ThemeProvider } from 'styled-components'; import { Store } from '../reducers/types'; import Routes from '../Routes'; import darkTheme from '../utils/dark_theme.json'; - +import { DndProvider } from 'react-dnd' +import { HTML5Backend } from 'react-dnd-html5-backend' type Props = { store: Store; history: History; @@ -17,7 +18,9 @@ const Root = ({ store, history }: Props) => ( - + + + diff --git a/app/containers/TreeMenuCont/TreeMenuCont.tsx b/app/containers/TreeMenuCont/TreeMenuCont.tsx index a5ad165..517d4cc 100644 --- a/app/containers/TreeMenuCont/TreeMenuCont.tsx +++ b/app/containers/TreeMenuCont/TreeMenuCont.tsx @@ -26,7 +26,7 @@ class TreeMenuCont extends React.Component { render() { - const {selectedNotebook, selectNotebook, note, subNotes, handlers, children} = this.props + const {selectedNotebook, selectNotebook, note, subNotes, handlers, children, cacheParentId} = this.props const { cmCreateNotebookInside, cmShowInMenuHandler, @@ -36,7 +36,7 @@ class TreeMenuCont extends React.Component { const {_id, title} = note // console.log(selectedNotebook) const icon = this.state.open ? this.setState({open: false})} icon={faChevronDown} /> : this.setState({open: true})} icon={faChevronRight} /> - + // console.log("TreeMenuCont Note id " + _id) // we dont want to close a notebook menu when it is first selected. We want to close it on click (given its already selected) and open it given its closed. // const singleClickHandler = (selectedNotebook !== _id) ? () => {selectNotebook(note._id); this.setState({open: true})} : () => {selectNotebook(note._id); this.setState({open: !this.state.open})} const singleClickHandler = () => {selectNotebook(note._id); this.setState({open: !this.state.open})} @@ -45,20 +45,27 @@ class TreeMenuCont extends React.Component { {subNotes && subNotes.length ===0 && {note.title}} icon={} - key={note._id} right={{children.length}} + right={{children.length}} selected={selectedNotebook === _id} - onClickHandler={e=>selectNotebook(note._id)} key={"menucokponent"+_id} + onClickHandler={e=>selectNotebook(note._id)} + cacheParentId={e=>cacheParentId(_id)} /> } {subNotes && subNotes.length > 0 && <> {singleClickHandler() }} + key={`menu-item-${_id}`} + droppable + noteId={this.props.note._id} + onClickHandler={e=> {singleClickHandler() }} + cacheParentId={e=>cacheParentId(_id)} indent={this.props.level*16} - key={"MenuItem"+_id} label={ {note.title } diff --git a/app/reducers/noteActions.ts b/app/reducers/noteActions.ts index 9863ede..b27dbc3 100644 --- a/app/reducers/noteActions.ts +++ b/app/reducers/noteActions.ts @@ -5,8 +5,10 @@ import {notesDB} from '../PouchInit' import FlexSearch from 'flexsearch'; import MiddleMenu from '../components/MiddleMenu/MiddleMenu'; export const UPDATE_NOTE = 'UPDATE_NOTE'; +export const MOVE_NOTE = 'MOVE_NOTE'; export const CREATE_NOTE = 'CREATE_NOTE'; export const DELETE_NOTE = 'DELETE_NOTE'; +export const CACHE_NOTE_PARENT_ID = 'CACHE_NOTE_PARENT_ID'; // required beacuse react-dnd always receives undefined from Drop Target export const SAVE_ATTACHMENT = 'ADD_ATTACHMENT'; export const SAVE_ATTACHMENT_SUCCESS = 'SAVE_ATTACHMENT_SUCCESS'; export const SAVE_ATTACHMENT_ERROR = 'SAVE_ATTACHMENT_ERROR'; @@ -41,6 +43,25 @@ export function emptyTrash() { }; } +export function moveNote(id: string, parent: string) { + return dispatch => { + dispatch({ + type: MOVE_NOTE, + id, + parent + }); + }; +} + +export function cacheParentId(id: string) { + return dispatch => { + dispatch({ + type: CACHE_NOTE_PARENT_ID, + id + }); + }; +} + export function createNote(parent: string, attributes: object) { const noteId = uuid() return dispatch => { diff --git a/app/reducers/notes.ts b/app/reducers/notes.ts index 45cb8f4..61fb45d 100644 --- a/app/reducers/notes.ts +++ b/app/reducers/notes.ts @@ -1,22 +1,20 @@ import { persistentCollectionReducer } from 'redux-pouchdb'; import PouchDB from 'pouchdb' import config from '../utils/config'; -import {createReducer} from '../utils/utils' +import {createReducer, removeNoteFromParentsChildArray, updateNoteAttributesInArray, addChildToParent} from '../utils/utils' // import { createReducer } from '@reduxjs/toolkit' -import { UPDATE_NOTE, CREATE_NOTE, DELETE_NOTE, REMOVE_EDITOR, ADD_EDITOR, TOGGLE_MENU_SHOW_NOTE, TOGGLE_PIN_NOTE, ADD_ATTACHMENT} from './noteActions'; +import { UPDATE_NOTE, CREATE_NOTE, DELETE_NOTE, REMOVE_EDITOR, ADD_EDITOR, TOGGLE_MENU_SHOW_NOTE, TOGGLE_PIN_NOTE, ADD_ATTACHMENT, MOVE_NOTE} from './noteActions'; import { notesDB } from '../PouchInit'; import { SELECT_NOTE } from '../containers/ContentAreaCont/actions'; import { findChildrenOfNoteInclDeleted } from '../containers/MainMenu/selectors' const initialState = [] const notesReducer = createReducer(initialState, { + [CREATE_NOTE]: (state, action) => { const noteId = action.id - const newState = state.map((note, id) => { - if (note._id !== action.parent) { return note } - return {...note, children: [...note.children, noteId]} // add new child to parents `children` array (for easy read operation) - }) + const newState = addChildToParent(newState, action.id, action.parent) const newNote = {_id: noteId, title: "", createdAt: Date.now(), @@ -49,48 +47,24 @@ const notesReducer = createReducer(initialState, { // return state // } } - const parent = noteToBeNuked.parent - if ( parent !== undefined && parent !== "root") { - console.log("parent: ",parent) - console.log("parent.children: ",parent.children) - newState = newState.map((note, id) => { - if (note._id !== parent) { return note } - // we found the parent note: - let splicedChildren = note.children - const index = splicedChildren.indexOf(noteToBeNuked._id) - if (index > -1) { - splicedChildren.splice(index, 1) - } - console.log("parent: ",parent) - return {...note, children: splicedChildren} // remove child entry - }) - } + newState = removeNoteFromParentsChildArray(newState, noteToBeNuked) return newState // and add new note to array }, [UPDATE_NOTE]: (state, action) => { console.log(action) - return state.map((item, id) => { - if (item._id !== action.id) { return item } - let extra = {} - let c = action.attributes - console.log(action) - // if (action.attributes.skipUpdatedAt || false) { - // } else { - // c.updatedAt = Date.now() - // } - if (c.hasOwnProperty("title") || c.hasOwnProperty("content")) { - console.log("Title or content updated") - c.updatedAt = Date.now() - console.log(c) - } - delete c.skipUpdatedAt - return { - ...item, - ...c - } - }) + return updateNoteAttributesInArray(newState, action.id, action.attributes) + + }, + [MOVE_NOTE]: (state, action) => { + const noteToBeMoved = state.filter(n => n._id === action.id)[0] + let newState = removeNoteFromParentsChildArray(state, noteToBeMoved ) + newState = addChildToParent(newState, action.id, action.parent) + newState = updateNoteAttributesInArray(newState, action.id, {parent: action.parent}) + return newState + + }, [SELECT_NOTE]: (state, action) => { // when we select the note, save its id in the parents lastSelectedChild field console.group("SELECT_NOTE in notes reducer") diff --git a/app/utils/DragItemTypes.js b/app/utils/DragItemTypes.js new file mode 100644 index 0000000..4230ab6 --- /dev/null +++ b/app/utils/DragItemTypes.js @@ -0,0 +1,3 @@ +export const DragItemTypes = { + NOTE: 'note', +} diff --git a/app/utils/utils.js b/app/utils/utils.js index 41397b9..2b21309 100644 --- a/app/utils/utils.js +++ b/app/utils/utils.js @@ -117,3 +117,63 @@ export const imageURL = ( note, attachment ) => { return `${config.url}/notes/${note._id}/${attachment}`; } +export const hasChildren = ( children ) => { + + if (children != null) { + return children.length > 0; + } else { + return false; + } +} +export const updateNoteAttributesInArray = (state, noteId, attributes) => { + return state.map((item, id) => { + if (item._id !== noteId) { return item } + let extra = {} + let c = attributes + // if (action.attributes.skipUpdatedAt || false) { + // } else { + // c.updatedAt = Date.now() + // } + if (c.hasOwnProperty("title") || c.hasOwnProperty("content")) { + console.log("Title or content updated") + c.updatedAt = Date.now() + console.log(c) + } + + delete c.skipUpdatedAt + return { + ...item, + ...c + } + }) +} +export const addChildToParent = (state, noteId, parentId ) => { + return state.map((note, id) => { + if (note._id !== parentId) { return note } + return {...note, children: [...note.children, noteId]} // add new child to parents `children` array (for easy read operation) + }) +} + +export const removeNoteFromParentsChildArray = (newState, noteToBeNuked ) => { + const parent = noteToBeNuked.parent + if ( parent !== undefined && parent !== "root") { + console.log("parent: ",parent) + console.log("parent.children: ",parent.children) + + // find the parent note is all notes: + newState = newState.map((note, id) => { + if (note._id !== parent) { return note } + // we found the parent note: + let splicedChildren = note.children + const index = splicedChildren.indexOf(noteToBeNuked._id) // Remove deleted note from the parent's child array + if (index > -1) { + splicedChildren.splice(index, 1) + } + console.log("parent: ",parent) + return {...note, children: splicedChildren} // remove child entry + }) + } + return newState +} + + diff --git a/package.json b/package.json index a59e67d..ee197fb 100644 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ "cross-spawn": "^7.0.1", "css-loader": "^3.4.2", "detect-port": "^1.3.0", - "electron": "8.0.2", + "electron": "8.2.4", "electron-builder": "^22.4.0", "electron-devtools-installer": "^2.2.4", "electron-rebuild": "^1.10.0", @@ -320,6 +320,8 @@ "react-contextmenu": "^2.13.0", "react-custom-scrollbars": "^4.2.1", "react-delay-input": "^4.1.0", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", "react-dom": "^16.12.0", "react-ellipsis-text": "^1.2.1", "react-highlight-words": "^0.16.0", diff --git a/yarn.lock b/yarn.lock index 823d5d6..3e06ccc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1423,6 +1423,21 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@react-dnd/asap@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-4.0.0.tgz#b300eeed83e9801f51bd66b0337c9a6f04548651" + integrity sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ== + +"@react-dnd/invariant@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-2.0.0.tgz#09d2e81cd39e0e767d7da62df9325860f24e517e" + integrity sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw== + +"@react-dnd/shallowequal@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a" + integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg== + "@reduxjs/toolkit@^1.2.5": version "1.3.4" resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.3.4.tgz#23abc4892310c75310224e0551d27b990d853a45" @@ -1600,7 +1615,7 @@ version "4.7.5" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860" -"@types/hoist-non-react-statics@^3.3.0": +"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" dependencies: @@ -5853,6 +5868,15 @@ dmg-builder@22.5.1: js-yaml "^3.13.1" sanitize-filename "^1.6.3" +dnd-core@^11.1.3: + version "11.1.3" + resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-11.1.3.tgz#f92099ba7245e49729d2433157031a6267afcc98" + integrity sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA== + dependencies: + "@react-dnd/asap" "^4.0.0" + "@react-dnd/invariant" "^2.0.0" + redux "^4.0.4" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -6219,9 +6243,10 @@ electron-updater@^4.2.5: pako "^1.0.11" semver "^7.1.3" -electron@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/electron/-/electron-8.0.2.tgz#8dfd62fd42529fed94040b643660f2a82b4f8e95" +electron@8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/electron/-/electron-8.2.4.tgz#c4e51ca8e84b5a5beaaabdae1024bd52ba487ba4" + integrity sha512-Lle0InIgSAHZxD5KDY0wZ1A2Zlc6GHwMhAxoHMzn05mndyP1YBkCYHc0TDDofzUTrsLFofduPjlknO5Oj9fTPA== dependencies: "@electron/get" "^1.0.1" "@types/node" "^12.0.12" @@ -13415,6 +13440,23 @@ react-delay-input@^4.1.0: lodash.debounce "^4" prop-types "^15" +react-dnd-html5-backend@^11.1.3: + version "11.1.3" + resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz#2749f04f416ec230ea193f5c1fbea2de7dffb8f7" + integrity sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw== + dependencies: + dnd-core "^11.1.3" + +react-dnd@^11.1.3: + version "11.1.3" + resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-11.1.3.tgz#f9844f5699ccc55dfc81462c2c19f726e670c1af" + integrity sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ== + dependencies: + "@react-dnd/shallowequal" "^2.0.0" + "@types/hoist-non-react-statics" "^3.3.1" + dnd-core "^11.1.3" + hoist-non-react-statics "^3.3.0" + react-dom@^16.12.0, react-dom@^16.2.0, react-dom@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" @@ -13853,7 +13895,7 @@ redux@^3.0.4, redux@^3.6.0: loose-envify "^1.1.0" symbol-observable "^1.0.3" -redux@^4.0.0, redux@^4.0.5: +redux@^4.0.0, redux@^4.0.4, redux@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" dependencies: