From 4379daa079f39290c96028cf7fe953ca8fd7a82b Mon Sep 17 00:00:00 2001 From: Milos Holba Date: Wed, 6 Apr 2022 17:40:44 +0200 Subject: [PATCH 1/5] added infinite scroll in browsing --- config/vuefilemanager.php | 4 + public/mix-manifest.json | 140 ++++++------ .../js/components/FilesView/FileBrowser.vue | 48 +++- .../js/components/Spotlight/Spotlight.vue | 6 +- resources/js/helpers/functionHelpers.js | 20 +- resources/js/helpers/itemHelpers.js | 2 +- resources/js/store/modules/fileBrowser.js | 213 ++++++++++++------ resources/js/store/modules/sharing.js | 19 +- resources/js/store/modules/teams.js | 176 ++++++++------- resources/js/store/modules/uploadRequest.js | 9 +- resources/js/store/modules/userAuth.js | 10 +- .../Components/NavigationSharePanel.vue | 2 +- .../Components/PanelNavigationFiles.vue | 2 +- resources/js/views/FileView/Files.vue | 4 +- resources/js/views/FileView/MySharedItems.vue | 2 +- resources/js/views/FileView/Public.vue | 2 +- resources/js/views/FileView/SharedWithMe.vue | 4 +- resources/js/views/FileView/TeamFolders.vue | 4 +- resources/js/views/FileView/Trash.vue | 2 +- resources/views/index.blade.php | 1 + src/App/Users/Models/User.php | 3 +- .../Controllers/BrowseFolderController.php | 14 +- .../BrowseLatestFilesController.php | 14 +- .../BrowseSharedItemsController.php | 16 +- .../BrowseTrashContentController.php | 61 +++-- .../VisitorBrowseFolderController.php | 15 +- .../Files/Resources/FilesCollection.php | 7 +- .../Folders/Resources/FolderCollection.php | 7 +- .../BrowseSharedWithMeController.php | 16 +- .../Controllers/TeamFoldersController.php | 16 +- src/Support/helpers.php | 51 +++++ 31 files changed, 555 insertions(+), 335 deletions(-) diff --git a/config/vuefilemanager.php b/config/vuefilemanager.php index 928897b6..6dfff8d1 100644 --- a/config/vuefilemanager.php +++ b/config/vuefilemanager.php @@ -60,4 +60,8 @@ return [ ], ], ], + + 'paginate' => [ + 'perPage' => 50 + ] ]; diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 05ada352..eb14b871 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,75 +1,75 @@ { "/js/main.js": "/js/main.js", - "/chunks/request.js": "/chunks/request.js?id=37e3e34fbcc98d4c", - "/chunks/request-upload.js": "/chunks/request-upload.js?id=2a6d910114ffb8d2", - "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=3c2fc454c3fce8d2", - "/chunks/status-check.js": "/chunks/status-check.js?id=783c6143db13e6c0", - "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=c1df85c34d7e9521", - "/chunks/database.js": "/chunks/database.js?id=d4f38bfdef26b0d9", - "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=21e576c9c8183e42", - "/chunks/app-setup.js": "/chunks/app-setup.js?id=647bf9cdc907e83c", - "/chunks/admin-account.js": "/chunks/admin-account.js?id=d21b66f2b6e1638e", - "/chunks/shared.js": "/chunks/shared.js?id=52ff66b9c01f84ef", - "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=a9710655d75c8079", - "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=c013d98f7386c448", - "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=ca8cc89fe5982782", - "/chunks/not-found.js": "/chunks/not-found.js?id=4cb8d3a7a2212c3c", - "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=c71981d946a9ca71", - "/chunks/admin.js": "/chunks/admin.js?id=4c86279cd6e85aa5", - "/chunks/dashboard.js": "/chunks/dashboard.js?id=d8740b43db79abfe", - "/chunks/invoices.js": "/chunks/invoices.js?id=70fb9a603be2f554", - "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=94e96e1bb505ae59", - "/chunks/pages.js": "/chunks/pages.js?id=d1f5d211e9dfc4ae", - "/chunks/page-edit.js": "/chunks/page-edit.js?id=184547a95a64a121", - "/chunks/plans.js": "/chunks/plans.js?id=f6e9d2f34fac6d79", - "/chunks/users.js": "/chunks/users.js?id=651b8af7afecc88e", - "/chunks/user-create.js": "/chunks/user-create.js?id=d24c5037b91a2fa2", - "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=20a6ee217157864f", - "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=617982724a144a43", - "/chunks/user.js": "/chunks/user.js?id=dae4ac26750f99d0", - "/chunks/user-detail.js": "/chunks/user-detail.js?id=d56437755ba2c6cc", - "/chunks/user-storage.js": "/chunks/user-storage.js?id=c26b370f6f4323fe", - "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=6d7d1235d1ae5bf2", - "/chunks/user-password.js": "/chunks/user-password.js?id=acd9b49cca55d161", - "/chunks/user-delete.js": "/chunks/user-delete.js?id=47d44b2f8e4e620c", - "/chunks/plan.js": "/chunks/plan.js?id=d8ffa85dc9b68966", - "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=3010ddb4ba7419e9", - "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=d3c236e167831f25", - "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=44ad905bfe1ae983", - "/chunks/payments.js": "/chunks/payments.js?id=051e8246e2b5c9d0", - "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=7ec4ad9b9755b2b8", - "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=6644b642875c732f", - "/chunks/app-settings.js": "/chunks/app-settings.js?id=692d3291fb9d2cf7", - "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=27652021b725b9e7", - "/chunks/app-index.js": "/chunks/app-index.js?id=968d5378d871f070", - "/chunks/app-environment.js": "/chunks/app-environment.js?id=09a06687b64b4246", - "/chunks/app-others.js": "/chunks/app-others.js?id=2c024715a619858e", - "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=ea65b443a513ad8c", - "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=c4c4cda03202a49a", - "/chunks/app-server.js": "/chunks/app-server.js?id=307fce5c9d192bf3", - "/chunks/app-language.js": "/chunks/app-language.js?id=51c79c7bdb8f9382", - "/chunks/homepage.js": "/chunks/homepage.js?id=b45798483b942ac1", - "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=e110e8923b6ca22f", - "/chunks/contact-us.js": "/chunks/contact-us.js?id=54d3469e6d46cef6", - "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=3153532f0d2273c8", - "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=d630ed9f6f558509", - "/chunks/sign-in.js": "/chunks/sign-in.js?id=73e0fd17a1b1677d", - "/chunks/sign-up.js": "/chunks/sign-up.js?id=920ebe5b86e59c09", - "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=9c62b8573fbdd567", - "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=926b35b6745d99ba", - "/chunks/settings.js": "/chunks/settings.js?id=a1244ef9a4054cdf", - "/chunks/profile.js": "/chunks/profile.js?id=e92af0c70da9aa83", - "/chunks/settings-password.js": "/chunks/settings-password.js?id=080d3133ed6bc14c", - "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=736118b6409186cc", - "/chunks/billing.js": "/chunks/billing.js?id=e4e8b9c2f7fa6cd2", - "/chunks/platform.js": "/chunks/platform.js?id=dd458bc66dd8cb51", - "/chunks/files.js": "/chunks/files.js?id=5d6eb9b9f9ecd296", - "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=827d3a5dcce159b5", - "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=2a4e4e0db02cbcbb", - "/chunks/trash.js": "/chunks/trash.js?id=8362aa0f91231350", - "/chunks/team-folders.js": "/chunks/team-folders.js?id=0a46fecf35a23406", - "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=77a33583775c6d8f", - "/chunks/invitation.js": "/chunks/invitation.js?id=64a211c90b505767", + "/chunks/request.js": "/chunks/request.js?id=e12cca6ff4d753a0", + "/chunks/request-upload.js": "/chunks/request-upload.js?id=6162439c4476a9fb", + "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=e8b9ac5e5a0854bf", + "/chunks/status-check.js": "/chunks/status-check.js?id=4c7482ca1bc4806d", + "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=95910a6098545b18", + "/chunks/database.js": "/chunks/database.js?id=f075fa5bd4011705", + "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=6a2f88cf2e1c8c42", + "/chunks/app-setup.js": "/chunks/app-setup.js?id=fac96a371fa057a9", + "/chunks/admin-account.js": "/chunks/admin-account.js?id=f207f8887394310d", + "/chunks/shared.js": "/chunks/shared.js?id=cdfbac570212aaba", + "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=eb7d18bbc0ac131a", + "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=fda3ee1897218fb4", + "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=a68c497e91a6fadb", + "/chunks/not-found.js": "/chunks/not-found.js?id=cbcb2fcb42696af3", + "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=8b78c188c3ef58cc", + "/chunks/admin.js": "/chunks/admin.js?id=23b353c5fba8f97b", + "/chunks/dashboard.js": "/chunks/dashboard.js?id=c265489f6698ba44", + "/chunks/invoices.js": "/chunks/invoices.js?id=4888dcbcb1371d33", + "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=c754f2735eefc4c9", + "/chunks/pages.js": "/chunks/pages.js?id=d7fa7d4e7183174e", + "/chunks/page-edit.js": "/chunks/page-edit.js?id=3bd81e19fcce81aa", + "/chunks/plans.js": "/chunks/plans.js?id=d69f27e0eef6cd1a", + "/chunks/users.js": "/chunks/users.js?id=89c6cffd734c97b0", + "/chunks/user-create.js": "/chunks/user-create.js?id=200db7025d533298", + "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=9d40af67b3f3eb25", + "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=47674b7d5dd105e6", + "/chunks/user.js": "/chunks/user.js?id=b9b5caf4720670e9", + "/chunks/user-detail.js": "/chunks/user-detail.js?id=ae8139dee6bc9148", + "/chunks/user-storage.js": "/chunks/user-storage.js?id=415f9f91492ec6eb", + "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=2e485797f12f64c8", + "/chunks/user-password.js": "/chunks/user-password.js?id=30e1861f3b9f4e2b", + "/chunks/user-delete.js": "/chunks/user-delete.js?id=61995898ac991620", + "/chunks/plan.js": "/chunks/plan.js?id=d8cdd722694b202d", + "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=a264bff3e18fbb1c", + "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=aaaf30d34d941711", + "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=385d94cbf75154cd", + "/chunks/payments.js": "/chunks/payments.js?id=26aa71dcfe9109fb", + "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=c2edc02c0261af92", + "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=72383895b3bfb5a4", + "/chunks/app-settings.js": "/chunks/app-settings.js?id=a6b8202457054e7c", + "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=8a139759c507aab3", + "/chunks/app-index.js": "/chunks/app-index.js?id=0237d25f5fec22f8", + "/chunks/app-environment.js": "/chunks/app-environment.js?id=5cdd3a4a5276b300", + "/chunks/app-others.js": "/chunks/app-others.js?id=8c9ef45b8163b98e", + "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=bdd9ab8b100e63e9", + "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=916521e9750df132", + "/chunks/app-server.js": "/chunks/app-server.js?id=daa05ca55f05276e", + "/chunks/app-language.js": "/chunks/app-language.js?id=3dc649491be91954", + "/chunks/homepage.js": "/chunks/homepage.js?id=8d839489cb2670b7", + "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=0b84c5e06b3f1202", + "/chunks/contact-us.js": "/chunks/contact-us.js?id=c2f9beea77a7109b", + "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=d080d93ce30187d1", + "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=5d0042e9619ed73e", + "/chunks/sign-in.js": "/chunks/sign-in.js?id=379b9147d37291d5", + "/chunks/sign-up.js": "/chunks/sign-up.js?id=d1bcad80748579ae", + "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=7e713217b427cc06", + "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=094a12eb5ba69c9f", + "/chunks/settings.js": "/chunks/settings.js?id=7ef82be482dcf31d", + "/chunks/profile.js": "/chunks/profile.js?id=d280577d80754c91", + "/chunks/settings-password.js": "/chunks/settings-password.js?id=4f56d97ef76cff6e", + "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=e6866a6ffd9c3a80", + "/chunks/billing.js": "/chunks/billing.js?id=ce81cf6583d26d4c", + "/chunks/platform.js": "/chunks/platform.js?id=8899666aebaf9db4", + "/chunks/files.js": "/chunks/files.js?id=5f981e4f05062e30", + "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=3469cce1ee71c03c", + "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=2f712e064ac8e575", + "/chunks/trash.js": "/chunks/trash.js?id=2df58d71ed9f7ea2", + "/chunks/team-folders.js": "/chunks/team-folders.js?id=7bda1a54e372f0de", + "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=f8eec4a942b431a0", + "/chunks/invitation.js": "/chunks/invitation.js?id=3220065b746aa8fe", "/css/tailwind.css": "/css/tailwind.css", "/css/app.css": "/css/app.css" } diff --git a/resources/js/components/FilesView/FileBrowser.vue b/resources/js/components/FilesView/FileBrowser.vue index 0318686a..14c451af 100644 --- a/resources/js/components/FilesView/FileBrowser.vue +++ b/resources/js/components/FilesView/FileBrowser.vue @@ -11,6 +11,7 @@ @dragover="dragEnter" @dragleave="dragLeave" @dragover.prevent + @scroll="infiniteScroll" tabindex="-1" @click.self="deselect" > @@ -24,6 +25,14 @@ :key="item.data.id" :item="item" /> + + +
+ +
@@ -31,14 +40,16 @@ import ItemHandler from './ItemHandler' import { events } from '../../bus' import { mapGetters } from 'vuex' +import Spinner from './Spinner' export default { name: 'FileBrowser', components: { ItemHandler, + Spinner }, computed: { - ...mapGetters(['isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard', 'entries', 'config']), + ...mapGetters(['isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard', 'entries', 'config', 'paginate']), draggedItems() { // Set opacity for dragged items if (!this.clipboard.includes(this.draggingId)) { @@ -49,14 +60,46 @@ export default { return this.clipboard } }, + continueInfiniteScroll() { + if(this.paginate) + return this.paginate.paginate.currentPage !== this.paginate.paginate.lastPage + }, + showInfiniteLoadSpinner() { + return this.continueInfiniteScroll && this.entries.length !== 0 && config.itemsPerPage <= this.entries.length + }, }, data() { return { draggingId: undefined, isDragging: false, + infiniteScrollLoad: false, } }, methods: { + infiniteScroll() { + + if( this.continueInfiniteScroll && this.elementInViewport() ) { + + if(! this.infiniteScrollLoad) { + this.infiniteScrollLoad = true + + this.$getDataByLocation(this.paginate.paginate.currentPage + 1).then(() => { + this.infiniteScrollLoad = false + }) + } + } + }, + elementInViewport() { + var item = document.getElementById('infinite-loader') + var rect = item.getBoundingClientRect() + + return ( + rect.bottom > 0 && + rect.right > 0 && + rect.left < (window.innerWidth || document.documentElement.clientWidth) && + rect.top < (window.innerHeight || document.documentElement.clientHeight) + ); + }, deleteItems() { if ((this.clipboard.length > 0 && this.$checkPermission('master')) || this.$checkPermission('editor')) { this.$store.dispatch('deleteItem') @@ -133,6 +176,9 @@ export default { }, }, created() { + if(this.$isMobile()) + document.addEventListener('scroll', this.infiniteScroll, true) + events.$on('drop', () => { this.isDragging = false diff --git a/resources/js/components/Spotlight/Spotlight.vue b/resources/js/components/Spotlight/Spotlight.vue index b3a85276..14abe3ec 100644 --- a/resources/js/components/Spotlight/Spotlight.vue +++ b/resources/js/components/Spotlight/Spotlight.vue @@ -839,13 +839,13 @@ export default { .then((response) => { // Show user result if (this.activeFilter === 'users') { - this.results = response.data.data + this.results = response.data } // Show file result if (!this.activeFilter) { - let files = response.data.files.data - let folders = response.data.folders.data + let files = response.data.files + let folders = response.data.folders this.results = folders.concat(files) } diff --git a/resources/js/helpers/functionHelpers.js b/resources/js/helpers/functionHelpers.js index ad528370..86ff803c 100644 --- a/resources/js/helpers/functionHelpers.js +++ b/resources/js/helpers/functionHelpers.js @@ -325,19 +325,19 @@ const FunctionHelpers = { }[this.$router.currentRoute.name] } - Vue.prototype.$getDataByLocation = function () { + Vue.prototype.$getDataByLocation = async function (page) { let routes = { - RequestUpload: ['getUploadRequestFolder', router.currentRoute.params.id || undefined ], - Public: ['getSharedFolder', router.currentRoute.params.id || undefined], - Files: ['getFolder', router.currentRoute.params.id || undefined], - RecentUploads: ['getRecentUploads'], - MySharedItems: ['getMySharedItems'], - Trash: ['getTrash', router.currentRoute.params.id || undefined], - TeamFolders: ['getTeamFolder', router.currentRoute.params.id || undefined], - SharedWithMe: ['getSharedWithMeFolder', router.currentRoute.params.id || undefined], + RequestUpload: ['getUploadRequestFolder', {page:page, id:router.currentRoute.params.id || undefined} ], + Public: ['getSharedFolder', {page:page, id:router.currentRoute.params.id || undefined}], + Files: ['getFolder', {page:page, id:router.currentRoute.params.id || undefined}], + RecentUploads: ['getRecentUploads', page], + MySharedItems: ['getMySharedItems', page], + Trash: ['getTrash', {page:page , id:router.currentRoute.params.id || undefined}], + TeamFolders: ['getTeamFolder',{page:page, id:router.currentRoute.params.id || undefined}], + SharedWithMe: ['getSharedWithMeFolder',{page:page, id:router.currentRoute.params.id || undefined}], } - store.dispatch(...routes[router.currentRoute.name]) + await store.dispatch(...routes[router.currentRoute.name]) } Vue.prototype.$getPaymentLogo = function (driver) { diff --git a/resources/js/helpers/itemHelpers.js b/resources/js/helpers/itemHelpers.js index 635272d0..da1dcaa5 100644 --- a/resources/js/helpers/itemHelpers.js +++ b/resources/js/helpers/itemHelpers.js @@ -17,7 +17,7 @@ const itemHelpers = { } Vue.prototype.$toggleFavourites = function (entry) { - let favourites = store.getters.user.data.relationships.favourites.data + let favourites = store.getters.user.data.relationships.favourites // Check if folder is in favourites and then add/remove from favourites if (favourites && !favourites.find((el) => el.data.id === entry.data.id)) { diff --git a/resources/js/store/modules/fileBrowser.js b/resources/js/store/modules/fileBrowser.js index 487dfe6e..be98fb3e 100644 --- a/resources/js/store/modules/fileBrowser.js +++ b/resources/js/store/modules/fileBrowser.js @@ -12,93 +12,150 @@ const defaultState = { isLoading: true, clipboard: [], entries: [], + paginate: undefined, } const actions = { - getFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getFolder: ({ commit, getters },{page, id}) => { + return new Promise ((resolve, reject) => { - axios - .get(`${getters.api}/browse/folders/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + if( !page) + commit('LOADING_STATE', { loading: true, data: [] }) - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) + let currentPage = page || 1 - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + axios + .get(`${getters.api}/browse/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) - }, - getRecentUploads: ({ commit, getters }) => { - commit('LOADING_STATE', { loading: true, data: [] }) - axios - .get(getters.api + '/browse/latest') - .then((response) => { - commit('LOADING_STATE', { - loading: false, - data: response.data.files.data, + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + events.$emit('scrollTop') + + resolve(true); }) - commit('SET_CURRENT_FOLDER', undefined) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) - }, - getMySharedItems: ({ commit, getters }) => { - commit('LOADING_STATE', { loading: true, data: [] }) - - axios - .get(getters.api + '/browse/share' + getters.sorting.URI) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), + reject(error) }) - commit('SET_CURRENT_FOLDER', undefined) - - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) + }) }, - getTrash: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getRecentUploads: ({ commit, getters }, page) => { + return new Promise ((resolve, reject) => { - axios - .get(`${getters.api}/browse/trash/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(getters.api + `/browse/latest?page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', undefined) + + events.$emit('scrollTop') - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), + resolve(true) }) - commit('SET_CURRENT_FOLDER', response.data.root) + .catch((error) => { + Vue.prototype.$isSomethingWrong() - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) + reject(error) + }) + }) + + }, + getMySharedItems: ({ commit, getters }, page) => { + return new Promise ((resolve, reject) => { + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(`${getters.api}/browse/share${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', undefined) + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) + }) + + }, + getTrash: ({ commit, getters },{page, id}) => { + return new Promise ((resolve, reject) => { + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(`${getters.api}/browse/trash/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) + }) }, getFolderTree: ({ commit, getters }) => { return new Promise((resolve, reject) => { @@ -116,17 +173,24 @@ const actions = { commit('UPDATE_FOLDER_TREE', response.data) }) .catch((error) => { - reject(error) - Vue.prototype.$isSomethingWrong() + + reject(error) }) }) }, } const mutations = { + SET_PAGINATE(state, payload) { + state.paginate = payload + }, LOADING_STATE(state, payload) { - state.entries = payload.data + if(payload.data.length === 0) { + state.entries = [] + } else { + state.entries.push(...payload.data) + } state.isLoading = payload.loading }, SET_CURRENT_FOLDER(state, folder) { @@ -221,6 +285,7 @@ const getters = { clipboard: (state) => state.clipboard, isLoading: (state) => state.isLoading, entries: (state) => state.entries, + paginate: (state) => state.paginate } export default { diff --git a/resources/js/store/modules/sharing.js b/resources/js/store/modules/sharing.js index 81b3ead6..fa4e9203 100644 --- a/resources/js/store/modules/sharing.js +++ b/resources/js/store/modules/sharing.js @@ -20,21 +20,26 @@ const defaultState = { sharedFile: undefined, } const actions = { - getSharedFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getSharedFolder: ({ commit, getters }, {page, id}) => { + + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 return new Promise((resolve, reject) => { axios - .get(`/api/browse/folders/${id}/${router.currentRoute.params.token}${getters.sorting.URI}`) + .get(`/api/browse/folders/${id}/${router.currentRoute.params.token}${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) commit('LOADING_STATE', { loading: false, - data: folders.concat(files), + data: response.data.data, }) - commit('SET_CURRENT_FOLDER', response.data.root) + commit('SET_CURRENT_FOLDER', response.data.meta.root) events.$emit('scrollTop') diff --git a/resources/js/store/modules/teams.js b/resources/js/store/modules/teams.js index 4cac8427..41df857c 100644 --- a/resources/js/store/modules/teams.js +++ b/resources/js/store/modules/teams.js @@ -9,89 +9,111 @@ const defaultState = { } const actions = { - getTeamFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getTeamFolder: ({ commit, getters }, {page, id}) => { + return new Promise ((resolve, reject) => { - if (typeof id === 'undefined') { - commit('SET_CURRENT_TEAM_FOLDER', null) - } + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + if (typeof id === 'undefined') { + commit('SET_CURRENT_TEAM_FOLDER', null) + } - axios - .get(`${getters.api}/teams/folders/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) - - if ( - !getters.currentTeamFolder || - getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id - ) { - commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) - } - - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + let currentPage = page || 1 + + axios + .get(`${getters.api}/teams/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) + + commit('LOADING_STATE', { + loading: false, + data:response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + if ( + !getters.currentTeamFolder || + getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id + ) { + commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) + } + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } + + reject(error) + }) + }) }, - getSharedWithMeFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getSharedWithMeFolder: ({ commit, getters }, {page, id}) => { + return new Promise ((resolve, reject) => { + + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + if (typeof id === 'undefined') { + commit('SET_CURRENT_TEAM_FOLDER', null) + } - if (typeof id === 'undefined') { - commit('SET_CURRENT_TEAM_FOLDER', null) - } - - axios - .get(`${getters.api}/teams/shared-with-me/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) - - if ( - !getters.currentTeamFolder || - getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id - ) { - commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) - } - - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + let currentPage = page || 1 + + axios + .get(`${getters.api}/teams/shared-with-me/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + if ( + !getters.currentTeamFolder || + getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id + ) { + commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) + } + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } + + reject(error) + }) + }) }, getTeamFolderTree: ({ commit, getters }) => { return new Promise((resolve, reject) => { diff --git a/resources/js/store/modules/uploadRequest.js b/resources/js/store/modules/uploadRequest.js index eeafcef7..0c2a18da 100644 --- a/resources/js/store/modules/uploadRequest.js +++ b/resources/js/store/modules/uploadRequest.js @@ -15,8 +15,8 @@ const actions = { axios .get(`/api/upload-request/${router.currentRoute.params.token}/browse/${id}${getters.sorting.URI}`) .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + let folders = response.data.folders + let files = response.data.files commit('LOADING_STATE', { loading: false, @@ -52,6 +52,11 @@ const actions = { commit('SET_CURRENT_FOLDER', response.data.data.relationships.folder) } }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) }) }, closeUploadRequest: ({ commit }) => { diff --git a/resources/js/store/modules/userAuth.js b/resources/js/store/modules/userAuth.js index 60d5ec06..f8e3db14 100644 --- a/resources/js/store/modules/userAuth.js +++ b/resources/js/store/modules/userAuth.js @@ -75,7 +75,7 @@ const actions = { items.forEach((item) => { if (item.data.type === 'folder') { if ( - context.getters.user.data.relationships.favourites.data.find((folder) => folder.id === item.data.id) + context.getters.user.data.relationships.favourites.find((folder) => folder.id === item.data.id) ) return @@ -92,7 +92,7 @@ const actions = { // Check is favorites already don't include some of pushed folders items.map((item) => { - if (!context.getters.user.data.relationships.favourites.data.find((folder) => folder.data.id === item.id)) { + if (!context.getters.user.data.relationships.favourites.find((folder) => folder.data.id === item.id)) { pushToFavorites.push(item) } }) @@ -152,7 +152,7 @@ const mutations = { }, ADD_TO_FAVOURITES(state, folder) { folder.forEach((item) => { - state.user.data.relationships.favourites.data.push(item) + state.user.data.relationships.favourites.push(item) }) }, UPDATE_FIRST_NAME(state, name) { @@ -169,12 +169,12 @@ const mutations = { } }, REMOVE_ITEM_FROM_FAVOURITES(state, item) { - state.user.data.relationships.favourites.data = state.user.data.relationships.favourites.data.filter( + state.user.data.relationships.favourites = state.user.data.relationships.favourites.filter( (folder) => folder.data.id !== item.data.id ) }, UPDATE_NAME_IN_FAVOURITES(state, data) { - state.user.data.relationships.favourites.data.find((folder) => { + state.user.data.relationships.favourites.find((folder) => { if (folder.id === data.id) { folder.name = data.name } diff --git a/resources/js/views/FileView/Components/NavigationSharePanel.vue b/resources/js/views/FileView/Components/NavigationSharePanel.vue index 83ee0add..0bd5c594 100644 --- a/resources/js/views/FileView/Components/NavigationSharePanel.vue +++ b/resources/js/views/FileView/Components/NavigationSharePanel.vue @@ -115,7 +115,7 @@ export default { 'isDarkMode', ]), favourites() { - return this.user.data.relationships.favourites.data.attributes.folders + return this.user.data.relationships.favourites.attributes.folders }, storage() { return this.$store.getters.user.data.attributes.storage diff --git a/resources/js/views/FileView/Components/PanelNavigationFiles.vue b/resources/js/views/FileView/Components/PanelNavigationFiles.vue index 89dc148a..c950cde2 100644 --- a/resources/js/views/FileView/Components/PanelNavigationFiles.vue +++ b/resources/js/views/FileView/Components/PanelNavigationFiles.vue @@ -132,7 +132,7 @@ export default { computed: { ...mapGetters(['isVisibleNavigationBars', 'navigation', 'clipboard', 'config', 'user']), favourites() { - return this.user.data.relationships.favourites.data + return this.user.data.relationships.favourites }, storage() { return this.$store.getters.user.data.attributes.storage diff --git a/resources/js/views/FileView/Files.vue b/resources/js/views/FileView/Files.vue index d51dc283..1a4e4b5a 100644 --- a/resources/js/views/FileView/Files.vue +++ b/resources/js/views/FileView/Files.vue @@ -251,7 +251,7 @@ export default { return this.item && this.item.data.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.data.id === this.item.data.id) + return this.user.data.relationships.favourites.find((el) => el.data.id === this.item.data.id) }, hasFile() { return this.clipboard.find((item) => item.data.type !== 'folder') @@ -263,7 +263,7 @@ export default { } }, created() { - this.$store.dispatch('getFolder', this.$route.params.id) + this.$store.dispatch('getFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('context-menu:current-folder', (folder) => (this.item = folder)) diff --git a/resources/js/views/FileView/MySharedItems.vue b/resources/js/views/FileView/MySharedItems.vue index 44b7a2d6..2e4920b3 100644 --- a/resources/js/views/FileView/MySharedItems.vue +++ b/resources/js/views/FileView/MySharedItems.vue @@ -152,7 +152,7 @@ export default { return this.item && this.item.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.id === this.item.id) + return this.user.data.relationships.favourites.find((el) => el.id === this.item.id) }, hasFile() { return this.clipboard.find((item) => item.type !== 'folder') diff --git a/resources/js/views/FileView/Public.vue b/resources/js/views/FileView/Public.vue index 3cf722e6..57db6df8 100644 --- a/resources/js/views/FileView/Public.vue +++ b/resources/js/views/FileView/Public.vue @@ -228,7 +228,7 @@ export default { }, }, created() { - this.$store.dispatch('getSharedFolder', this.$route.params.id) + this.$store.dispatch('getSharedFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/js/views/FileView/SharedWithMe.vue b/resources/js/views/FileView/SharedWithMe.vue index 24af38a2..0e76cea7 100644 --- a/resources/js/views/FileView/SharedWithMe.vue +++ b/resources/js/views/FileView/SharedWithMe.vue @@ -234,7 +234,7 @@ export default { }, }, mounted() { - this.$store.dispatch('getSharedWithMeFolder', this.$route.params.id) + this.$store.dispatch('getSharedWithMeFolder',{page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) @@ -249,7 +249,7 @@ export default { if (this.$route.params.id) { this.$router.push({ name: 'SharedWithMe' }) } else { - this.$store.dispatch('getSharedWithMeFolder', undefined) + this.$store.dispatch('getSharedWithMeFolder',{page:null, id:undefined}) } events.$emit('toaster', { diff --git a/resources/js/views/FileView/TeamFolders.vue b/resources/js/views/FileView/TeamFolders.vue index c17715b8..23206851 100644 --- a/resources/js/views/FileView/TeamFolders.vue +++ b/resources/js/views/FileView/TeamFolders.vue @@ -275,7 +275,7 @@ export default { return this.item && this.item.data.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.id === this.item.id) + return this.user.data.relationships.favourites.find((el) => el.id === this.item.id) }, hasFile() { return this.clipboard.find((item) => item.type !== 'folder') @@ -287,7 +287,7 @@ export default { } }, mounted() { - this.$store.dispatch('getTeamFolder', this.$route.params.id) + this.$store.dispatch('getTeamFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/js/views/FileView/Trash.vue b/resources/js/views/FileView/Trash.vue index 5faed522..7dfbfc1e 100644 --- a/resources/js/views/FileView/Trash.vue +++ b/resources/js/views/FileView/Trash.vue @@ -146,7 +146,7 @@ export default { } }, created() { - this.$store.dispatch('getTrash', this.$route.params.id) + this.$store.dispatch('getTrash', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index a9a93617..d4ede93f 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -180,6 +180,7 @@ // App settings userRegistration: {{ $settings->registration ?? 1 }}, userVerification: {{ $settings->user_verification ?? 0 }}, + itemsPerPage: {{ config('vuefilemanager.paginate.perPage') }}, } diff --git a/src/App/Users/Models/User.php b/src/App/Users/Models/User.php index 7003cca3..b5edb88b 100644 --- a/src/App/Users/Models/User.php +++ b/src/App/Users/Models/User.php @@ -159,8 +159,7 @@ class User extends Authenticatable implements MustVerifyEmail ->with([ 'parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in', - ]) - ->take(40); + ]); } /** diff --git a/src/Domain/Browsing/Controllers/BrowseFolderController.php b/src/Domain/Browsing/Controllers/BrowseFolderController.php index 0baf51bb..0d42c906 100644 --- a/src/Domain/Browsing/Controllers/BrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/BrowseFolderController.php @@ -6,9 +6,7 @@ use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; class BrowseFolderController { @@ -31,11 +29,15 @@ class BrowseFolderController ->sortable() ->get(); - // Collect folders and files to single array + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => $root_id ? new FolderResource(Folder::findOrFail($root_id)) : null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $root_id ? new FolderResource(Folder::findOrFail($root_id)) : null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php index 1f1eb085..556f50fb 100644 --- a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php +++ b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php @@ -3,11 +3,11 @@ namespace Domain\Browsing\Controllers; use App\Users\Models\User; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; +use Illuminate\Http\Request; class BrowseLatestFilesController { - public function __invoke(): array + public function __invoke(Request $request): array { $user = User::with([ 'latestUploads' => fn ($query) => $query->sortable(['created_at' => 'desc']), @@ -15,9 +15,15 @@ class BrowseLatestFilesController ->where('id', Auth::id()) ->first(); + list($data, $paginate, $links) = groupPaginate($request, null, $user->latestUploads); + return [ - 'files' => new FilesCollection($user->latestUploads), - 'root' => null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php index 902af769..0dc73125 100644 --- a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php +++ b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php @@ -5,12 +5,11 @@ use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; -use Domain\Folders\Resources\FolderCollection; +use Illuminate\Http\Request; class BrowseSharedItemsController { - public function __invoke(): array + public function __invoke(Request $request): array { $user_id = Auth::id(); @@ -36,11 +35,16 @@ class BrowseSharedItemsController ->sortable() ->get(); + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php index 994ac075..06428057 100644 --- a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php +++ b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php @@ -4,12 +4,11 @@ namespace Domain\Browsing\Controllers; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; -use Domain\Folders\Resources\FolderCollection; +use Illuminate\Http\Request; class BrowseTrashContentController { - public function __invoke(string $id): array + public function __invoke(Request $request, string $id): array { $user_id = Auth::id(); $root_id = $id === 'undefined' ? null : $id; @@ -29,43 +28,43 @@ class BrowseTrashContentController ->sortable() ->get(); - // Collect folders and files to single array - return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => $requestedFolder, - ]; - } - // Get folders and files - $folders_trashed = Folder::onlyTrashed() + } else { + // Get folders and files + $folders_trashed = Folder::onlyTrashed() ->with(['trashedFolders', 'parent']) ->where('user_id', $user_id) ->get(['parent_id', 'id', 'name']); - $folders = Folder::onlyTrashed() - ->with(['parent']) - ->where('user_id', $user_id) - ->whereIn('id', filter_folders_ids($folders_trashed)) - ->sortable() - ->get(); + $folders = Folder::onlyTrashed() + ->with(['parent']) + ->where('user_id', $user_id) + ->whereIn('id', filter_folders_ids($folders_trashed)) + ->sortable() + ->get(); - // Get files trashed - $files_trashed = File::onlyTrashed() - ->with(['parent']) - ->where('user_id', $user_id) - ->where(function ($query) use ($folders_trashed) { - $query->whereNull('parent_id'); - $query->orWhereNotIn('parent_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'id')))); - }) - ->sortable() - ->get(); + // Get files trashed + $files = File::onlyTrashed() + ->with(['parent']) + ->where('user_id', $user_id) + ->where(function ($query) use ($folders_trashed) { + $query->whereNull('parent_id'); + $query->orWhereNotIn('parent_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'id')))); + }) + ->sortable() + ->get(); + } + + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files_trashed), - 'root' => $requestedFolder, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $requestedFolder, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php index fc0ddaad..db32ca9f 100644 --- a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php @@ -4,11 +4,10 @@ namespace Domain\Browsing\Controllers; use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; use Domain\Sharing\Actions\ProtectShareRecordAction; use Domain\Sharing\Actions\VerifyAccessToItemAction; +use Illuminate\Http\Request; /** * Browse shared folder @@ -24,6 +23,7 @@ class VisitorBrowseFolderController public function __invoke( string $id, Share $shared, + Request $request, ): array { // Check ability to access protected share record ($this->protectShareRecord)($shared); @@ -48,10 +48,15 @@ class VisitorBrowseFolderController // Set thumbnail links for public files $files->map(fn ($file) => $file->setSharedPublicUrl($shared->token)); + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => new FolderResource($requestedFolder), + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => new FolderResource($requestedFolder), + ] ]; } } diff --git a/src/Domain/Files/Resources/FilesCollection.php b/src/Domain/Files/Resources/FilesCollection.php index 28f265a5..e2c50f93 100644 --- a/src/Domain/Files/Resources/FilesCollection.php +++ b/src/Domain/Files/Resources/FilesCollection.php @@ -1,16 +1,15 @@ $this->collection, - ]; + return $this->collection; } } diff --git a/src/Domain/Folders/Resources/FolderCollection.php b/src/Domain/Folders/Resources/FolderCollection.php index 5b00fcf3..4fd429c4 100644 --- a/src/Domain/Folders/Resources/FolderCollection.php +++ b/src/Domain/Folders/Resources/FolderCollection.php @@ -1,16 +1,15 @@ $this->collection, - ]; + return $this->collection; } } diff --git a/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php b/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php index 50cad2c0..4602528c 100644 --- a/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php +++ b/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php @@ -3,17 +3,16 @@ namespace Domain\Teams\Controllers; use Str; use Gate; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; class BrowseSharedWithMeController { - public function __invoke($id): array + public function __invoke(Request $request, $id): array { $id = Str::isUuid($id) ? $id : null; @@ -46,11 +45,16 @@ class BrowseSharedWithMeController ->get(); } + list($data, $paginate, $links) = groupPaginate($request, $folders, $files ?? null); + return [ - 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, - 'folders' => new FolderCollection($folders), - 'files' => isset($files) ? new FilesCollection($files) : new FilesCollection([]), + 'data' => $data, 'teamFolder' => $id ? new FolderResource($teamFolder) : null, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null + ] ]; } } diff --git a/src/Domain/Teams/Controllers/TeamFoldersController.php b/src/Domain/Teams/Controllers/TeamFoldersController.php index cc3f20f0..93d7b620 100644 --- a/src/Domain/Teams/Controllers/TeamFoldersController.php +++ b/src/Domain/Teams/Controllers/TeamFoldersController.php @@ -2,6 +2,7 @@ namespace Domain\Teams\Controllers; use Illuminate\Support\Str; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Illuminate\Http\Response; use Domain\Folders\Models\Folder; @@ -10,10 +11,8 @@ use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; use Domain\Teams\Models\TeamFolderMember; use Domain\Teams\DTO\CreateTeamFolderData; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; use Domain\Teams\Actions\UpdateMembersAction; -use Domain\Folders\Resources\FolderCollection; use Domain\Teams\Actions\UpdateInvitationsAction; use Illuminate\Contracts\Routing\ResponseFactory; use Domain\Teams\Requests\CreateTeamFolderRequest; @@ -29,7 +28,7 @@ class TeamFoldersController extends Controller ) { } - public function show($id): array + public function show(Request $request, $id): array { $id = Str::isUuid($id) ? $id : null; @@ -52,12 +51,17 @@ class TeamFoldersController extends Controller ->get(); } + list($data, $paginate, $links) = groupPaginate($request, $folders, $files ?? null); + // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => isset($files) ? new FilesCollection($files) : new FilesCollection([]), - 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, + 'data' => $data, 'teamFolder' => $id ? new FolderResource(Folder::findOrFail($id)->getLatestParent()) : null, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, + ] ]; } diff --git a/src/Support/helpers.php b/src/Support/helpers.php index f2a0ee1c..56263598 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -5,6 +5,7 @@ use ByteUnits\Metric; use App\Users\Models\User; use Illuminate\Support\Arr; use Illuminate\Support\Str; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; @@ -15,6 +16,8 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Storage; use Domain\Localization\Models\Language; +use Domain\Files\Resources\FilesCollection; +use Domain\Folders\Resources\FolderCollection; use Intervention\Image\ImageManagerStatic as Image; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -1148,4 +1151,52 @@ if (! function_exists('replace_occurrence')) { return "{$degrees}°$minutes'$seconds\"$ref"; } } + + if(! function_exists('groupPaginate')) { + /** + * Group paginate of Foldes and Files + */ + function groupPaginate( + Request $request, + ?Collection $folders = null, + ?Collection $files = null + ) : array { + + $perPage = config('vuefilemanager.paginate.perPage'); + $currentPage = $request->get('page'); + + // Collect Folders with Files + $entries = collect([ + $folders ? json_decode((new FolderCollection($folders))->toJson(), true) : null, + $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, + ])->collapse(); + + // Paginate grouped Folders and Files + $groupPaginate = $entries->forPage($currentPage, $perPage)->values(); + + $uri = $request->fullUrl(); + + $lastPage = ceil(count($entries) / $perPage); + + return [ + $groupPaginate, + [ + 'currentPage' => (int)$currentPage, + 'from' => 1, + 'lastPage' => $lastPage, + 'path' => $uri, + 'perPage' => $perPage, + 'to' => $perPage, + 'total' => count($entries), + ], + [ + 'first' => $uri . '&page=' . 1, + 'last' => $uri . '&page=' . $lastPage, + 'next' => $currentPage == $lastPage ? null : $uri . '&page=' . $currentPage + 1, + 'prev' => $currentPage == 1 ? null : $uri . '&page=' . $currentPage -1, + ] + ]; + } + } + } From d71e59875816a316d5b83752e3ee15f449775476 Mon Sep 17 00:00:00 2001 From: Milos Holba Date: Thu, 7 Apr 2022 12:56:01 +0200 Subject: [PATCH 2/5] added possibility to return all record --- public/mix-manifest.json | 16 ++++++++-------- .../js/components/FilesView/FileBrowser.vue | 4 ++-- resources/views/index.blade.php | 1 - src/Support/helpers.php | 13 +++++++++---- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/public/mix-manifest.json b/public/mix-manifest.json index eb14b871..ba311da0 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,7 +1,7 @@ { "/js/main.js": "/js/main.js", "/chunks/request.js": "/chunks/request.js?id=e12cca6ff4d753a0", - "/chunks/request-upload.js": "/chunks/request-upload.js?id=6162439c4476a9fb", + "/chunks/request-upload.js": "/chunks/request-upload.js?id=6f7ff06d99abc1db", "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=e8b9ac5e5a0854bf", "/chunks/status-check.js": "/chunks/status-check.js?id=4c7482ca1bc4806d", "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=95910a6098545b18", @@ -10,7 +10,7 @@ "/chunks/app-setup.js": "/chunks/app-setup.js?id=fac96a371fa057a9", "/chunks/admin-account.js": "/chunks/admin-account.js?id=f207f8887394310d", "/chunks/shared.js": "/chunks/shared.js?id=cdfbac570212aaba", - "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=eb7d18bbc0ac131a", + "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=82de4b533b350338", "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=fda3ee1897218fb4", "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=a68c497e91a6fadb", "/chunks/not-found.js": "/chunks/not-found.js?id=cbcb2fcb42696af3", @@ -63,12 +63,12 @@ "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=e6866a6ffd9c3a80", "/chunks/billing.js": "/chunks/billing.js?id=ce81cf6583d26d4c", "/chunks/platform.js": "/chunks/platform.js?id=8899666aebaf9db4", - "/chunks/files.js": "/chunks/files.js?id=5f981e4f05062e30", - "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=3469cce1ee71c03c", - "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=2f712e064ac8e575", - "/chunks/trash.js": "/chunks/trash.js?id=2df58d71ed9f7ea2", - "/chunks/team-folders.js": "/chunks/team-folders.js?id=7bda1a54e372f0de", - "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=f8eec4a942b431a0", + "/chunks/files.js": "/chunks/files.js?id=a6dbd9f43e4eb694", + "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=8f087976e1d1af41", + "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=969ac9f4297e1179", + "/chunks/trash.js": "/chunks/trash.js?id=da9791f0f6155a99", + "/chunks/team-folders.js": "/chunks/team-folders.js?id=88bce3b12b4dce95", + "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=45b03e5063720b33", "/chunks/invitation.js": "/chunks/invitation.js?id=3220065b746aa8fe", "/css/tailwind.css": "/css/tailwind.css", "/css/app.css": "/css/app.css" diff --git a/resources/js/components/FilesView/FileBrowser.vue b/resources/js/components/FilesView/FileBrowser.vue index 14c451af..515e887c 100644 --- a/resources/js/components/FilesView/FileBrowser.vue +++ b/resources/js/components/FilesView/FileBrowser.vue @@ -65,7 +65,7 @@ export default { return this.paginate.paginate.currentPage !== this.paginate.paginate.lastPage }, showInfiniteLoadSpinner() { - return this.continueInfiniteScroll && this.entries.length !== 0 && config.itemsPerPage <= this.entries.length + return this.continueInfiniteScroll && this.entries.length !== 0 && this.paginate.paginate.perPage <= this.entries.length }, }, data() { @@ -90,7 +90,7 @@ export default { } }, elementInViewport() { - var item = document.getElementById('infinite-loader') + var item = document.getElementById('infinite-loader') var rect = item.getBoundingClientRect() return ( diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index d4ede93f..a9a93617 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -180,7 +180,6 @@ // App settings userRegistration: {{ $settings->registration ?? 1 }}, userVerification: {{ $settings->user_verification ?? 0 }}, - itemsPerPage: {{ config('vuefilemanager.paginate.perPage') }}, } diff --git a/src/Support/helpers.php b/src/Support/helpers.php index 56263598..23152911 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -1163,7 +1163,7 @@ if (! function_exists('replace_occurrence')) { ) : array { $perPage = config('vuefilemanager.paginate.perPage'); - $currentPage = $request->get('page'); + $currentPage = $request->get('page') === 'all' ? 1 : (int)$request->get('page'); // Collect Folders with Files $entries = collect([ @@ -1171,8 +1171,13 @@ if (! function_exists('replace_occurrence')) { $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, ])->collapse(); - // Paginate grouped Folders and Files - $groupPaginate = $entries->forPage($currentPage, $perPage)->values(); + if($request->input('page') === 'all') { + // If is page set to 'all' return all records + $groupPaginate = $entries; + } else { + // Paginate grouped Folders and Files + $groupPaginate = $entries->forPage($currentPage, $perPage)->values(); + } $uri = $request->fullUrl(); @@ -1181,7 +1186,7 @@ if (! function_exists('replace_occurrence')) { return [ $groupPaginate, [ - 'currentPage' => (int)$currentPage, + 'currentPage' => $currentPage, 'from' => 1, 'lastPage' => $lastPage, 'path' => $uri, From ad8793ce282fb51aaef5ec3c2e94cc6704131f93 Mon Sep 17 00:00:00 2001 From: Milos Holba Date: Thu, 14 Apr 2022 16:25:57 +0200 Subject: [PATCH 3/5] change of the browsing functionality --- config/vuefilemanager.php | 2 +- .../Controllers/BrowseFolderController.php | 34 +++++--- src/Support/helpers.php | 83 +++++++++++++++---- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/config/vuefilemanager.php b/config/vuefilemanager.php index 6dfff8d1..099cce35 100644 --- a/config/vuefilemanager.php +++ b/config/vuefilemanager.php @@ -62,6 +62,6 @@ return [ ], 'paginate' => [ - 'perPage' => 50 + 'perPage' => 15 ] ]; diff --git a/src/Domain/Browsing/Controllers/BrowseFolderController.php b/src/Domain/Browsing/Controllers/BrowseFolderController.php index 0d42c906..774bbbac 100644 --- a/src/Domain/Browsing/Controllers/BrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/BrowseFolderController.php @@ -2,7 +2,6 @@ namespace Domain\Browsing\Controllers; use Str; -use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; @@ -11,25 +10,40 @@ use Domain\Folders\Resources\FolderResource; class BrowseFolderController { public function __invoke( - Request $request, string $id, ): array { $root_id = Str::isUuid($id) ? $id : null; + $folderQuery = [ + 'parent_id' => $root_id, + 'team_folder' => false, + 'user_id' => Auth::id(), + 'deleted_at' => null + ]; + + $fileQuery = [ + 'parent_id' => $root_id, + 'user_id' => Auth::id(), + 'deleted_at' => null + ]; + + list($foldersTake, $foldersSkip, $filesTake, $filesSkip, $totalItemsCount) = getRecordsCount($folderQuery, $fileQuery); + $folders = Folder::with(['parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in']) - ->where('parent_id', $root_id) - ->where('team_folder', false) - ->where('user_id', Auth::id()) + ->where($folderQuery) ->sortable() + ->skip($foldersSkip) + ->take($foldersTake) ->get(); - + $files = File::with(['parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in']) - ->where('parent_id', $root_id) - ->where('user_id', Auth::id()) + ->where($fileQuery) ->sortable() + ->skip($filesSkip) + ->take($filesTake) ->get(); - - list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + + list($data, $paginate, $links) = groupPaginate($folders, $files, $totalItemsCount); return [ 'data' => $data, diff --git a/src/Support/helpers.php b/src/Support/helpers.php index 23152911..d263a980 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -5,12 +5,12 @@ use ByteUnits\Metric; use App\Users\Models\User; use Illuminate\Support\Arr; use Illuminate\Support\Str; -use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; use Illuminate\Support\Collection; use Domain\Settings\Models\Setting; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Http; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\QueryException; @@ -1157,13 +1157,13 @@ if (! function_exists('replace_occurrence')) { * Group paginate of Foldes and Files */ function groupPaginate( - Request $request, ?Collection $folders = null, - ?Collection $files = null + ?Collection $files = null, + int $totalItemsCount ) : array { $perPage = config('vuefilemanager.paginate.perPage'); - $currentPage = $request->get('page') === 'all' ? 1 : (int)$request->get('page'); + $currentPage = request()->input('page') === 'all' ? 1 : (int)request()->input('page'); // Collect Folders with Files $entries = collect([ @@ -1171,20 +1171,11 @@ if (! function_exists('replace_occurrence')) { $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, ])->collapse(); - if($request->input('page') === 'all') { - // If is page set to 'all' return all records - $groupPaginate = $entries; - } else { - // Paginate grouped Folders and Files - $groupPaginate = $entries->forPage($currentPage, $perPage)->values(); - } - - $uri = $request->fullUrl(); - - $lastPage = ceil(count($entries) / $perPage); + $uri = request()->fullUrl(); + $lastPage = ceil($totalItemsCount / $perPage); return [ - $groupPaginate, + $entries, [ 'currentPage' => $currentPage, 'from' => 1, @@ -1192,7 +1183,7 @@ if (! function_exists('replace_occurrence')) { 'path' => $uri, 'perPage' => $perPage, 'to' => $perPage, - 'total' => count($entries), + 'total' => $totalItemsCount, ], [ 'first' => $uri . '&page=' . 1, @@ -1202,6 +1193,62 @@ if (! function_exists('replace_occurrence')) { ] ]; } - } + if(! function_exists('getRecordsCount')) { + /** + * Get count of items from the Database + */ + function getRecordsCount ( + array $folderQuery, + array $fileQuery + ) : array { + + $perPage = config('vuefilemanager.paginate.perPage'); + $currentPage = request()->input('page') === 'all' ? 1 : (int)request()->input('page'); + + $foldersSkip = 0; + $foldersTake = 0; + $filesSkip = 0; + $filesTake = 0; + + $foldersCount = DB::table('folders') + ->where($folderQuery) + ->count(); + + $filesCount = DB::table('files') + ->where($fileQuery) + ->count(); + + $totalItemsCount = $foldersCount + $filesCount; + + if(request()->input('page') !== 'all') { + + // Folders pages + if($foldersCount >= $currentPage * $perPage) { + $foldersTake = $perPage; + $foldersSkip = ($currentPage - 1) * $perPage; + } + + // Mixed page + if($foldersCount < $currentPage * $perPage && ceil($currentPage) === ceil($foldersCount / $perPage) ) { + $foldersSkip = ($currentPage - 1) * $perPage; + $foldersTake = $foldersCount - $foldersSkip; + $filesTake = ($currentPage * $perPage) - $foldersCount; + $filesSkip = 0; + } + + // Files pages + if($currentPage > ceil($foldersCount / $perPage)) { + $filesTake = $perPage; + $filesSkip = ((ceil($foldersCount / $perPage) * $perPage) - $foldersCount) + ($currentPage - (ceil($foldersCount / $perPage)) -1) * $perPage; + } + } else { + $foldersTake = $foldersCount; + $filesTake = $filesCount; + } + + return [$foldersTake, $foldersSkip, $filesTake, $filesSkip, $totalItemsCount]; + } + } + } } From f75c20e5a70d5a14ae42977912fa5de447d44668 Mon Sep 17 00:00:00 2001 From: Milos Holba Date: Mon, 2 May 2022 18:21:20 +0200 Subject: [PATCH 4/5] added test for getRecordsCount, format code --- config/language-translations.php | 8 +-- config/vuefilemanager.php | 4 +- src/App/Providers/AppServiceProvider.php | 2 +- .../SocialiteCallbackController.php | 10 +-- src/App/Users/Actions/UpdateUserPassword.php | 5 +- .../Controllers/BrowseFolderController.php | 19 ++++-- .../BrowseLatestFilesController.php | 4 +- .../BrowseSharedItemsController.php | 4 +- .../BrowseTrashContentController.php | 12 ++-- .../VisitorBrowseFolderController.php | 4 +- .../Actions/GenerateImageThumbnailAction.php | 1 - .../Controllers/UploadFileController.php | 4 +- src/Domain/Files/Requests/UploadRequest.php | 1 - .../RenameFileOrFolderController.php | 4 +- .../CreateAdminAccountController.php | 2 +- .../BrowseSharedWithMeController.php | 4 +- .../Controllers/TeamFoldersController.php | 2 +- .../InvitationIntoTeamFolder.php | 2 +- .../UploadRequestFulfilledNotification.php | 6 +- src/Support/helpers.php | 63 ++++++++----------- tests/App/Users/SignFlowTest.php | 1 - .../Languages/AdminLanguageTranslatorTest.php | 4 +- tests/Domain/SetupWizard/SetupWizardTest.php | 26 ++++---- tests/Support/Helpers/HelperTest.php | 57 +++++++++++++++++ 24 files changed, 147 insertions(+), 102 deletions(-) diff --git a/config/language-translations.php b/config/language-translations.php index 0db97fd3..50a542fc 100644 --- a/config/language-translations.php +++ b/config/language-translations.php @@ -905,7 +905,7 @@ return [ 'total_x_of_x_members' => 'Total ${use} of ${total} Members', 'go_back_from_x' => 'Go back from {location}', 'new_team_invitation' => 'New Team Invitation', - 'x_invite_to_join_team' => ":name invite you to join into Team Folder.", + 'x_invite_to_join_team' => ':name invite you to join into Team Folder.', 'team_invitation_notify_title' => 'You are invited to collaboration with team folder in :app', 'team_invitation_notify_desc' => 'You are invited to collaboration with team folder', 'team_invitation_notify_desc_without_account' => 'You are invited to collaboration with team folder. But at first, you have to create an account to proceed into team folder.', @@ -915,12 +915,12 @@ return [ 'file_request_filled_desc' => "Your file request for ':name' folder was filled successfully.", 'show_files' => 'Show Files', 'file_request_filled_mail' => "Your file request was fulfilled in your ':name' folder", - 'file_request_filled_mail_note' => "We are emailing you because your file request was fulfilled. Please click on the link below to show uploaded files.", + 'file_request_filled_mail_note' => 'We are emailing you because your file request was fulfilled. Please click on the link below to show uploaded files.', 'thanks_salutation' => 'Thank you for using our application!', 'upload_your_files' => 'Upload your Files', - 'file_request_optional_message' => "PS: :name left you a message: :notes", + 'file_request_optional_message' => 'PS: :name left you a message: :notes', 'file_request_notify_title' => ':name Request You for File Upload', - 'file_request_notify_description' => "We are emailing you because :name requested files from you. Please click on the link below and upload your files for :name.", + 'file_request_notify_description' => 'We are emailing you because :name requested files from you. Please click on the link below and upload your files for :name.', 'user_action_not_allowed' => 'This user action is not allowed.', 'pcs.' => 'Pcs.', 'mem.' => 'Mem.', diff --git a/config/vuefilemanager.php b/config/vuefilemanager.php index 099cce35..74c3164f 100644 --- a/config/vuefilemanager.php +++ b/config/vuefilemanager.php @@ -62,6 +62,6 @@ return [ ], 'paginate' => [ - 'perPage' => 15 - ] + 'perPage' => 15, + ], ]; diff --git a/src/App/Providers/AppServiceProvider.php b/src/App/Providers/AppServiceProvider.php index 18a24794..4665d294 100644 --- a/src/App/Providers/AppServiceProvider.php +++ b/src/App/Providers/AppServiceProvider.php @@ -1,8 +1,8 @@ 'error', 'message' => 'User registration is not allowed', diff --git a/src/App/Users/Actions/UpdateUserPassword.php b/src/App/Users/Actions/UpdateUserPassword.php index 3e5b2112..309116df 100644 --- a/src/App/Users/Actions/UpdateUserPassword.php +++ b/src/App/Users/Actions/UpdateUserPassword.php @@ -1,10 +1,9 @@ ['required', 'string'], 'password' => $this->passwordRules(), ])->after(function ($validator) use ($user, $input) { - if (!isset($input['current_password']) || !Hash::check($input['current_password'], $user->password)) { + if (! isset($input['current_password']) || ! Hash::check($input['current_password'], $user->password)) { $validator->errors()->add('current_password', __t('password_doesnt_match')); } })->validateWithBag('updatePassword'); diff --git a/src/Domain/Browsing/Controllers/BrowseFolderController.php b/src/Domain/Browsing/Controllers/BrowseFolderController.php index 774bbbac..6a19e726 100644 --- a/src/Domain/Browsing/Controllers/BrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/BrowseFolderController.php @@ -5,7 +5,9 @@ use Str; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; +use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; +use Domain\Folders\Resources\FolderCollection; class BrowseFolderController { @@ -18,16 +20,16 @@ class BrowseFolderController 'parent_id' => $root_id, 'team_folder' => false, 'user_id' => Auth::id(), - 'deleted_at' => null + 'deleted_at' => null, ]; $fileQuery = [ 'parent_id' => $root_id, 'user_id' => Auth::id(), - 'deleted_at' => null + 'deleted_at' => null, ]; - list($foldersTake, $foldersSkip, $filesTake, $filesSkip, $totalItemsCount) = getRecordsCount($folderQuery, $fileQuery); + list($foldersTake, $foldersSkip, $filesTake, $filesSkip, $totalItemsCount) = getRecordsCount($folderQuery, $fileQuery, request()->input('page')); $folders = Folder::with(['parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in']) ->where($folderQuery) @@ -42,16 +44,21 @@ class BrowseFolderController ->skip($filesSkip) ->take($filesTake) ->get(); + + $entries = collect([ + $folders ? json_decode((new FolderCollection($folders))->toJson(), true) : null, + $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, + ])->collapse(); - list($data, $paginate, $links) = groupPaginate($folders, $files, $totalItemsCount); + list($paginate, $links) = generatePaginationCounts($totalItemsCount); return [ - 'data' => $data, + 'data' => $entries, 'links' => $links, 'meta' => [ 'paginate' => $paginate, 'root' => $root_id ? new FolderResource(Folder::findOrFail($root_id)) : null, - ] + ], ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php index 556f50fb..5572300b 100644 --- a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php +++ b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php @@ -2,8 +2,8 @@ namespace Domain\Browsing\Controllers; use App\Users\Models\User; -use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class BrowseLatestFilesController { @@ -23,7 +23,7 @@ class BrowseLatestFilesController 'meta' => [ 'paginate' => $paginate, 'root' => null, - ] + ], ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php index 0dc73125..03282375 100644 --- a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php +++ b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php @@ -1,11 +1,11 @@ [ 'paginate' => $paginate, 'root' => null, - ] + ], ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php index 06428057..e49ad47a 100644 --- a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php +++ b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php @@ -1,10 +1,10 @@ where('parent_id', $root_id) ->sortable() ->get(); - - } else { // Get folders and files $folders_trashed = Folder::onlyTrashed() - ->with(['trashedFolders', 'parent']) - ->where('user_id', $user_id) - ->get(['parent_id', 'id', 'name']); + ->with(['trashedFolders', 'parent']) + ->where('user_id', $user_id) + ->get(['parent_id', 'id', 'name']); $folders = Folder::onlyTrashed() ->with(['parent']) @@ -64,7 +62,7 @@ class BrowseTrashContentController 'meta' => [ 'paginate' => $paginate, 'root' => $requestedFolder, - ] + ], ]; } } diff --git a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php index db32ca9f..5dad77fb 100644 --- a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php @@ -1,13 +1,13 @@ [ 'paginate' => $paginate, 'root' => new FolderResource($requestedFolder), - ] + ], ]; } } diff --git a/src/Domain/Files/Actions/GenerateImageThumbnailAction.php b/src/Domain/Files/Actions/GenerateImageThumbnailAction.php index 2fe5bd3a..2d51d6ed 100644 --- a/src/Domain/Files/Actions/GenerateImageThumbnailAction.php +++ b/src/Domain/Files/Actions/GenerateImageThumbnailAction.php @@ -19,7 +19,6 @@ class GenerateImageThumbnailAction collect(config("vuefilemanager.image_sizes.$execution")) ->each(function ($size) use ($userId, $fileName, $imageWidth) { if ($imageWidth > $size['size']) { - // Create intervention image $intervention = Image::make( Storage::disk('local')->path("temp/$userId/$fileName") diff --git a/src/Domain/Files/Controllers/UploadFileController.php b/src/Domain/Files/Controllers/UploadFileController.php index 747dcf2c..1e3d7b6c 100644 --- a/src/Domain/Files/Controllers/UploadFileController.php +++ b/src/Domain/Files/Controllers/UploadFileController.php @@ -2,7 +2,6 @@ namespace Domain\Files\Controllers; use Domain\Files\Models\File; -use Illuminate\Http\Response; use App\Http\Controllers\Controller; use Domain\Files\Requests\UploadRequest; use Domain\Files\Resources\FileResource; @@ -21,7 +20,8 @@ class UploadFileController extends Controller /** * Upload file for authenticated master|editor user */ - public function __invoke(UploadRequest $request) { + public function __invoke(UploadRequest $request) + { if (is_demo_account()) { return ($this->fakeUploadFile)($request); } diff --git a/src/Domain/Files/Requests/UploadRequest.php b/src/Domain/Files/Requests/UploadRequest.php index 5a41a0fe..b4c01645 100644 --- a/src/Domain/Files/Requests/UploadRequest.php +++ b/src/Domain/Files/Requests/UploadRequest.php @@ -1,5 +1,4 @@ $links, 'meta' => [ 'paginate' => $paginate, - 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null - ] + 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, + ], ]; } } diff --git a/src/Domain/Teams/Controllers/TeamFoldersController.php b/src/Domain/Teams/Controllers/TeamFoldersController.php index 93d7b620..19849a02 100644 --- a/src/Domain/Teams/Controllers/TeamFoldersController.php +++ b/src/Domain/Teams/Controllers/TeamFoldersController.php @@ -61,7 +61,7 @@ class TeamFoldersController extends Controller 'meta' => [ 'paginate' => $paginate, 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, - ] + ], ]; } diff --git a/src/Domain/Teams/Notifications/InvitationIntoTeamFolder.php b/src/Domain/Teams/Notifications/InvitationIntoTeamFolder.php index ebdd0900..f2d1d624 100644 --- a/src/Domain/Teams/Notifications/InvitationIntoTeamFolder.php +++ b/src/Domain/Teams/Notifications/InvitationIntoTeamFolder.php @@ -61,7 +61,7 @@ class InvitationIntoTeamFolder extends Notification implements ShouldQueue return [ 'category' => 'team-invitation', 'title' => __t('new_team_invitation'), - 'description' => __t('x_invite_to_join_team', ['name' => $this->invitation->inviter->settings->name,]), + 'description' => __t('x_invite_to_join_team', ['name' => $this->invitation->inviter->settings->name, ]), 'action' => [ 'type' => 'invitation', 'params' => [ diff --git a/src/Domain/UploadRequest/Notifications/UploadRequestFulfilledNotification.php b/src/Domain/UploadRequest/Notifications/UploadRequestFulfilledNotification.php index 5b044ca5..cc7a1c4a 100644 --- a/src/Domain/UploadRequest/Notifications/UploadRequestFulfilledNotification.php +++ b/src/Domain/UploadRequest/Notifications/UploadRequestFulfilledNotification.php @@ -1,5 +1,4 @@ 'file-request', 'title' => __t('file_request_filled'), - 'description' => __t('file_request_filled_desc', ['name' => $this->uploadRequest->parent->name,]), + 'description' => __t('file_request_filled_desc', ['name' => $this->uploadRequest->parent->name, ]), 'action' => [ 'type' => 'route', 'params' => [ diff --git a/src/Support/helpers.php b/src/Support/helpers.php index d263a980..e5ef6a15 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -9,15 +9,13 @@ use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; use Illuminate\Support\Collection; -use Domain\Settings\Models\Setting; use Illuminate\Support\Facades\DB; +use Domain\Settings\Models\Setting; use Illuminate\Support\Facades\Http; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Storage; use Domain\Localization\Models\Language; -use Domain\Files\Resources\FilesCollection; -use Domain\Folders\Resources\FolderCollection; use Intervention\Image\ImageManagerStatic as Image; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -1152,30 +1150,20 @@ if (! function_exists('replace_occurrence')) { } } - if(! function_exists('groupPaginate')) { + if (! function_exists('generatePaginationCounts')) { /** * Group paginate of Foldes and Files */ - function groupPaginate( - ?Collection $folders = null, - ?Collection $files = null, + function generatePaginationCounts( int $totalItemsCount ) : array { - $perPage = config('vuefilemanager.paginate.perPage'); - $currentPage = request()->input('page') === 'all' ? 1 : (int)request()->input('page'); - - // Collect Folders with Files - $entries = collect([ - $folders ? json_decode((new FolderCollection($folders))->toJson(), true) : null, - $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, - ])->collapse(); + $currentPage = request()->input('page') === 'all' ? 1 : (int) request()->input('page'); $uri = request()->fullUrl(); $lastPage = ceil($totalItemsCount / $perPage); return [ - $entries, [ 'currentPage' => $currentPage, 'from' => 1, @@ -1188,28 +1176,29 @@ if (! function_exists('replace_occurrence')) { [ 'first' => $uri . '&page=' . 1, 'last' => $uri . '&page=' . $lastPage, - 'next' => $currentPage == $lastPage ? null : $uri . '&page=' . $currentPage + 1, - 'prev' => $currentPage == 1 ? null : $uri . '&page=' . $currentPage -1, - ] + 'next' => $currentPage == $lastPage ? null : $uri . '&page=' . $currentPage + 1, + 'prev' => $currentPage == 1 ? null : $uri . '&page=' . $currentPage - 1, + ], ]; } - - if(! function_exists('getRecordsCount')) { + } + + if (! function_exists('getRecordsCount')) { /** * Get count of items from the Database */ - function getRecordsCount ( - array $folderQuery, - array $fileQuery - ) : array { - + function getRecordsCount( + array $folderQuery, + array $fileQuery, + string $page + ) : array { $perPage = config('vuefilemanager.paginate.perPage'); - $currentPage = request()->input('page') === 'all' ? 1 : (int)request()->input('page'); + $currentPage = $page === 'all' ? 1 : (int) $page; $foldersSkip = 0; $foldersTake = 0; - $filesSkip = 0; - $filesTake = 0; + $filesSkip = 0; + $filesTake = 0; $foldersCount = DB::table('folders') ->where($folderQuery) @@ -1221,34 +1210,32 @@ if (! function_exists('replace_occurrence')) { $totalItemsCount = $foldersCount + $filesCount; - if(request()->input('page') !== 'all') { - + if ($page !== 'all') { // Folders pages - if($foldersCount >= $currentPage * $perPage) { + if ($foldersCount >= $currentPage * $perPage) { $foldersTake = $perPage; $foldersSkip = ($currentPage - 1) * $perPage; } // Mixed page - if($foldersCount < $currentPage * $perPage && ceil($currentPage) === ceil($foldersCount / $perPage) ) { + if ($foldersCount < $currentPage * $perPage && ceil($currentPage) === ceil($foldersCount / $perPage)) { $foldersSkip = ($currentPage - 1) * $perPage; $foldersTake = $foldersCount - $foldersSkip; - $filesTake = ($currentPage * $perPage) - $foldersCount; + $filesTake = ($currentPage * $perPage) - $foldersCount; $filesSkip = 0; } // Files pages - if($currentPage > ceil($foldersCount / $perPage)) { + if ($currentPage > ceil($foldersCount / $perPage)) { $filesTake = $perPage; - $filesSkip = ((ceil($foldersCount / $perPage) * $perPage) - $foldersCount) + ($currentPage - (ceil($foldersCount / $perPage)) -1) * $perPage; + $filesSkip = ((ceil($foldersCount / $perPage) * $perPage) - $foldersCount) + ($currentPage - (ceil($foldersCount / $perPage)) - 1) * $perPage; } } else { $foldersTake = $foldersCount; - $filesTake = $filesCount; + $filesTake = $filesCount; } return [$foldersTake, $foldersSkip, $filesTake, $filesSkip, $totalItemsCount]; } - } } } diff --git a/tests/App/Users/SignFlowTest.php b/tests/App/Users/SignFlowTest.php index ec8bf448..bc892d86 100644 --- a/tests/App/Users/SignFlowTest.php +++ b/tests/App/Users/SignFlowTest.php @@ -1,5 +1,4 @@ assertStatus(200) ->assertJsonFragment([ 'locale' => 'en', - 'close' => 'Close', + 'close' => 'Close', ]); } @@ -180,7 +180,7 @@ class AdminLanguageTranslatorTest extends TestCase ->getJson("/api/admin/languages/$language->id") ->assertStatus(200) ->assertJsonFragment([ - 'close' => 'Close', + 'close' => 'Close', 'locale' => 'en', ]); } diff --git a/tests/Domain/SetupWizard/SetupWizardTest.php b/tests/Domain/SetupWizard/SetupWizardTest.php index 30030d2c..2ba0bbde 100644 --- a/tests/Domain/SetupWizard/SetupWizardTest.php +++ b/tests/Domain/SetupWizard/SetupWizardTest.php @@ -61,21 +61,21 @@ class SetupWizardTest extends TestCase Setting::all()->each->delete(); $this->postJson('/api/setup/app-setup', [ - 'color' => '#00BC72', - 'title' => 'VueFileManager', - 'description' => 'The best file manager on the internet', - 'googleAnalytics' => 'UA-12345678-1', - 'contactMail' => 'john@doe.com', - 'subscriptionType' => 'metered', - 'userVerification' => 1, - 'userRegistration' => 1, - 'storageLimitation' => 1, - 'defaultStorage' => 10, - 'logo' => UploadedFile::fake()->image('fake-logo.jpg'), + 'color' => '#00BC72', + 'title' => 'VueFileManager', + 'description' => 'The best file manager on the internet', + 'googleAnalytics' => 'UA-12345678-1', + 'contactMail' => 'john@doe.com', + 'subscriptionType' => 'metered', + 'userVerification' => 1, + 'userRegistration' => 1, + 'storageLimitation' => 1, + 'defaultStorage' => 10, + 'logo' => UploadedFile::fake()->image('fake-logo.jpg'), 'logo_dark' => UploadedFile::fake()->image('fake-logo-dark.jpg'), - 'logo_horizontal' => UploadedFile::fake()->image('fake-logo-horizontal.jpg'), + 'logo_horizontal' => UploadedFile::fake()->image('fake-logo-horizontal.jpg'), 'logo_horizontal_dark' => UploadedFile::fake()->image('fake-logo-horizontal-dark.jpg'), - 'favicon' => UploadedFile::fake()->image('fake-favicon.jpg'), + 'favicon' => UploadedFile::fake()->image('fake-favicon.jpg'), ])->assertStatus(204); $this diff --git a/tests/Support/Helpers/HelperTest.php b/tests/Support/Helpers/HelperTest.php index c5d156d9..6c44ea0b 100644 --- a/tests/Support/Helpers/HelperTest.php +++ b/tests/Support/Helpers/HelperTest.php @@ -2,6 +2,10 @@ namespace Tests\Support\Helpers; use Tests\TestCase; +use App\Users\Models\User; +use Domain\Files\Models\File; +use Domain\Folders\Models\Folder; +use Illuminate\Support\Facades\Config; class HelperTest extends TestCase { @@ -25,4 +29,57 @@ class HelperTest extends TestCase $this->assertEquals('Jane', $thirdTest['first_name']); $this->assertEquals('', $thirdTest['last_name']); } + + /** + * @test + */ + public function it_test_get_records_count() + { + $user = User::factory() + ->hasSettings() + ->create(); + + Folder::factory() + ->count(12) + ->create([ + 'user_id' => $user->id, + 'parent_id' => null, + ]); + + File::factory() + ->count(13) + ->create([ + 'user_id' => $user->id, + 'parent_id' => null, + ]); + + $folderQuery = [ + 'parent_id' => null, + 'team_folder' => false, + 'user_id' => $user->id, + 'deleted_at' => null, + ]; + + $fileQuery = [ + 'parent_id' => null, + 'user_id' => $user->id, + 'deleted_at' => null, + ]; + + Config::set('vuefilemanager.paginate.perPage', 5); + + // getRecordsCunt returned array [foldersTake, foldersSkip, filesTake, filesSkip, totalItemsCount] + + // Get folders page + $this->assertEquals([5, 0, 0, 0, 25], getRecordsCount($folderQuery, $fileQuery, '1')); + + // Get mixed page + $this->assertEquals([2, 10, 3, 0, 25], getRecordsCount($folderQuery, $fileQuery, '3')); + + // Get files page + $this->assertEquals([0, 0, 5, 8, 25], getRecordsCount($folderQuery, $fileQuery, '5')); + + // Get all pages + $this->assertEquals([12, 0, 13, 0, 25], getRecordsCount($folderQuery, $fileQuery, 'all')); + } } From 36c5e51b4f828b2b562379c6993d1560ab816e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Carodej?= Date: Tue, 24 May 2022 10:01:07 +0200 Subject: [PATCH 5/5] refactoring --- config/vuefilemanager.php | 2 +- package-lock.json | 188 ++++++++++-------- package.json | 18 +- public/mix-manifest.json | 140 ++++++------- .../js/components/FilesView/FileBrowser.vue | 57 +++--- resources/js/store/modules/fileBrowser.js | 18 +- resources/js/store/modules/sharing.js | 4 +- resources/js/store/modules/teams.js | 8 +- src/Support/helpers.php | 2 +- 9 files changed, 218 insertions(+), 219 deletions(-) diff --git a/config/vuefilemanager.php b/config/vuefilemanager.php index 74c3164f..fd0a19a4 100644 --- a/config/vuefilemanager.php +++ b/config/vuefilemanager.php @@ -62,6 +62,6 @@ return [ ], 'paginate' => [ - 'perPage' => 15, + 'perPage' => 8, ], ]; diff --git a/package-lock.json b/package-lock.json index 105b2756..70c5011d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1231,9 +1231,9 @@ } }, "@stripe/stripe-js": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.24.0.tgz", - "integrity": "sha512-8CEILOpzoRhGwvgcf6y+BlPyEq1ZqxAv3gsX7LvokFYvbcyH72GRcHQMGXuZS3s7HqfYQuTSFrvZNL/qdkgA9Q==" + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.29.0.tgz", + "integrity": "sha512-OsUxk0VLlum8E2d6onlEdKuQcvLMs7qTrOXCnl/BGV3fAm65qr6h3e1IZ5AX4lgUlPRrzRcddSOA5DvkKKYLvg==" }, "@trysound/sax": { "version": "0.2.0", @@ -2088,17 +2088,50 @@ "dev": true }, "autoprefixer": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", - "integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==", + "version": "10.4.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz", + "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==", "dev": true, "requires": { - "browserslist": "^4.19.1", - "caniuse-lite": "^1.0.30001297", - "fraction.js": "^4.1.2", + "browserslist": "^4.20.3", + "caniuse-lite": "^1.0.30001335", + "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" + }, + "dependencies": { + "browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001342", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001342.tgz", + "integrity": "sha512-bn6sOCu7L7jcbBbyNhLg0qzXdJ/PMbybZTH/BA6Roet9wxYRm6Tr9D0s0uhLkOZ6MSG+QU6txUgdpr3MXIVqjA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + } } }, "aws-sign2": { @@ -4159,9 +4192,9 @@ "dev": true }, "fraction.js": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", - "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", "dev": true }, "fresh": { @@ -4761,9 +4794,9 @@ } }, "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "import-fresh": { @@ -5252,9 +5285,9 @@ "dev": true }, "laravel-echo": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.11.3.tgz", - "integrity": "sha512-VNTnnoF8gK29ovxslnrFDt3xgrKiKKW1kTnKKO1A4kYVj4UCKmNO4x2ehRlfg2UTrG/oggwk95p+S9ftQYjXdw==", + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.11.7.tgz", + "integrity": "sha512-LhEZp/RbdtdMlhptJyn452+aXfz+A1UW2bhJM7NROgXhnNgj+6P9BkG9JcPCBMernp5TGkOGI6A0NPbkAWYWGg==", "dev": true }, "laravel-mix": { @@ -5980,9 +6013,9 @@ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true }, "negotiator": { @@ -6259,9 +6292,9 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true }, "object-is": { @@ -6657,12 +6690,12 @@ } }, "postcss": { - "version": "8.4.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.8.tgz", - "integrity": "sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==", + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", "dev": true, "requires": { - "nanoid": "^3.3.1", + "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -7047,9 +7080,9 @@ } }, "prettier-plugin-tailwindcss": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.8.tgz", - "integrity": "sha512-hwarSBCswAXa+kqYtaAkFr3Vop9o04WOyZs0qo3NyvW8L7f1rif61wRyq0+ArmVThOuRBcJF5hjGXYk86cwemg==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.11.tgz", + "integrity": "sha512-a28+1jvpIZQdZ/W97wOXb6VqI762MKE/TxMMuibMEHhyYsSxQA8Ek30KObd5kJI2HF1ldtSYprFayXJXi3pz8Q==", "dev": true }, "pretty-time": { @@ -7586,9 +7619,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.49.9", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.9.tgz", - "integrity": "sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A==", + "version": "1.52.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz", + "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -8197,62 +8230,34 @@ "integrity": "sha512-X324n9OtpTmOMqEgDUEA/RgLrNfBF/jwJdctaPZDzB3mppxJk7TLIDmOreEDm1Bq4R9LSPu4Epf8VSdovNU+iA==" }, "tailwindcss": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.23.tgz", - "integrity": "sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA==", + "version": "3.0.24", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.24.tgz", + "integrity": "sha512-H3uMmZNWzG6aqmg9q07ZIRNIawoiEcNFKDfL+YzOPuPsXuDXxJxB9icqzLgdzKNwjG3SAro2h9SYav8ewXNgig==", "dev": true, "requires": { "arg": "^5.0.1", - "chalk": "^4.1.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", - "cosmiconfig": "^7.0.1", "detective": "^5.2.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.11", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", + "lilconfig": "^2.0.5", "normalize-path": "^3.0.0", - "object-hash": "^2.2.0", - "postcss": "^8.4.6", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.12", "postcss-js": "^4.0.0", - "postcss-load-config": "^3.1.0", + "postcss-load-config": "^3.1.4", "postcss-nested": "5.0.6", - "postcss-selector-parser": "^6.0.9", + "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", "resolve": "^1.22.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", @@ -8268,19 +8273,30 @@ "is-glob": "^4.0.3" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "lilconfig": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", "dev": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" } } } @@ -8597,9 +8613,9 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v-click-outside": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-3.1.2.tgz", - "integrity": "sha512-gMdRqfRE6m6XU6SiFi3dyBlFB2MWogiXpof8Aa3LQysrl9pzTndqp/iEaAphLoadaQUFnQ0ec6fLLaxr7LiY6A==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-3.2.0.tgz", + "integrity": "sha512-QD0bDy38SHJXQBjgnllmkI/rbdiwmq9RC+/+pvrFjYJKTn8dtp7Penf9q1lLBta280fYG2q53mgLhQ+3l3z74w==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -8695,9 +8711,9 @@ "integrity": "sha512-W+y2EAI/BxS4Vlcca9scQv8ifeBFck56DRtSwWJ2H4Cw1GLNUYxiZxUHHkuzuI5JPW/cYtL1bPO5xPyEXx4LmQ==" }, "vue-router": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", - "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.4.tgz", + "integrity": "sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==" }, "vue-style-loader": { "version": "4.1.3", diff --git a/package.json b/package.json index 5d053531..a5b6d471 100644 --- a/package.json +++ b/package.json @@ -10,39 +10,39 @@ "production": "mix --production" }, "devDependencies": { - "autoprefixer": "^10.4.2", + "autoprefixer": "^10.4.7", "axios": "^0.21.4", "cross-env": "^5.1", - "laravel-echo": "^1.11.3", + "laravel-echo": "^1.11.7", "laravel-mix": "^6.0.43", - "postcss": "^8.4.8", + "postcss": "^8.4.14", "prettier": "^2.5.1", "prettier-plugin-import-sort": "0.0.7", - "prettier-plugin-tailwindcss": "^0.1.8", + "prettier-plugin-tailwindcss": "^0.1.11", "pusher-js": "^7.0.6", "resolve-url-loader": "^2.3.1", - "sass": "^1.49.9", + "sass": "^1.52.1", "sass-loader": "^8.0.2", - "tailwindcss": "^3.0.23", + "tailwindcss": "^3.0.24", "tailwindcss-debug-screens": "^2.2.1", "vue-loader": "^15.9.8", "vue-template-compiler": "^2.6.14" }, "dependencies": { "@paypal/paypal-js": "^4.2.2", - "@stripe/stripe-js": "^1.24.0", + "@stripe/stripe-js": "^1.29.0", "lodash": "^4.17.21", "node-sass": "^4.14.1", "pdfvuer": "^1.9.2", "tailwind-scrollbar-hide": "^1.1.7", "twemoji": "^13.1.0", - "v-click-outside": "^3.1.2", + "v-click-outside": "^3.2.0", "vee-validate": "^3.4.14", "vue": "^2.6.14", "vue-feather-icons": "^5.1.0", "vue-i18n": "^8.27.0", "vue-recaptcha-v3": "^1.9.0", - "vue-router": "^3.5.3", + "vue-router": "^3.5.4", "vuex": "^3.6.2" } } diff --git a/public/mix-manifest.json b/public/mix-manifest.json index ba311da0..f0fdf892 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,75 +1,75 @@ { "/js/main.js": "/js/main.js", - "/chunks/request.js": "/chunks/request.js?id=e12cca6ff4d753a0", - "/chunks/request-upload.js": "/chunks/request-upload.js?id=6f7ff06d99abc1db", - "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=e8b9ac5e5a0854bf", - "/chunks/status-check.js": "/chunks/status-check.js?id=4c7482ca1bc4806d", - "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=95910a6098545b18", - "/chunks/database.js": "/chunks/database.js?id=f075fa5bd4011705", - "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=6a2f88cf2e1c8c42", - "/chunks/app-setup.js": "/chunks/app-setup.js?id=fac96a371fa057a9", - "/chunks/admin-account.js": "/chunks/admin-account.js?id=f207f8887394310d", - "/chunks/shared.js": "/chunks/shared.js?id=cdfbac570212aaba", - "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=82de4b533b350338", - "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=fda3ee1897218fb4", - "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=a68c497e91a6fadb", - "/chunks/not-found.js": "/chunks/not-found.js?id=cbcb2fcb42696af3", - "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=8b78c188c3ef58cc", - "/chunks/admin.js": "/chunks/admin.js?id=23b353c5fba8f97b", - "/chunks/dashboard.js": "/chunks/dashboard.js?id=c265489f6698ba44", - "/chunks/invoices.js": "/chunks/invoices.js?id=4888dcbcb1371d33", - "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=c754f2735eefc4c9", - "/chunks/pages.js": "/chunks/pages.js?id=d7fa7d4e7183174e", - "/chunks/page-edit.js": "/chunks/page-edit.js?id=3bd81e19fcce81aa", - "/chunks/plans.js": "/chunks/plans.js?id=d69f27e0eef6cd1a", - "/chunks/users.js": "/chunks/users.js?id=89c6cffd734c97b0", - "/chunks/user-create.js": "/chunks/user-create.js?id=200db7025d533298", - "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=9d40af67b3f3eb25", - "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=47674b7d5dd105e6", - "/chunks/user.js": "/chunks/user.js?id=b9b5caf4720670e9", - "/chunks/user-detail.js": "/chunks/user-detail.js?id=ae8139dee6bc9148", - "/chunks/user-storage.js": "/chunks/user-storage.js?id=415f9f91492ec6eb", - "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=2e485797f12f64c8", - "/chunks/user-password.js": "/chunks/user-password.js?id=30e1861f3b9f4e2b", - "/chunks/user-delete.js": "/chunks/user-delete.js?id=61995898ac991620", - "/chunks/plan.js": "/chunks/plan.js?id=d8cdd722694b202d", - "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=a264bff3e18fbb1c", - "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=aaaf30d34d941711", - "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=385d94cbf75154cd", - "/chunks/payments.js": "/chunks/payments.js?id=26aa71dcfe9109fb", - "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=c2edc02c0261af92", - "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=72383895b3bfb5a4", - "/chunks/app-settings.js": "/chunks/app-settings.js?id=a6b8202457054e7c", - "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=8a139759c507aab3", - "/chunks/app-index.js": "/chunks/app-index.js?id=0237d25f5fec22f8", - "/chunks/app-environment.js": "/chunks/app-environment.js?id=5cdd3a4a5276b300", - "/chunks/app-others.js": "/chunks/app-others.js?id=8c9ef45b8163b98e", - "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=bdd9ab8b100e63e9", - "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=916521e9750df132", - "/chunks/app-server.js": "/chunks/app-server.js?id=daa05ca55f05276e", - "/chunks/app-language.js": "/chunks/app-language.js?id=3dc649491be91954", - "/chunks/homepage.js": "/chunks/homepage.js?id=8d839489cb2670b7", - "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=0b84c5e06b3f1202", - "/chunks/contact-us.js": "/chunks/contact-us.js?id=c2f9beea77a7109b", - "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=d080d93ce30187d1", - "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=5d0042e9619ed73e", - "/chunks/sign-in.js": "/chunks/sign-in.js?id=379b9147d37291d5", - "/chunks/sign-up.js": "/chunks/sign-up.js?id=d1bcad80748579ae", - "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=7e713217b427cc06", - "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=094a12eb5ba69c9f", - "/chunks/settings.js": "/chunks/settings.js?id=7ef82be482dcf31d", - "/chunks/profile.js": "/chunks/profile.js?id=d280577d80754c91", - "/chunks/settings-password.js": "/chunks/settings-password.js?id=4f56d97ef76cff6e", - "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=e6866a6ffd9c3a80", - "/chunks/billing.js": "/chunks/billing.js?id=ce81cf6583d26d4c", - "/chunks/platform.js": "/chunks/platform.js?id=8899666aebaf9db4", - "/chunks/files.js": "/chunks/files.js?id=a6dbd9f43e4eb694", - "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=8f087976e1d1af41", - "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=969ac9f4297e1179", - "/chunks/trash.js": "/chunks/trash.js?id=da9791f0f6155a99", - "/chunks/team-folders.js": "/chunks/team-folders.js?id=88bce3b12b4dce95", - "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=45b03e5063720b33", - "/chunks/invitation.js": "/chunks/invitation.js?id=3220065b746aa8fe", + "/chunks/request.js": "/chunks/request.js?id=4dae0cd347eacccf", + "/chunks/request-upload.js": "/chunks/request-upload.js?id=37b9e11f7f085164", + "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=19a0784e59d768ec", + "/chunks/status-check.js": "/chunks/status-check.js?id=ca27b637120e086a", + "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=df5bd89528649783", + "/chunks/database.js": "/chunks/database.js?id=6bd9994bd24d6c8d", + "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=fc9b6215ce43229b", + "/chunks/app-setup.js": "/chunks/app-setup.js?id=77937d105dfa28ba", + "/chunks/admin-account.js": "/chunks/admin-account.js?id=6dbc3fe81f957a59", + "/chunks/shared.js": "/chunks/shared.js?id=811ed03bd8ff236a", + "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=ae81a41ecf6222f9", + "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=9ccb8bb19b95a23f", + "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=672e931a9fb0b672", + "/chunks/not-found.js": "/chunks/not-found.js?id=9f6ce23ce5d969f1", + "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=f564565faa09d6d6", + "/chunks/admin.js": "/chunks/admin.js?id=c48facc21639ee2c", + "/chunks/dashboard.js": "/chunks/dashboard.js?id=c7fa2f0dc8ed949c", + "/chunks/invoices.js": "/chunks/invoices.js?id=1416cbf6d1a593ac", + "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=5bf6704f5b599f36", + "/chunks/pages.js": "/chunks/pages.js?id=c8380d571e91e8be", + "/chunks/page-edit.js": "/chunks/page-edit.js?id=b19868b3100360a3", + "/chunks/plans.js": "/chunks/plans.js?id=c8506e0e20966ef7", + "/chunks/users.js": "/chunks/users.js?id=ec687ee365c4248a", + "/chunks/user-create.js": "/chunks/user-create.js?id=bb3b30ce248209f0", + "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=a8ffa08ce94ddf4e", + "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=3b516dcccbbef20a", + "/chunks/user.js": "/chunks/user.js?id=c191b906a0496fe5", + "/chunks/user-detail.js": "/chunks/user-detail.js?id=80491654e6ee63b1", + "/chunks/user-storage.js": "/chunks/user-storage.js?id=69eb59b682c5482f", + "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=a69ebc3b23446cda", + "/chunks/user-password.js": "/chunks/user-password.js?id=e1c4ebc07ba426e6", + "/chunks/user-delete.js": "/chunks/user-delete.js?id=82b5180a1d9e1217", + "/chunks/plan.js": "/chunks/plan.js?id=4b267375ea9f19b3", + "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=a956ceca6865c50c", + "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=f366690f8764bb20", + "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=e26d5bd3ecbb4bb1", + "/chunks/payments.js": "/chunks/payments.js?id=dc4586691c25de6f", + "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=9942aaac1bdb11e5", + "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=717bf97ba2ffdc28", + "/chunks/app-settings.js": "/chunks/app-settings.js?id=55da23af2b076069", + "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=c308941663208358", + "/chunks/app-index.js": "/chunks/app-index.js?id=aa62aedf1f38cc22", + "/chunks/app-environment.js": "/chunks/app-environment.js?id=538eea914fc27794", + "/chunks/app-others.js": "/chunks/app-others.js?id=3282fb7a70e8e02e", + "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=3f8e5f906a4dee4e", + "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=4ee8de4ac0dae19e", + "/chunks/app-server.js": "/chunks/app-server.js?id=dd8c15d4646053cd", + "/chunks/app-language.js": "/chunks/app-language.js?id=ba087a47c8efca29", + "/chunks/homepage.js": "/chunks/homepage.js?id=f1cfba4f0152f4b9", + "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=2504793131107b1f", + "/chunks/contact-us.js": "/chunks/contact-us.js?id=2e0b16655d2d85d7", + "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=25b805ade5230382", + "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=f4562229776d9f56", + "/chunks/sign-in.js": "/chunks/sign-in.js?id=295d214d04f2a86d", + "/chunks/sign-up.js": "/chunks/sign-up.js?id=77351b7631a6ee6c", + "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=50a1bc5e4ed86ec9", + "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=f652de052dba55c1", + "/chunks/settings.js": "/chunks/settings.js?id=f41a95bc12c30010", + "/chunks/profile.js": "/chunks/profile.js?id=5b2ed82815320625", + "/chunks/settings-password.js": "/chunks/settings-password.js?id=c912a79595c2efcb", + "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=6fec7aac1a5280c7", + "/chunks/billing.js": "/chunks/billing.js?id=3a9b4a3869602995", + "/chunks/platform.js": "/chunks/platform.js?id=b966740835699124", + "/chunks/files.js": "/chunks/files.js?id=4e608db6e46c8e1a", + "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=75ae670c0dd88d28", + "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=20366862e84678f3", + "/chunks/trash.js": "/chunks/trash.js?id=3930329bfca5ef73", + "/chunks/team-folders.js": "/chunks/team-folders.js?id=bf4c9aa124ec9b8e", + "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=87d0fb60c573f01d", + "/chunks/invitation.js": "/chunks/invitation.js?id=9ed8456c9d6d5ce1", "/css/tailwind.css": "/css/tailwind.css", "/css/app.css": "/css/app.css" } diff --git a/resources/js/components/FilesView/FileBrowser.vue b/resources/js/components/FilesView/FileBrowser.vue index 515e887c..41bf106e 100644 --- a/resources/js/components/FilesView/FileBrowser.vue +++ b/resources/js/components/FilesView/FileBrowser.vue @@ -25,13 +25,14 @@ :key="item.data.id" :item="item" /> - + -
- +
+
@@ -41,6 +42,7 @@ import ItemHandler from './ItemHandler' import { events } from '../../bus' import { mapGetters } from 'vuex' import Spinner from './Spinner' +import { debounce } from 'lodash' export default { name: 'FileBrowser', @@ -60,38 +62,31 @@ export default { return this.clipboard } }, - continueInfiniteScroll() { - if(this.paginate) - return this.paginate.paginate.currentPage !== this.paginate.paginate.lastPage + canLoadMoreEntries() { + return this.paginate?.currentPage !== this.paginate?.lastPage }, showInfiniteLoadSpinner() { - return this.continueInfiniteScroll && this.entries.length !== 0 && this.paginate.paginate.perPage <= this.entries.length + return this.canLoadMoreEntries && this.entries.length !== 0 && this.paginate.perPage <= this.entries.length }, }, data() { return { draggingId: undefined, isDragging: false, - infiniteScrollLoad: false, + isLoadingNewEntries: false, } }, methods: { - infiniteScroll() { - - if( this.continueInfiniteScroll && this.elementInViewport() ) { - - if(! this.infiniteScrollLoad) { - this.infiniteScrollLoad = true - - this.$getDataByLocation(this.paginate.paginate.currentPage + 1).then(() => { - this.infiniteScrollLoad = false - }) - } - } - }, - elementInViewport() { - var item = document.getElementById('infinite-loader') - var rect = item.getBoundingClientRect() + infiniteScroll: debounce(function () { + if (this.isInfinityLoaderAtBottomPage() && this.canLoadMoreEntries && !this.isLoadingNewEntries) { + this.isLoadingNewEntries = true + + this.$getDataByLocation(this.paginate.currentPage + 1) + .then(() => this.isLoadingNewEntries = false) + } + }, 150), + isInfinityLoaderAtBottomPage() { + let rect = this.$refs.infinityLoader.getBoundingClientRect() return ( rect.bottom > 0 && @@ -126,7 +121,7 @@ export default { // Store dragged folder this.draggingId = data - // TODO: founded issue on firefox + // TODO: found issue on firefox }, dragFinish(data, event) { if (event.dataTransfer.items.length === 0) { @@ -176,8 +171,10 @@ export default { }, }, created() { - if(this.$isMobile()) - document.addEventListener('scroll', this.infiniteScroll, true) + // Track document scrolling to load new entries if needed + if (window.innerWidth <= 1024) { + document.addEventListener('scroll', this.infiniteScroll) + } events.$on('drop', () => { this.isDragging = false diff --git a/resources/js/store/modules/fileBrowser.js b/resources/js/store/modules/fileBrowser.js index be98fb3e..01f5bf54 100644 --- a/resources/js/store/modules/fileBrowser.js +++ b/resources/js/store/modules/fileBrowser.js @@ -19,7 +19,7 @@ const actions = { getFolder: ({ commit, getters },{page, id}) => { return new Promise ((resolve, reject) => { - if( !page) + if(!page) commit('LOADING_STATE', { loading: true, data: [] }) let currentPage = page || 1 @@ -27,9 +27,7 @@ const actions = { axios .get(`${getters.api}/browse/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, @@ -70,9 +68,7 @@ const actions = { .get(getters.api + `/browse/latest?page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, @@ -103,9 +99,7 @@ const actions = { .get(`${getters.api}/browse/share${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, @@ -136,9 +130,7 @@ const actions = { .get(`${getters.api}/browse/trash/${id}/${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, diff --git a/resources/js/store/modules/sharing.js b/resources/js/store/modules/sharing.js index fa4e9203..53faac2b 100644 --- a/resources/js/store/modules/sharing.js +++ b/resources/js/store/modules/sharing.js @@ -31,9 +31,7 @@ const actions = { axios .get(`/api/browse/folders/${id}/${router.currentRoute.params.token}${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, diff --git a/resources/js/store/modules/teams.js b/resources/js/store/modules/teams.js index 41df857c..123cafb3 100644 --- a/resources/js/store/modules/teams.js +++ b/resources/js/store/modules/teams.js @@ -24,9 +24,7 @@ const actions = { axios .get(`${getters.api}/teams/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, @@ -77,9 +75,7 @@ const actions = { axios .get(`${getters.api}/teams/shared-with-me/${id}/${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - commit('SET_PAGINATE', { - paginate: response.data.meta.paginate - }) + commit('SET_PAGINATE', response.data.meta.paginate) commit('LOADING_STATE', { loading: false, diff --git a/src/Support/helpers.php b/src/Support/helpers.php index e5ef6a15..f5ff694d 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -1174,7 +1174,7 @@ if (! function_exists('replace_occurrence')) { 'total' => $totalItemsCount, ], [ - 'first' => $uri . '&page=' . 1, + 'first' => $uri . '&page=1', 'last' => $uri . '&page=' . $lastPage, 'next' => $currentPage == $lastPage ? null : $uri . '&page=' . $currentPage + 1, 'prev' => $currentPage == 1 ? null : $uri . '&page=' . $currentPage - 1,