UBERF-6946 Highlight file drop area in drive (#5895)

Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
Alexander Onnikov 2024-06-21 23:24:20 +07:00 committed by GitHub
parent 649c16fe13
commit 631de6038e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 111 additions and 31 deletions

View File

@ -14,7 +14,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import core, { type Blob } from '@hcengineering/core' import core, { type Blob } from '@hcengineering/core'
import drive, { type File } from '@hcengineering/drive' import { type File } from '@hcengineering/drive'
import { FilePreview, createQuery } from '@hcengineering/presentation' import { FilePreview, createQuery } from '@hcengineering/presentation'
import { createEventDispatcher, onMount } from 'svelte' import { createEventDispatcher, onMount } from 'svelte'

View File

@ -0,0 +1,104 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { type Ref } from '@hcengineering/core'
import { type Drive, type Folder } from '@hcengineering/drive'
import { createFiles } from '../utils'
export let space: Ref<Drive>
export let parent: Ref<Folder>
export let canDrop: ((e: DragEvent) => boolean) | undefined = undefined
let dragover = false
let counter = 0
async function handleDragEnter (): Promise<void> {
counter++
}
async function handleDragLeave (): Promise<void> {
if (counter > 0) {
counter--
}
if (counter === 0) {
dragover = false
}
}
async function handleDragOver (e: DragEvent): Promise<void> {
if (canDrop !== undefined && !canDrop(e)) {
return
}
e.preventDefault()
e.stopPropagation()
dragover = true
}
async function handleDrop (e: DragEvent): Promise<void> {
counter = 0
dragover = false
if (canDrop !== undefined && !canDrop(e)) {
return
}
e.preventDefault()
e.stopPropagation()
// progress = true
const list = e.dataTransfer?.files
if (list !== undefined && list.length !== 0) {
await createFiles(list, space, parent)
}
// progress = false
}
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="dropzone h-full"
on:dragenter={handleDragEnter}
on:dragleave={handleDragLeave}
on:dragover|preventDefault={handleDragOver}
on:drop={handleDrop}
>
{#if dragover}
<div class="dropzone-overlay" />
{/if}
<slot />
</div>
<style lang="scss">
.dropzone {
position: relative;
}
.dropzone-overlay {
pointer-events: none;
z-index: 1;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: var(--primary-button-transparent);
border: 2px dashed var(--primary-button-outline);
}
</style>

View File

@ -15,8 +15,8 @@
<script lang="ts"> <script lang="ts">
import { type Doc, type DocumentQuery, type Ref, type WithLookup } from '@hcengineering/core' import { type Doc, type DocumentQuery, type Ref, type WithLookup } from '@hcengineering/core'
import drive, { type Drive, type Folder } from '@hcengineering/drive' import drive, { type Drive, type Folder } from '@hcengineering/drive'
import { Viewlet, ViewOptions } from '@hcengineering/view'
import { Scroller, SearchEdit } from '@hcengineering/ui' import { Scroller, SearchEdit } from '@hcengineering/ui'
import { Viewlet, ViewOptions } from '@hcengineering/view'
import { import {
FilterBar, FilterBar,
FilterButton, FilterButton,
@ -25,7 +25,7 @@
ViewletSettingButton ViewletSettingButton
} from '@hcengineering/view-resources' } from '@hcengineering/view-resources'
import { createFiles } from '../utils' import FileDropArea from './FileDropArea.svelte'
export let space: Ref<Drive> export let space: Ref<Drive>
export let parent: Ref<Folder> export let parent: Ref<Folder>
@ -35,8 +35,6 @@
$: query = { space, parent } $: query = { space, parent }
let dragover = false
let viewlet: WithLookup<Viewlet> | undefined = undefined let viewlet: WithLookup<Viewlet> | undefined = undefined
let viewOptions: ViewOptions | undefined let viewOptions: ViewOptions | undefined
@ -50,35 +48,11 @@
function updateSearchQuery (search: string): void { function updateSearchQuery (search: string): void {
searchQuery = search === '' ? { ...query } : { ...query, $search: search } searchQuery = search === '' ? { ...query } : { ...query, $search: search }
} }
async function handleDrop (e: DragEvent): Promise<void> {
if (readonly) {
return
}
// progress = true
const list = e.dataTransfer?.files
if (list !== undefined && list.length !== 0) {
await createFiles(list, space, parent)
}
// progress = false
}
</script> </script>
{#if space !== undefined} {#if space !== undefined}
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div <div class="antiComponent">
class="antiComponent"
class:solid={dragover}
on:dragover|preventDefault={() => {
dragover = true
}}
on:dragleave={() => {
dragover = false
}}
on:drop|preventDefault|stopPropagation={(ev) => {
void handleDrop(ev)
}}
>
<div class="ac-header full divide caption-height"> <div class="ac-header full divide caption-height">
<div class="ac-header-full small-gap"> <div class="ac-header-full small-gap">
<SearchEdit bind:value={search} on:change={() => {}} /> <SearchEdit bind:value={search} on:change={() => {}} />
@ -96,7 +70,9 @@
<div class="popupPanel rowContent" on:contextmenu> <div class="popupPanel rowContent" on:contextmenu>
{#if viewlet} {#if viewlet}
<Scroller horizontal={true}> <Scroller horizontal={true}>
<ViewletContentView {_class} {viewlet} query={resultQuery} {space} {viewOptions} /> <FileDropArea {space} {parent} canDrop={() => !readonly}>
<ViewletContentView {_class} {viewlet} query={resultQuery} {space} {viewOptions} />
</FileDropArea>
</Scroller> </Scroller>
{/if} {/if}
</div> </div>