Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(patch vue-router): url / to %2F encoding #5715

Merged
merged 10 commits into from
Sep 6, 2021
6 changes: 6 additions & 0 deletions changelog/unreleased/bugfix-pagination-move-pagereload
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Bugfix: Pagination on Locationpicker

Pagination on copying/moving files as well as page reloads when copying/moving files were broken.
When changing the Vue router encoding, we fixed both issues.

https://github.com/owncloud/web/pull/5715
11 changes: 11 additions & 0 deletions changelog/unreleased/change-update-ods
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Change: Update ODS to 10.0.0

We updated the ownCloud Design System to version 10.0.0-rc1. Please refer to the full changelog in the ODS release (linked) for more details. Summary:

- Change - Use route query to store active page: https://github.com/owncloud/owncloud-design-system/pull/1626
- Change - Refactor OcAvatarGroup and rename to OcAvatars: https://github.com/owncloud/owncloud-design-system/pull/5736
- Enhancement - Switch filesize calculation base: https://github.com/owncloud/owncloud-design-system/pull/1598
- Bugfix - Reset droptarget background color in OcTableFiles: https://github.com/owncloud/owncloud-design-system/pull/1625

https://github.com/owncloud/web/pull/5769
https://github.com/owncloud/owncloud-design-system/releases/tag/v10.0.0-rc1
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-url-encoding
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: URL encoding / decoding

We have updated the Vue router (prior to version 4) encoding from `files%2Fall%2Ffolder` to `files/all/folder`.
It was also needed to use the router query object instead of the params to store the current page pagination information.

