Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ interface ContentManagerDocRowProps {
currentUserIsCoreMember: boolean
onSelect: (val: boolean) => void
setUpdating: React.Dispatch<React.SetStateAction<string[]>>
onDragStart: (event: any, doc: SerializedDocWithBookmark) => void
onDragEnd: (event: any) => void
onDrop: (event: any, doc: SerializedDocWithBookmark) => void
}

const ContentManagerDocRow = ({
Expand All @@ -43,6 +46,9 @@ const ContentManagerDocRow = ({
showPath,
currentUserIsCoreMember,
onSelect,
onDragStart,
onDragEnd,
onDrop,
}: ContentManagerDocRowProps) => {
const { permissions = [] } = usePage()
const { push } = useRouter()
Expand Down Expand Up @@ -165,6 +171,9 @@ const ContentManagerDocRow = ({
labelOnclick={() => push(href)}
defaultIcon={mdiFileDocumentOutline}
emoji={doc.emoji}
onDragStart={(event: any) => onDragStart(event, doc)}
onDragEnd={(event: any) => onDragEnd(event)}
onDrop={(event: any) => onDrop(event, doc)}
>
<ContentManagerCell fullWidth={true}>
<DocAssigneeSelect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useNav } from '../../../../lib/stores/nav'
import { useTranslation } from 'react-i18next'
import { lngKeys } from '../../../../lib/i18n/types'
import { useRouter } from '../../../../lib/router'

interface ContentManagerFolderRowProps {
team: SerializedTeam
folder: SerializedFolderWithBookmark
Expand All @@ -16,6 +17,9 @@ interface ContentManagerFolderRowProps {
checked?: boolean
onSelect: (val: boolean) => void
currentUserIsCoreMember: boolean
onDragStart: (event: any, folder: SerializedFolderWithBookmark) => void
onDragEnd: (event: any) => void
onDrop: (event: any, folder: SerializedFolderWithBookmark) => void
}

const ContentmanagerFolderRow = ({
Expand All @@ -24,6 +28,9 @@ const ContentmanagerFolderRow = ({
checked,
currentUserIsCoreMember,
onSelect,
onDragStart,
onDragEnd,
onDrop,
}: ContentManagerFolderRowProps) => {
const { t } = useTranslation()
const { docsMap, foldersMap } = useNav()
Expand Down Expand Up @@ -51,6 +58,9 @@ const ContentmanagerFolderRow = ({
emoji={folder.emoji}
labelHref={href}
labelOnclick={() => push(href)}
onDragStart={(event: any) => onDragStart(event, folder)}
onDragEnd={(event: any) => onDragEnd(event)}
onDrop={(event: any) => onDrop(event, folder)}
>
<ContentManagerCell>
{childrenFolders} {t(lngKeys.GeneralFolders).toLocaleLowerCase()}{' '}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useCallback } from 'react'
import React, { useCallback, useRef, useState } from 'react'
import cc from 'classcat'
import Checkbox from '../../../atoms/Checkbox'
import styled from '../../../../../shared/lib/styled'
import { AppComponent } from '../../../../../shared/lib/types'
import EmojiIcon from '../../../atoms/EmojiIcon'
import { onDragLeaveCb } from '../../../../../shared/lib/dnd'

interface ContentManagerRowProps {
type?: 'header' | 'row'
Expand All @@ -15,6 +16,9 @@ interface ContentManagerRowProps {
emoji?: string
defaultIcon?: string
showCheckbox: boolean
onDragStart?: (event: any) => void
onDragEnd?: (event: any) => void
onDrop?: (event: any) => void
}

const ContentManagerRow: AppComponent<ContentManagerRowProps> = ({
Expand All @@ -29,6 +33,9 @@ const ContentManagerRow: AppComponent<ContentManagerRowProps> = ({
defaultIcon,
showCheckbox,
onSelect,
onDragStart,
onDragEnd,
onDrop,
}) => {
const LabelTag = labelHref != null || labelOnclick != null ? 'a' : 'div'

Expand All @@ -45,9 +52,46 @@ const ContentManagerRow: AppComponent<ContentManagerRowProps> = ({
[labelOnclick]
)

const [draggedOver, setDraggedOver] = useState(false)
const dragRef = useRef<HTMLDivElement>(null)

return (
<StyledContentManagerRow
className={cc(['cm__row', `cm__row--${type}`, className])}
className={cc([
'cm__row',
`cm__row--${type}`,
className,
draggedOver && 'content__manager__row--draggedOver',
])}
draggable={true}
onDrop={(event: any) => {
event.stopPropagation()
if (onDrop != null) {
onDrop(event)
}
setDraggedOver(false)
}}
onDragStart={(event: any) => {
event.stopPropagation()
if (onDragStart != null) {
onDragStart(event)
}
}}
onDragOver={(event: any) => {
event.preventDefault()
event.stopPropagation()
setDraggedOver(true)
}}
onDragLeave={(event: any) => {
onDragLeaveCb(event, dragRef, () => {
setDraggedOver(false)
})
}}
onDragEnd={(event: any) => {
if (onDragEnd != null) {
onDragEnd(event)
}
}}
>
{showCheckbox && (
<Checkbox
Expand All @@ -56,7 +100,12 @@ const ContentManagerRow: AppComponent<ContentManagerRowProps> = ({
onChange={onSelect}
/>
)}
<LabelTag className='cm__row__label' onClick={navigate} href={labelHref}>
<LabelTag
draggable={true}
className='cm__row__label'
onClick={navigate}
href={labelHref}
>
<div className='cm__row__emoji'>
<EmojiIcon
className='emoji-icon'
Expand Down Expand Up @@ -155,4 +204,8 @@ const StyledContentManagerRow = styled.div`
opacity: 1;
}
}

&.content__manager__row--draggedOver {
background: ${({ theme }) => theme.colors.background.quaternary};
}
`
68 changes: 65 additions & 3 deletions src/cloud/components/molecules/ContentManager/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import React, { useState, useMemo, useCallback, useEffect, useRef } from 'react'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import {
SerializedDocWithBookmark,
DocStatus,
SerializedDocWithBookmark,
} from '../../../interfaces/db/doc'
import { SerializedFolderWithBookmark } from '../../../interfaces/db/folder'
import { useSet } from 'react-use'
import {
sortByAttributeAsc,
sortByAttributeDesc,
} from '../../../lib/utils/array'
import { getDocTitle, getDocId, getFolderId } from '../../../lib/utils/patterns'
import {
docToDataTransferItem,
folderToDataTransferItem,
getDocId,
getDocTitle,
getFolderId,
} from '../../../lib/utils/patterns'
import { SerializedWorkspace } from '../../../interfaces/db/workspace'
import { StyledContentManagerList } from './styled'
import Checkbox from '../../atoms/Checkbox'
Expand All @@ -32,6 +38,8 @@ import ContentManagerCell from './ContentManagerCell'
import Flexbox from '../../../../shared/components/atoms/Flexbox'
import ContentManagerStatusFilter from './ContentManagerStatusFilter'
import VerticalScroller from '../../../../shared/components/atoms/VerticalScroller'
import { useCloudDnd } from '../../../lib/hooks/sidebar/useCloudDnd'
import { DraggedTo } from '../../../../shared/lib/dnd'

export type ContentManagerParent =
| { type: 'folder'; item: SerializedFolderWithBookmark }
Expand Down Expand Up @@ -209,6 +217,54 @@ const ContentManager = ({
[setPreferences]
)

const {
dropInDocOrFolder,
saveFolderTransferData,
saveDocTransferData,
clearDragTransferData,
} = useCloudDnd()

const onDragStartFolder = useCallback(
(event: any, folder: SerializedFolderWithBookmark) => {
saveFolderTransferData(event, folder)
},
[saveFolderTransferData]
)

const onDropFolder = useCallback(
(event, folder: SerializedFolderWithBookmark) =>
dropInDocOrFolder(
event,
{ type: 'folder', resource: folderToDataTransferItem(folder) },
DraggedTo.insideFolder
),
[dropInDocOrFolder]
)

const onDragStartDoc = useCallback(
(event: any, doc: SerializedDocWithBookmark) => {
saveDocTransferData(event, doc)
},
[saveDocTransferData]
)

const onDropDoc = useCallback(
(event: any, doc: SerializedDocWithBookmark) =>
dropInDocOrFolder(
event,
{ type: 'doc', resource: docToDataTransferItem(doc) },
DraggedTo.beforeItem
),
[dropInDocOrFolder]
)

const onDragEnd = useCallback(
(event: any) => {
clearDragTransferData(event)
},
[clearDragTransferData]
)

return (
<Container>
<VerticalScroller className='cm__scroller'>
Expand Down Expand Up @@ -283,6 +339,9 @@ const ContentManager = ({
checked={hasFolder(folder.id)}
onSelect={() => toggleFolder(folder.id)}
currentUserIsCoreMember={currentUserIsCoreMember}
onDrop={onDropFolder}
onDragEnd={onDragEnd}
onDragStart={onDragStartFolder}
/>
))}

Expand Down Expand Up @@ -331,6 +390,9 @@ const ContentManager = ({
onSelect={() => toggleDoc(doc.id)}
showPath={page != null}
currentUserIsCoreMember={currentUserIsCoreMember}
onDrop={onDropDoc}
onDragEnd={onDragEnd}
onDragStart={onDragStartDoc}
/>
))}
{orderedDocs.length === 0 && <EmptyRow label='No Documents' />}
Expand Down
30 changes: 26 additions & 4 deletions src/cloud/interfaces/resources.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
import { SerializedFolderWithBookmark } from './db/folder'
import { SerializedDocWithBookmark } from './db/doc'
export const FOLDER_DRAG_TRANSFER_DATA_JSON =
'application/boostnote.folder+json'
export const DOC_DRAG_TRANSFER_DATA_JSON = 'application/boostnote.doc+json'
export const CATEGORY_DRAG_TRANSFER_DATA_JSON =
'application/boostnote.category+json'

export interface DocDataTransferItem {
workspaceId: string
teamId: string
id: string
emoji?: string
url: string
title: string
}

export interface FolderDataTransferItem {
workspaceId: string
teamId: string
id: string
emoji?: string
url: string
name: string
description?: string
}

export type SerializedFolderNav = {
type: 'folder'
result: SerializedFolderWithBookmark
resource: FolderDataTransferItem
}

export type SerializedDocNav = {
type: 'doc'
result: SerializedDocWithBookmark
resource: DocDataTransferItem
}

export type SerializedPendingNav = {
Expand Down
Loading