mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-06 02:33:48 +00:00
finish file request
This commit is contained in:
@@ -4,15 +4,16 @@
|
||||
<NavigationBar />
|
||||
|
||||
<div class="flex items-center">
|
||||
|
||||
<!--I am Done-->
|
||||
<div class="bg-theme-200 mr-6 flex cursor-pointer items-center rounded-lg py-1 pr-1 pl-4">
|
||||
<b @click="uploadingDone" class="text-theme mr-3 text-xs">
|
||||
{{ isDone ? $t('Awesome!') : $t('Tell Jane you are done!') }}
|
||||
{{ $t('Tell Jane you are done!') }}
|
||||
</b>
|
||||
<img
|
||||
class="w-8 rounded-lg"
|
||||
src="http://192.168.1.112:8000/avatars/md-f45abbe5-962c-4229-aef2-9991e96d54d9.png"
|
||||
alt="Avatar"
|
||||
/>
|
||||
<MemberAvatar
|
||||
:member="uploadRequest.data.relationships.user"
|
||||
:size="34"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--Create button-->
|
||||
@@ -89,6 +90,7 @@ import PopoverItem from '../Desktop/PopoverItem'
|
||||
import UploadProgress from './UploadProgress'
|
||||
import NavigationBar from './NavigationBar'
|
||||
import ToolbarButton from './ToolbarButton'
|
||||
import MemberAvatar from "./MemberAvatar"
|
||||
import OptionUpload from './OptionUpload'
|
||||
import OptionGroup from './OptionGroup'
|
||||
import SearchBar from './SearchBar'
|
||||
@@ -104,6 +106,7 @@ export default {
|
||||
PopoverWrapper,
|
||||
NavigationBar,
|
||||
ToolbarButton,
|
||||
MemberAvatar,
|
||||
OptionUpload,
|
||||
OptionGroup,
|
||||
PopoverItem,
|
||||
@@ -111,30 +114,22 @@ export default {
|
||||
Option,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard']),
|
||||
canEdit() {
|
||||
return this.sharedDetail && this.sharedDetail.data.attributes.permission === 'editor'
|
||||
},
|
||||
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard', 'uploadRequest']),
|
||||
canManipulate() {
|
||||
return this.clipboard[0]
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDone: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
uploadingDone() {
|
||||
// TODO: add name to the message
|
||||
if (!this.isDone) {
|
||||
events.$emit('toaster', {
|
||||
type: 'success',
|
||||
message: this.$t('We notified Jane about your new uploads successfully.'),
|
||||
})
|
||||
}
|
||||
|
||||
this.isDone = true
|
||||
events.$emit('confirm:open', {
|
||||
title: this.$t('Are you sure you uploaded all files you want for {name}?', {name: this.uploadRequest.relationships.user.data.attributes.name}),
|
||||
message: this.$t("You won't be able to upload any files here once again."),
|
||||
action: {
|
||||
id: this.$router.currentRoute.params.token,
|
||||
operation: 'close-upload-request',
|
||||
},
|
||||
})
|
||||
},
|
||||
showCreateMenu() {
|
||||
events.$emit('popover:open', 'desktop-create')
|
||||
|
||||
2
resources/js/store/modules/fileFunctions.js
vendored
2
resources/js/store/modules/fileFunctions.js
vendored
@@ -146,7 +146,7 @@ const actions = {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Get route
|
||||
let route = {
|
||||
RequestUpload: `/api/upload-request/${router.currentRoute.params.token}`,
|
||||
RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/upload`,
|
||||
Public: `/api/editor/upload/${router.currentRoute.params.token}`,
|
||||
}[router.currentRoute.name] || '/api/upload'
|
||||
|
||||
|
||||
12
resources/js/store/modules/uploadRequest.js
vendored
12
resources/js/store/modules/uploadRequest.js
vendored
@@ -9,8 +9,7 @@ const defaultState = {
|
||||
}
|
||||
|
||||
const actions = {
|
||||
getUploadRequestDetail: ({ commit, getters }) => {
|
||||
|
||||
getUploadRequestDetail: ({ commit }) => {
|
||||
axios.get(`/api/upload-request/${router.currentRoute.params.token}`)
|
||||
.then((response) => {
|
||||
|
||||
@@ -24,6 +23,15 @@ const actions = {
|
||||
}
|
||||
})
|
||||
},
|
||||
closeUploadRequest: ({ commit }) => {
|
||||
axios
|
||||
.delete(`/api/upload-request/${router.currentRoute.params.token}`)
|
||||
.then((response) => {
|
||||
commit('LOADING_STATE', { loading: false, data: [] })
|
||||
commit('SET_UPLOAD_REQUEST', response.data)
|
||||
})
|
||||
.catch(() => this.$isSomethingWrong())
|
||||
},
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
|
||||
@@ -15,29 +15,29 @@
|
||||
</OptionGroup>
|
||||
<OptionGroup :title="$t('Create')">
|
||||
<Option
|
||||
@click.stop.native="createFolder"
|
||||
:title="$t('actions.create_folder')"
|
||||
icon="folder-plus"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
@click.stop.native="createFolder"
|
||||
:title="$t('actions.create_folder')"
|
||||
icon="folder-plus"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
</MobileCreateMenu>
|
||||
|
||||
<MobileMultiSelectToolbar>
|
||||
<ToolbarButton
|
||||
@click.native="$moveFileOrFolder(clipboard)"
|
||||
class="action-btn"
|
||||
source="move"
|
||||
:action="$t('actions.move')"
|
||||
:class="{ 'is-inactive': clipboard.length < 1 }"
|
||||
/>
|
||||
@click.native="$moveFileOrFolder(clipboard)"
|
||||
class="action-btn"
|
||||
source="move"
|
||||
:action="$t('actions.move')"
|
||||
:class="{ 'is-inactive': clipboard.length < 1 }"
|
||||
/>
|
||||
<ToolbarButton
|
||||
@click.native="$deleteFileOrFolder(clipboard)"
|
||||
class="action-btn"
|
||||
source="trash"
|
||||
:class="{ 'is-inactive': clipboard.length < 1 }"
|
||||
:action="$t('actions.delete')"
|
||||
/>
|
||||
@click.native="$deleteFileOrFolder(clipboard)"
|
||||
class="action-btn"
|
||||
source="trash"
|
||||
:class="{ 'is-inactive': clipboard.length < 1 }"
|
||||
:action="$t('actions.delete')"
|
||||
/>
|
||||
</MobileMultiSelectToolbar>
|
||||
|
||||
<ContextMenu v-if="entries.length">
|
||||
@@ -48,20 +48,20 @@
|
||||
</OptionGroup>
|
||||
<OptionGroup>
|
||||
<Option
|
||||
@click.native="$createFolder"
|
||||
:title="$t('context_menu.create_folder')"
|
||||
icon="create-folder"
|
||||
/>
|
||||
@click.native="$createFolder"
|
||||
:title="$t('context_menu.create_folder')"
|
||||
icon="create-folder"
|
||||
/>
|
||||
</OptionGroup>
|
||||
</template>
|
||||
|
||||
<template v-slot:single-select v-if="item">
|
||||
<OptionGroup>
|
||||
<Option
|
||||
@click.native="$renameFileOrFolder(item)"
|
||||
:title="$t('context_menu.rename')"
|
||||
icon="rename"
|
||||
/>
|
||||
@click.native="$renameFileOrFolder(item)"
|
||||
:title="$t('context_menu.rename')"
|
||||
icon="rename"
|
||||
/>
|
||||
<Option @click.native="$moveFileOrFolder(item)" :title="$t('context_menu.move')" icon="move-item" />
|
||||
<Option @click.native="$deleteFileOrFolder(item)" :title="$t('context_menu.delete')" icon="trash" />
|
||||
</OptionGroup>
|
||||
@@ -86,10 +86,10 @@
|
||||
{{ $t('Spotlight') }}
|
||||
</MobileActionButton>
|
||||
<MobileActionButton
|
||||
@click.native="$showMobileMenu('create-list')"
|
||||
v-if="$checkPermission(['master', 'editor'])"
|
||||
icon="cloud-plus"
|
||||
>
|
||||
@click.native="$showMobileMenu('create-list')"
|
||||
v-if="$checkPermission(['master', 'editor'])"
|
||||
icon="cloud-plus"
|
||||
>
|
||||
{{ $t('mobile.create') }}
|
||||
</MobileActionButton>
|
||||
<MobileActionButton @click.native="$enableMultiSelectMode" icon="check-square">
|
||||
@@ -100,28 +100,26 @@
|
||||
</MobileActionButton>
|
||||
</FileActionsMobile>
|
||||
|
||||
<EmptyFilePage>
|
||||
<div v-if="uploadRequest" class="relative mx-auto mb-8 w-24 text-center">
|
||||
<EmptyFilePage v-if="uploadRequest">
|
||||
<div class="relative mx-auto mb-8 w-24 text-center">
|
||||
<VueFolderIcon class="inline-block w-28" />
|
||||
<MemberAvatar
|
||||
:member="uploadRequest.data.relationships.user"
|
||||
class="absolute -bottom-2.5 -right-2"
|
||||
:is-border="true"
|
||||
:size="32"
|
||||
/>
|
||||
v-if="uploadRequest.data.attributes.status !== 'expired'"
|
||||
:member="uploadRequest.data.relationships.user"
|
||||
class="absolute -bottom-2.5 -right-2"
|
||||
:is-border="true"
|
||||
:size="32"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h1 class="title">
|
||||
{{ $t('Jane Request You for File Upload') }}
|
||||
{{ emptyPageTitle }}
|
||||
</h1>
|
||||
<p class="description max-w-[420px]">
|
||||
{{
|
||||
$t(
|
||||
'Your files will be uploaded automatically and after that, you can organize your files in folders.'
|
||||
)
|
||||
}}
|
||||
{{ emptyPageDescription }}
|
||||
</p>
|
||||
<ButtonUpload button-style="theme">
|
||||
|
||||
<ButtonUpload v-if="uploadRequest.data.attributes.status === 'active'" button-style="theme">
|
||||
{{ $t('empty_page.call_to_action') }}
|
||||
</ButtonUpload>
|
||||
</EmptyFilePage>
|
||||
@@ -146,51 +144,65 @@ import FileBrowser from '../../components/FilesView/FileBrowser'
|
||||
import ContextMenu from '../../components/FilesView/ContextMenu'
|
||||
import OptionGroup from '../../components/FilesView/OptionGroup'
|
||||
import Option from '../../components/FilesView/Option'
|
||||
import { events } from '../../bus'
|
||||
import { mapGetters } from 'vuex'
|
||||
import {events} from '../../bus'
|
||||
import {mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Files',
|
||||
components: {
|
||||
MobileMultiSelectToolbar,
|
||||
MobileActionButton,
|
||||
FileActionsMobile,
|
||||
MobileContextMenu,
|
||||
MobileCreateMenu,
|
||||
EmptyFilePage,
|
||||
VueFolderIcon,
|
||||
ToolbarButton,
|
||||
MemberAvatar,
|
||||
ButtonUpload,
|
||||
OptionUpload,
|
||||
OptionGroup,
|
||||
FileBrowser,
|
||||
ContextMenu,
|
||||
Option,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['fastPreview', 'clipboard', 'config', 'user', 'entries', 'uploadRequest']),
|
||||
isFolder() {
|
||||
return this.item && this.item.data.type === 'folder'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
item: undefined,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createFolder() {
|
||||
events.$emit('popup:open', { name: 'create-folder' })
|
||||
},
|
||||
},
|
||||
created() {
|
||||
name: 'Files',
|
||||
components: {
|
||||
MobileMultiSelectToolbar,
|
||||
MobileActionButton,
|
||||
FileActionsMobile,
|
||||
MobileContextMenu,
|
||||
MobileCreateMenu,
|
||||
EmptyFilePage,
|
||||
VueFolderIcon,
|
||||
ToolbarButton,
|
||||
MemberAvatar,
|
||||
ButtonUpload,
|
||||
OptionUpload,
|
||||
OptionGroup,
|
||||
FileBrowser,
|
||||
ContextMenu,
|
||||
Option,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['fastPreview', 'clipboard', 'config', 'user', 'entries', 'uploadRequest']),
|
||||
isFolder() {
|
||||
return this.item && this.item.data.type === 'folder'
|
||||
},
|
||||
emptyPageTitle() {
|
||||
// Todo: add name into translation
|
||||
return {
|
||||
active: this.$t('Jane Request You for File Upload'),
|
||||
filled: this.$t('Upload Request was Fulfilled Successfully'),
|
||||
expired: this.$t('Upload Request Expired'),
|
||||
}[this.uploadRequest.data.attributes.status]
|
||||
},
|
||||
emptyPageDescription() {
|
||||
return {
|
||||
active: this.$t('Your files will be uploaded automatically and after that, you can organize your files in folders.'),
|
||||
filled: this.$t('This upload request is no longer available for uploading files.'),
|
||||
expired: this.$t('This upload request is no longer available for uploading files.'),
|
||||
}[this.uploadRequest.data.attributes.status]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
item: undefined,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createFolder() {
|
||||
events.$emit('popup:open', {name: 'create-folder'})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
events.$on('context-menu:show', (event, item) => (this.item = item))
|
||||
events.$on('context-menu:current-folder', (folder) => (this.item = folder))
|
||||
events.$on('mobile-context-menu:show', (item) => (this.item = item))
|
||||
|
||||
this.$store.dispatch('getUploadRequestDetail')
|
||||
|
||||
},
|
||||
this.$store.dispatch('getUploadRequestDetail')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<FilePreview />
|
||||
<Spotlight />
|
||||
|
||||
<ConfirmPopup />
|
||||
|
||||
<!--Popups-->
|
||||
<CreateFolderPopup />
|
||||
<RenameItemPopup />
|
||||
@@ -42,6 +44,7 @@ import FileSortingMobile from '../components/FilesView/FileSortingMobile'
|
||||
import FileFilterMobile from '../components/FilesView/FileFilterMobile'
|
||||
import CreateFolderPopup from '../components/Others/CreateFolderPopup'
|
||||
import DesktopToolbar from '../components/FilesView/DesktopToolbar'
|
||||
import ConfirmPopup from "../components/Others/Popup/ConfirmPopup"
|
||||
import RenameItemPopup from '../components/Others/RenameItemPopup'
|
||||
import MobileToolbar from '../components/FilesView/MobileToolbar'
|
||||
import FilePreview from '../components/FilePreview/FilePreview'
|
||||
@@ -55,6 +58,7 @@ import { events } from '../bus'
|
||||
export default {
|
||||
name: 'UploadRequest',
|
||||
components: {
|
||||
ConfirmPopup,
|
||||
DesktopUploadRequestToolbar,
|
||||
CreateFolderPopup,
|
||||
FileSortingMobile,
|
||||
@@ -85,6 +89,11 @@ export default {
|
||||
// TODO: new scaledown effect
|
||||
events.$on('mobile-menu:show', () => (this.isScaledDown = true))
|
||||
events.$on('mobile-menu:hide', () => (this.isScaledDown = false))
|
||||
|
||||
events.$on('action:confirmed', (data) => {
|
||||
if (data.operation === 'close-upload-request')
|
||||
this.$store.dispatch('closeUploadRequest')
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
use Domain\UploadRequest\Controllers\GetUploadRequestController;
|
||||
use Domain\UploadRequest\Controllers\CreateUploadRequestController;
|
||||
use Domain\UploadRequest\Controllers\SetUploadRequestAsFilledController;
|
||||
use Domain\UploadRequest\Controllers\UploadFilesForUploadRequestController;
|
||||
|
||||
Route::get('/{uploadRequest}', GetUploadRequestController::class);
|
||||
Route::post('/{uploadRequest}', UploadFilesForUploadRequestController::class);
|
||||
Route::delete('/{uploadRequest}', SetUploadRequestAsFilledController::class);
|
||||
Route::post('/{uploadRequest}/upload', UploadFilesForUploadRequestController::class);
|
||||
|
||||
Route::group(['middleware' => ['auth:sanctum']], function () {
|
||||
Route::post('/', CreateUploadRequestController::class);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Domain\UploadRequest\Controllers;
|
||||
|
||||
use Domain\UploadRequest\Models\UploadRequest;
|
||||
use Domain\UploadRequest\Resources\UploadRequestResource;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class SetUploadRequestAsFilledController
|
||||
{
|
||||
public function __invoke(UploadRequest $uploadRequest): Response|Application|ResponseFactory
|
||||
{
|
||||
$uploadRequest->update([
|
||||
'status' => 'filled',
|
||||
]);
|
||||
|
||||
return response(new UploadRequestResource($uploadRequest), 201);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class UploadRequestResource extends JsonResource
|
||||
'id' => $this->user->id,
|
||||
'type' => 'user',
|
||||
'attributes' => [
|
||||
'name' => $this->user->settings->name,
|
||||
'name' => $this->user->settings->first_name,
|
||||
'avatar' => $this->user->settings->avatar,
|
||||
],
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Domain\UploadRequest;
|
||||
|
||||
use Storage;
|
||||
@@ -118,7 +119,7 @@ class UploadRequestTest extends TestCase
|
||||
->create('fake-file.pdf', 12000000, 'application/pdf');
|
||||
|
||||
$this
|
||||
->postJson("/api/upload-request/$uploadRequest->id", [
|
||||
->postJson("/api/upload-request/$uploadRequest->id/upload", [
|
||||
'filename' => $file->name,
|
||||
'file' => $file,
|
||||
'parent_id' => null,
|
||||
@@ -159,7 +160,7 @@ class UploadRequestTest extends TestCase
|
||||
->create('fake-file.pdf', 12000000, 'application/pdf');
|
||||
|
||||
$this
|
||||
->postJson("/api/upload-request/$uploadRequest->id", [
|
||||
->postJson("/api/upload-request/$uploadRequest->id/upload", [
|
||||
'filename' => $file->name,
|
||||
'file' => $file,
|
||||
'parent_id' => null,
|
||||
@@ -167,4 +168,28 @@ class UploadRequestTest extends TestCase
|
||||
'is_last' => 'true',
|
||||
])->assertStatus(410);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_mark_upload_request_as_filled()
|
||||
{
|
||||
$user = User::factory()
|
||||
->hasSettings()
|
||||
->create();
|
||||
|
||||
$uploadRequest = UploadRequest::factory()
|
||||
->create([
|
||||
'status' => 'active',
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this
|
||||
->deleteJson("/api/upload-request/$uploadRequest->id")
|
||||
->assertStatus(201)
|
||||
->assertJsonFragment([
|
||||
'id' => $uploadRequest->id,
|
||||
'status' => 'filled',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user