https://github.com/owncloud/web/issues/5714
https://github.com/owncloud/web/pull/5715
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default {

computed: {
...mapGetters('Files', ['selectedFiles', 'currentFolder', 'activeFiles']),
...mapGetters(['homeFolder']),

emptyTrashbinButtonText() {
return this.selectedFiles.length < 1
Expand Down Expand Up @@ -229,12 +230,13 @@ export default {
triggerLocationPicker(action) {
const resources = cloneStateObject(this.selectedFiles)
const context = this.isPublicPage ? 'public' : 'private'
const item = this.currentFolder.path || this.homeFolder

this.$router.push({
name: 'files-location-picker',
params: {
context,
item: this.currentFolder.path,
item,
action
},
query: {
Expand Down
22 changes: 12 additions & 10 deletions packages/web-app-files/src/components/AppBar/ViewOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
</li>
<li class="files-view-options-list-item">
<oc-page-size
v-model="pageItemsLimit"
v-model="itemsPerPageModel"
data-testid="files-pagination-size"
:label="$gettext('Items per page')"
:options="[100, 500, 1000, $gettext('All')]"
Expand All @@ -59,8 +59,9 @@ import { mapMutations, mapState, mapActions } from 'vuex'

export default {
computed: {
...mapState('Files', ['areHiddenFilesShown', 'filesPageLimit']),
...mapState('Files', ['areHiddenFilesShown']),
...mapState('Files/sidebar', { sidebarClosed: 'closed' }),
...mapState('Files/pagination', ['itemsPerPage']),

viewOptionsButtonLabel() {
return this.$gettext('Display customization options of the files list')
Expand All @@ -85,9 +86,9 @@ export default {
}
},

pageItemsLimit: {
itemsPerPageModel: {
get() {
return this.filesPageLimit
return this.itemsPerPage
},

set(value) {
Expand All @@ -99,8 +100,8 @@ export default {
watch: {
$route: {
handler(route) {
if (Object.prototype.hasOwnProperty.call(route.query, 'items-limit')) {
this.SET_FILES_PAGE_LIMIT(route.query['items-limit'])
if (Object.prototype.hasOwnProperty.call(route.query, 'items-per-page')) {
this.SET_ITEMS_PER_PAGE(route.query['items-per-page'])

return
}
Expand All @@ -111,13 +112,14 @@ export default {
}
},
methods: {
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY', 'SET_FILES_PAGE_LIMIT']),
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY']),
...mapActions('Files/sidebar', { toggleSidebar: 'toggle' }),
...mapMutations('Files/pagination', ['SET_ITEMS_PER_PAGE']),

updateQuery(limit = this.pageItemsLimit) {
const query = { ...this.$route.query, 'items-limit': limit }
updateQuery(limit = this.itemsPerPageModel) {
const query = { ...this.$route.query, 'items-per-page': limit }

this.SET_FILES_PAGE_LIMIT(limit)
this.SET_ITEMS_PER_PAGE(limit)
this.$router.replace({ query }).catch(() => {})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { mapState, mapGetters } from 'vuex'

export default {
computed: {
...mapState('Files', ['currentPage']),
...mapGetters('Files', ['pages'])
...mapState('Files/pagination', ['currentPage']),
...mapGetters('Files/pagination', ['pages'])
}
}
</script>
2 changes: 1 addition & 1 deletion packages/web-app-files/src/helpers/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @param {Boolean} includeCurrent whether to include the current path (with leading slash)
* @return {Array.<String>} parent paths
*/
export function getParentPaths(path, includeCurrent = false) {
export function getParentPaths(path = '', includeCurrent = false) {
// remove potential leading and trailing slash from current path (so that the resulting array doesn't start with an empty string).
// then reintroduce the leading slash, because we know that we need it.
const s = '/' + path.replace(/^\/+/, '').replace(/\/+$/, '')
Expand Down
50 changes: 42 additions & 8 deletions packages/web-app-files/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ const routes = [
children: [
{
name: 'personal',
path: 'all/:item?/:page?',
fschade marked this conversation as resolved.
Show resolved Hide resolved
path: 'all/:item*',
component: Personal,
meta: {
hasBulkActions: true,
Expand All @@ -203,7 +203,7 @@ const routes = [
},
{
name: 'favorites',
path: 'favorites/:page?',
path: 'favorites',
component: Favorites,
meta: {
hideFilelistActions: true,
Expand All @@ -212,7 +212,7 @@ const routes = [
}
},
{
path: 'shared-with-me/:page?',
path: 'shared-with-me',
component: SharedWithMe,
name: 'shared-with-me',
meta: {
Expand All @@ -222,7 +222,7 @@ const routes = [
}
},
{
path: 'shared-with-others/:page?',
path: 'shared-with-others',
component: SharedWithOthers,
name: 'shared-with-others',
meta: {
Expand All @@ -232,7 +232,7 @@ const routes = [
}
},
{
path: 'shared-via-link/:page?',
path: 'shared-via-link',
component: SharedViaLink,
name: 'shared-via-link',
meta: {
Expand All @@ -242,7 +242,7 @@ const routes = [
}
},
{
path: 'trash-bin/:page?',
path: 'trash-bin',
component: Trashbin,
name: 'trashbin',
meta: {
Expand All @@ -266,7 +266,7 @@ const routes = [
children: [
{
name: 'public-list',
path: 'list/:item/:page?',
path: 'list/:item*',
component: PublicFiles,
meta: {
auth: false,
Expand Down Expand Up @@ -297,7 +297,7 @@ const routes = [
meta: { hideHeadbar: true, title: $gettext('Resolving private link') }
},
{
path: '/location-picker/:context/:action/:item?/:page?',
path: '/location-picker/:context/:action/:item*',
name: 'location-picker',
components: {
app: LocationPicker
Expand All @@ -322,6 +322,39 @@ const routes = [
const translations = translationsJson
const quickActions = quickActionsImport

// type: patch
// temporary patch till we have upgraded web to the latest vue router which make this obsolete
// this takes care that routes like 'foo/bar/baz' which by default would be converted to 'foo%2Fbar%2Fbaz' stay as they are
// should immediately go away and be removed after finalizing the update
const patchRouter = router => {
// for now we only need the patch on following routes, if needed on more just extend
// - files-personal: https://github.com/owncloud/web/issues/1883
// - files-personal: https://github.com/owncloud/web/issues/4595
// - files-public-list
// - files-location-picker
const activateForRoutes = ['files-personal', 'files-public-list', 'files-location-picker']
const bindMatcher = router.match.bind(router)
const cleanPath = route =>
[
['%2F', '/'],
['//', '/']
].reduce((acc, rule) => acc.replaceAll(rule[0], rule[1]), route || '')

router.match = (raw, current, redirectFrom) => {
const bindMatch = bindMatcher(raw, current, redirectFrom)

if (!activateForRoutes.includes(bindMatch.name)) {
return bindMatch
}

return {
...bindMatch,
path: cleanPath(bindMatch.path),
fullPath: cleanPath(bindMatch.fullPath)
}
}
}

export default {
appInfo,
store,
Expand All @@ -330,6 +363,7 @@ export default {
quickActions,
translations,
mounted({ router: runtimeRouter, store: runtimeStore }) {
patchRouter(runtimeRouter)
Registry.filterSearch = new FilterSearch(runtimeStore, runtimeRouter)
Registry.sdkSearch = new SDKSearch(runtimeStore, runtimeRouter)

Expand Down
10 changes: 5 additions & 5 deletions packages/web-app-files/src/mixins/filesListFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,25 @@ export default {
immediate: true
},
pages() {
if (!this.$route.params.page) {
if (!this.$route.query.page) {
return
}

if (this.$route.params.page <= this.pages) {
if (this.$route.query.page <= this.pages) {
return
}

this.$router.push({
name: this.$route.name,
query: this.$route.query,
params: { ...this.$route.params, page: this.pages }
query: { ...this.$route.query, page: this.pages },
params: this.$route.params
})
}
},
methods: {
...mapMutations('Files', ['CLEAR_FILES_SEARCHED', 'LOAD_FILES_SEARCHED'])
},
computed: {
...mapGetters('Files', ['pages'])
...mapGetters('Files/pagination', ['pages'])
}
}
4 changes: 2 additions & 2 deletions packages/web-app-files/src/mixins/filesListPagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { mapMutations } from 'vuex'

export default {
methods: {
...mapMutations('Files', ['UPDATE_CURRENT_PAGE']),
...mapMutations('Files/pagination', ['UPDATE_CURRENT_PAGE']),

$_filesListPagination_updateCurrentPage() {
const page = this.$route.params.page || 1
const page = this.$route.query.page || 1

this.UPDATE_CURRENT_PAGE(page)
}
Expand Down
10 changes: 5 additions & 5 deletions packages/web-app-files/src/store/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ export default {
},
// a flat file list has no current folder nor parent
flatFileList: state => !!state.currentFolder === false,
pages: (state, getters) => Math.ceil(getters.filesAll.length / state.filesPageLimit),
activeFiles: (state, getters) => {
activeFiles: (state, getters, rootState) => {
let files = [].concat(getters.filesAll)

if (!state.areHiddenFilesShown) {
files = files.filter(file => !file.name.startsWith('.'))
}

if (state.filesPageLimit > 0) {
const firstElementIndex = (state.currentPage - 1) * state.filesPageLimit
const { itemsPerPage, currentPage } = rootState.Files.pagination
if (itemsPerPage > 0) {
const firstElementIndex = (currentPage - 1) * itemsPerPage

return files.splice(firstElementIndex, state.filesPageLimit)
return files.splice(firstElementIndex, itemsPerPage)
}

return files
Expand Down
6 changes: 4 additions & 2 deletions packages/web-app-files/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import state from './state'
import actions from './actions'
import mutations from './mutations'
import getters from './getters'
import sidebar from './sidebar'
import sidebarModule from './modules/sidebar'
import paginationModule from './modules/pagination'
const namespaced = true

export default {
Expand All @@ -12,6 +13,7 @@ export default {
actions,
mutations,
modules: {
sidebar
sidebar: sidebarModule,
pagination: paginationModule
}
}
27 changes: 27 additions & 0 deletions packages/web-app-files/src/store/modules/pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export default {
namespaced: true,
state: () => ({
currentPage: 1,
itemsPerPage: 100
}),
mutations: {
SET_ITEMS_PER_PAGE(state, limit) {
state.itemsPerPage = limit

window.localStorage.setItem('oc_filesPageLimit', limit)
},
UPDATE_CURRENT_PAGE(state, page) {
state.currentPage = parseInt(page)
}
},
getters: {
pages: (state, getters, rootState, rootGetters) => {
if (!parseInt(state.itemsPerPage)) {
return 1
}

const allFiles = rootGetters['Files/filesAll']
return Math.ceil(allFiles.length / state.itemsPerPage)
}
}
}
10 changes: 0 additions & 10 deletions packages/web-app-files/src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,20 +327,10 @@ export default {
Vue.set(fileSource, index, newResource)
},

UPDATE_CURRENT_PAGE(state, page) {
state.currentPage = parseInt(page)
},

SET_HIDDEN_FILES_VISIBILITY(state, value) {
state.areHiddenFilesShown = value

window.localStorage.setItem('oc_hiddenFilesShown', value)
},

SET_FILES_PAGE_LIMIT(state, limit) {
state.filesPageLimit = limit

window.localStorage.setItem('oc_filesPageLimit', limit)
}
}

Expand Down
Loading