finish file request

This commit is contained in:
Čarodej
2022-02-22 09:35:06 +01:00
parent 171ee5fa04
commit c3398f0da4
9 changed files with 185 additions and 113 deletions
@@ -4,14 +4,15 @@
<NavigationBar /> <NavigationBar />
<div class="flex items-center"> <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"> <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"> <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> </b>
<img <MemberAvatar
class="w-8 rounded-lg" :member="uploadRequest.data.relationships.user"
src="http://192.168.1.112:8000/avatars/md-f45abbe5-962c-4229-aef2-9991e96d54d9.png" :size="34"
alt="Avatar"
/> />
</div> </div>
@@ -89,6 +90,7 @@ import PopoverItem from '../Desktop/PopoverItem'
import UploadProgress from './UploadProgress' import UploadProgress from './UploadProgress'
import NavigationBar from './NavigationBar' import NavigationBar from './NavigationBar'
import ToolbarButton from './ToolbarButton' import ToolbarButton from './ToolbarButton'
import MemberAvatar from "./MemberAvatar"
import OptionUpload from './OptionUpload' import OptionUpload from './OptionUpload'
import OptionGroup from './OptionGroup' import OptionGroup from './OptionGroup'
import SearchBar from './SearchBar' import SearchBar from './SearchBar'
@@ -104,6 +106,7 @@ export default {
PopoverWrapper, PopoverWrapper,
NavigationBar, NavigationBar,
ToolbarButton, ToolbarButton,
MemberAvatar,
OptionUpload, OptionUpload,
OptionGroup, OptionGroup,
PopoverItem, PopoverItem,
@@ -111,30 +114,22 @@ export default {
Option, Option,
}, },
computed: { computed: {
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard']), ...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard', 'uploadRequest']),
canEdit() {
return this.sharedDetail && this.sharedDetail.data.attributes.permission === 'editor'
},
canManipulate() { canManipulate() {
return this.clipboard[0] return this.clipboard[0]
}, },
}, },
data() {
return {
isDone: false,
}
},
methods: { methods: {
uploadingDone() { uploadingDone() {
// TODO: add name to the message // TODO: add name to the message
if (!this.isDone) { events.$emit('confirm:open', {
events.$emit('toaster', { title: this.$t('Are you sure you uploaded all files you want for {name}?', {name: this.uploadRequest.relationships.user.data.attributes.name}),
type: 'success', message: this.$t("You won't be able to upload any files here once again."),
message: this.$t('We notified Jane about your new uploads successfully.'), action: {
id: this.$router.currentRoute.params.token,
operation: 'close-upload-request',
},
}) })
}
this.isDone = true
}, },
showCreateMenu() { showCreateMenu() {
events.$emit('popover:open', 'desktop-create') events.$emit('popover:open', 'desktop-create')
+1 -1
View File
@@ -146,7 +146,7 @@ const actions = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Get route // Get route
let 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}`, Public: `/api/editor/upload/${router.currentRoute.params.token}`,
}[router.currentRoute.name] || '/api/upload' }[router.currentRoute.name] || '/api/upload'
+10 -2
View File
@@ -9,8 +9,7 @@ const defaultState = {
} }
const actions = { const actions = {
getUploadRequestDetail: ({ commit, getters }) => { getUploadRequestDetail: ({ commit }) => {
axios.get(`/api/upload-request/${router.currentRoute.params.token}`) axios.get(`/api/upload-request/${router.currentRoute.params.token}`)
.then((response) => { .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 = { const mutations = {
@@ -100,10 +100,11 @@
</MobileActionButton> </MobileActionButton>
</FileActionsMobile> </FileActionsMobile>
<EmptyFilePage> <EmptyFilePage v-if="uploadRequest">
<div v-if="uploadRequest" class="relative mx-auto mb-8 w-24 text-center"> <div class="relative mx-auto mb-8 w-24 text-center">
<VueFolderIcon class="inline-block w-28" /> <VueFolderIcon class="inline-block w-28" />
<MemberAvatar <MemberAvatar
v-if="uploadRequest.data.attributes.status !== 'expired'"
:member="uploadRequest.data.relationships.user" :member="uploadRequest.data.relationships.user"
class="absolute -bottom-2.5 -right-2" class="absolute -bottom-2.5 -right-2"
:is-border="true" :is-border="true"
@@ -112,16 +113,13 @@
</div> </div>
<h1 class="title"> <h1 class="title">
{{ $t('Jane Request You for File Upload') }} {{ emptyPageTitle }}
</h1> </h1>
<p class="description max-w-[420px]"> <p class="description max-w-[420px]">
{{ {{ emptyPageDescription }}
$t(
'Your files will be uploaded automatically and after that, you can organize your files in folders.'
)
}}
</p> </p>
<ButtonUpload button-style="theme">
<ButtonUpload v-if="uploadRequest.data.attributes.status === 'active'" button-style="theme">
{{ $t('empty_page.call_to_action') }} {{ $t('empty_page.call_to_action') }}
</ButtonUpload> </ButtonUpload>
</EmptyFilePage> </EmptyFilePage>
@@ -146,8 +144,8 @@ import FileBrowser from '../../components/FilesView/FileBrowser'
import ContextMenu from '../../components/FilesView/ContextMenu' import ContextMenu from '../../components/FilesView/ContextMenu'
import OptionGroup from '../../components/FilesView/OptionGroup' import OptionGroup from '../../components/FilesView/OptionGroup'
import Option from '../../components/FilesView/Option' import Option from '../../components/FilesView/Option'
import { events } from '../../bus' import {events} from '../../bus'
import { mapGetters } from 'vuex' import {mapGetters} from 'vuex'
export default { export default {
name: 'Files', name: 'Files',
@@ -173,6 +171,21 @@ export default {
isFolder() { isFolder() {
return this.item && this.item.data.type === 'folder' 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() { data() {
return { return {
@@ -181,7 +194,7 @@ export default {
}, },
methods: { methods: {
createFolder() { createFolder() {
events.$emit('popup:open', { name: 'create-folder' }) events.$emit('popup:open', {name: 'create-folder'})
}, },
}, },
created() { created() {
@@ -190,7 +203,6 @@ export default {
events.$on('mobile-context-menu:show', (item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item))
this.$store.dispatch('getUploadRequestDetail') this.$store.dispatch('getUploadRequestDetail')
}, },
} }
</script> </script>
+9
View File
@@ -4,6 +4,8 @@
<FilePreview /> <FilePreview />
<Spotlight /> <Spotlight />
<ConfirmPopup />
<!--Popups--> <!--Popups-->
<CreateFolderPopup /> <CreateFolderPopup />
<RenameItemPopup /> <RenameItemPopup />
@@ -42,6 +44,7 @@ import FileSortingMobile from '../components/FilesView/FileSortingMobile'
import FileFilterMobile from '../components/FilesView/FileFilterMobile' import FileFilterMobile from '../components/FilesView/FileFilterMobile'
import CreateFolderPopup from '../components/Others/CreateFolderPopup' import CreateFolderPopup from '../components/Others/CreateFolderPopup'
import DesktopToolbar from '../components/FilesView/DesktopToolbar' import DesktopToolbar from '../components/FilesView/DesktopToolbar'
import ConfirmPopup from "../components/Others/Popup/ConfirmPopup"
import RenameItemPopup from '../components/Others/RenameItemPopup' import RenameItemPopup from '../components/Others/RenameItemPopup'
import MobileToolbar from '../components/FilesView/MobileToolbar' import MobileToolbar from '../components/FilesView/MobileToolbar'
import FilePreview from '../components/FilePreview/FilePreview' import FilePreview from '../components/FilePreview/FilePreview'
@@ -55,6 +58,7 @@ import { events } from '../bus'
export default { export default {
name: 'UploadRequest', name: 'UploadRequest',
components: { components: {
ConfirmPopup,
DesktopUploadRequestToolbar, DesktopUploadRequestToolbar,
CreateFolderPopup, CreateFolderPopup,
FileSortingMobile, FileSortingMobile,
@@ -85,6 +89,11 @@ export default {
// TODO: new scaledown effect // TODO: new scaledown effect
events.$on('mobile-menu:show', () => (this.isScaledDown = true)) events.$on('mobile-menu:show', () => (this.isScaledDown = true))
events.$on('mobile-menu:hide', () => (this.isScaledDown = false)) events.$on('mobile-menu:hide', () => (this.isScaledDown = false))
events.$on('action:confirmed', (data) => {
if (data.operation === 'close-upload-request')
this.$store.dispatch('closeUploadRequest')
})
}, },
} }
</script> </script>
+3 -1
View File
@@ -2,10 +2,12 @@
use Domain\UploadRequest\Controllers\GetUploadRequestController; use Domain\UploadRequest\Controllers\GetUploadRequestController;
use Domain\UploadRequest\Controllers\CreateUploadRequestController; use Domain\UploadRequest\Controllers\CreateUploadRequestController;
use Domain\UploadRequest\Controllers\SetUploadRequestAsFilledController;
use Domain\UploadRequest\Controllers\UploadFilesForUploadRequestController; use Domain\UploadRequest\Controllers\UploadFilesForUploadRequestController;
Route::get('/{uploadRequest}', GetUploadRequestController::class); 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::group(['middleware' => ['auth:sanctum']], function () {
Route::post('/', CreateUploadRequestController::class); 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, 'id' => $this->user->id,
'type' => 'user', 'type' => 'user',
'attributes' => [ 'attributes' => [
'name' => $this->user->settings->name, 'name' => $this->user->settings->first_name,
'avatar' => $this->user->settings->avatar, 'avatar' => $this->user->settings->avatar,
], ],
], ],
@@ -1,4 +1,5 @@
<?php <?php
namespace Tests\Domain\UploadRequest; namespace Tests\Domain\UploadRequest;
use Storage; use Storage;
@@ -118,7 +119,7 @@ class UploadRequestTest extends TestCase
->create('fake-file.pdf', 12000000, 'application/pdf'); ->create('fake-file.pdf', 12000000, 'application/pdf');
$this $this
->postJson("/api/upload-request/$uploadRequest->id", [ ->postJson("/api/upload-request/$uploadRequest->id/upload", [
'filename' => $file->name, 'filename' => $file->name,
'file' => $file, 'file' => $file,
'parent_id' => null, 'parent_id' => null,
@@ -159,7 +160,7 @@ class UploadRequestTest extends TestCase
->create('fake-file.pdf', 12000000, 'application/pdf'); ->create('fake-file.pdf', 12000000, 'application/pdf');
$this $this
->postJson("/api/upload-request/$uploadRequest->id", [ ->postJson("/api/upload-request/$uploadRequest->id/upload", [
'filename' => $file->name, 'filename' => $file->name,
'file' => $file, 'file' => $file,
'parent_id' => null, 'parent_id' => null,
@@ -167,4 +168,28 @@ class UploadRequestTest extends TestCase
'is_last' => 'true', 'is_last' => 'true',
])->assertStatus(410); ])->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',
]);
}
} }