Skip to content

Commit 3d23447

Browse files
committed
Dragging file to asset selector's footer should upload it
1 parent 6abb6d6 commit 3d23447

3 files changed

Lines changed: 106 additions & 68 deletions

File tree

resources/js/components/assets/Browser/Browser.vue

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<template>
22
<div ref="browser" class="h-full" @keydown.shift="shiftDown" @keyup="clearShift">
33
<Uploader
4-
ref="uploader"
4+
ref="internalUploader"
55
:container="container.id"
66
:path="path"
7-
:enabled="!preventDragging && canUpload"
7+
:enabled="!uploader && !preventDragging && canUpload"
88
@updated="uploadsUpdated"
99
@upload-complete="uploadCompleted"
1010
@error="uploadError"
@@ -272,6 +272,10 @@ export default {
272272
type: Array,
273273
default: () => [],
274274
},
275+
uploader: {
276+
type: Object,
277+
default: null,
278+
},
275279
},
276280
277281
setup() {
@@ -476,8 +480,9 @@ export default {
476480
this.loadAssets();
477481
},
478482
479-
path() {
483+
path(path) {
480484
this.loadAssets();
485+
this.$emit('path-changed', path);
481486
},
482487
483488
searchQuery() {
@@ -676,7 +681,7 @@ export default {
676681
},
677682
678683
openFileBrowser() {
679-
this.$refs.uploader.browse();
684+
(this.uploader || this.$refs.internalUploader).browse();
680685
},
681686
682687
selectFolder(path) {

resources/js/components/assets/Selector.vue

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,95 @@
11
<template>
2-
<div class="h-full">
3-
<div class="flex h-full min-h-0 flex-col">
4-
<div class="flex flex-1 flex-col gap-4 overflow-auto p-4">
5-
<AssetBrowser
6-
:container="container"
7-
:initial-per-page="$config.get('paginationSize')"
8-
:initial-columns="columns"
9-
:selected-path="folder"
10-
:selected-assets="browserSelections"
11-
:restrict-folder-navigation="restrictFolderNavigation"
12-
:max-files="maxFiles"
13-
:query-scopes="queryScopes"
14-
:autoselect-uploads="true"
15-
allow-selecting-existing-upload
16-
:allow-bulk-actions="false"
17-
@selections-updated="selectionsUpdated"
18-
@edit-asset="toggleAssetSelection"
19-
@initialized="focusSearchInput"
20-
>
21-
<template #initializing>
22-
<div class="flex flex-1">
23-
<div class="absolute inset-0 z-200 flex items-center justify-center text-center">
24-
<Icon name="loading" />
25-
</div>
26-
</div>
27-
</template>
2+
<Uploader
3+
ref="uploader"
4+
:container="container.id"
5+
:path="currentPath"
6+
:enabled="container.can_upload"
7+
@updated="(uploads) => $refs.browser?.uploadsUpdated(uploads)"
8+
@upload-complete="(asset) => $refs.browser?.uploadCompleted(asset)"
9+
@error="(upload, uploads) => $refs.browser?.uploadError(upload, uploads)"
10+
v-slot="{ dragging }"
11+
>
12+
<div class="relative h-full">
13+
<div class="drag-notification" v-show="dragging">
14+
<Icon name="upload-cloud-large" class="m-4 size-13" />
15+
<span>{{ __('Drop File to Upload') }}</span>
16+
</div>
2817

29-
<template #header="{ canUpload, openFileBrowser, canCreateFolders, startCreatingFolder, mode, modeChanged }">
30-
<div class="flex items-center gap-2 sm:gap-3 mb-4">
31-
<div class="flex flex-1 items-center gap-2 sm:gap-3">
32-
<Search ref="search" />
18+
<div class="flex h-full min-h-0 flex-col">
19+
<div class="flex flex-1 flex-col gap-4 overflow-auto p-4">
20+
<AssetBrowser
21+
ref="browser"
22+
:container="container"
23+
:initial-per-page="$config.get('paginationSize')"
24+
:initial-columns="columns"
25+
:selected-path="folder"
26+
:selected-assets="browserSelections"
27+
:restrict-folder-navigation="restrictFolderNavigation"
28+
:max-files="maxFiles"
29+
:query-scopes="queryScopes"
30+
:autoselect-uploads="true"
31+
:uploader="uploaderInstance"
32+
allow-selecting-existing-upload
33+
:allow-bulk-actions="false"
34+
@selections-updated="selectionsUpdated"
35+
@edit-asset="toggleAssetSelection"
36+
@initialized="focusSearchInput"
37+
@path-changed="currentPath = $event"
38+
>
39+
<template #initializing>
40+
<div class="flex flex-1">
41+
<div class="absolute inset-0 z-200 flex items-center justify-center text-center">
42+
<Icon name="loading" />
43+
</div>
3344
</div>
45+
</template>
3446

35-
<Button v-if="canUpload" :text="__('Upload')" icon="upload" @click="openFileBrowser" />
36-
<Button v-if="canCreateFolders" :text="__('Create Folder')" icon="folder-add" @click="startCreatingFolder" />
47+
<template #header="{ canUpload, openFileBrowser, canCreateFolders, startCreatingFolder, mode, modeChanged }">
48+
<div class="flex items-center gap-2 sm:gap-3 mb-4">
49+
<div class="flex flex-1 items-center gap-2 sm:gap-3">
50+
<Search ref="search" />
51+
</div>
3752

38-
<ToggleGroup :model-value="mode" @update:model-value="modeChanged">
39-
<ToggleItem icon="layout-grid" value="grid" />
40-
<ToggleItem icon="layout-list" value="table" />
41-
</ToggleGroup>
42-
</div>
43-
</template>
44-
</AssetBrowser>
45-
</div>
53+
<Button v-if="canUpload" :text="__('Upload')" icon="upload" @click="openFileBrowser" />
54+
<Button v-if="canCreateFolders" :text="__('Create Folder')" icon="folder-add" @click="startCreatingFolder" />
55+
56+
<ToggleGroup :model-value="mode" @update:model-value="modeChanged">
57+
<ToggleItem icon="layout-grid" value="grid" />
58+
<ToggleItem icon="layout-list" value="table" />
59+
</ToggleGroup>
60+
</div>
61+
</template>
62+
</AssetBrowser>
63+
</div>
4664

47-
<div class="flex items-center justify-between border-t bg-gray-100 dark:bg-gray-850 dark:border-gray-700 px-4 py-2 sm:p-4">
48-
<div
49-
class="dark:text-gray-200 text-sm text-gray-700"
50-
v-text="
51-
hasMaxFiles
52-
? __n(':count/:max selected', browserSelections, { max: maxFiles })
53-
: __n(':count asset selected|:count assets selected', browserSelections)
54-
"
55-
/>
56-
57-
<div class="flex items-center space-x-3">
58-
<Button variant="ghost" @click="close">
59-
{{ __('Cancel') }}
60-
</Button>
61-
62-
<Button variant="primary" @click="select">
63-
{{ __('Select') }}
64-
</Button>
65+
<div class="flex items-center justify-between border-t bg-gray-100 dark:bg-gray-850 dark:border-gray-700 px-4 py-2 sm:p-4">
66+
<div
67+
class="dark:text-gray-200 text-sm text-gray-700"
68+
v-text="
69+
hasMaxFiles
70+
? __n(':count/:max selected', browserSelections, { max: maxFiles })
71+
: __n(':count asset selected|:count assets selected', browserSelections)
72+
"
73+
/>
74+
75+
<div class="flex items-center space-x-3">
76+
<Button variant="ghost" @click="close">
77+
{{ __('Cancel') }}
78+
</Button>
79+
80+
<Button variant="primary" @click="select">
81+
{{ __('Select') }}
82+
</Button>
83+
</div>
6584
</div>
6685
</div>
6786
</div>
68-
</div>
87+
</Uploader>
6988
</template>
7089

7190
<script>
7291
import AssetBrowser from './Browser/Browser.vue'
92+
import Uploader from './Uploader.vue'
7393
import {
7494
Button,
7595
ToggleGroup,
@@ -92,6 +112,7 @@ export default {
92112
93113
components: {
94114
Uploads,
115+
Uploader,
95116
PanelHeader, Grid,
96117
Slider,
97118
ListingPagination, Breadcrumbs,
@@ -128,9 +149,15 @@ export default {
128149
// We only want selection changes to be reflected in the fieldtype once the user is ready to commit
129150
// them. They should be able to cancel at any time and have their updated selections discarded.
130151
browserSelections: this.selected,
152+
currentPath: this.folder,
153+
uploaderInstance: null,
131154
};
132155
},
133156
157+
mounted() {
158+
this.uploaderInstance = this.$refs.uploader;
159+
},
160+
134161
computed: {
135162
hasMaxFiles() {
136163
return this.maxFiles === Infinity ? false : Boolean(this.maxFiles);

resources/js/components/assets/Uploader.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@ export default {
1414
ref: 'nativeFileField',
1515
});
1616
17+
const events = this.enabled
18+
? {
19+
onDragenter: this.dragenter,
20+
onDragover: this.dragover,
21+
onDragleave: this.dragleave,
22+
onDrop: this.drop,
23+
}
24+
: {};
25+
1726
return h(
1827
'div',
1928
{
2029
class: 'h-full',
21-
onDragenter: this.dragenter,
22-
onDragover: this.dragover,
23-
onDragleave: this.dragleave,
24-
onDrop: this.drop,
30+
...events,
2531
},
2632
[
27-
h('div', { class: { 'pointer-events-none': this.dragging } }, [
33+
h('div', { class: ['h-full', { 'pointer-events-none': this.dragging }] }, [
2834
fileField,
2935
...this.$slots.default({ dragging: this.enabled ? this.dragging : false }),
3036
]),

0 commit comments

Comments
 (0)