mirror of
https://github.com/nextcloud/server.git
synced 2026-06-09 08:44:07 -04:00
Merge pull request #49261 from nextcloud/fix/file-list-filters-reset
fix(files): Properly reset all file list filters on view change
This commit is contained in:
commit
465fe42af1
14 changed files with 141 additions and 75 deletions
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import type { IFileListFilterChip, INode } from '@nextcloud/files'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import { FileListFilter } from '@nextcloud/files'
|
||||
|
||||
/**
|
||||
|
|
@ -16,7 +15,6 @@ export class FilenameFilter extends FileListFilter {
|
|||
|
||||
constructor() {
|
||||
super('files:filename', 5)
|
||||
subscribe('files:navigation:changed', () => this.updateQuery(''))
|
||||
}
|
||||
|
||||
public filter(nodes: INode[]): INode[] {
|
||||
|
|
@ -27,6 +25,10 @@ export class FilenameFilter extends FileListFilter {
|
|||
})
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.updateQuery('')
|
||||
}
|
||||
|
||||
public updateQuery(query: string) {
|
||||
query = (query || '').trim()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
import type { IFileListFilterChip, INode } from '@nextcloud/files'
|
||||
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import { FileListFilter, registerFileListFilter } from '@nextcloud/files'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import Vue from 'vue'
|
||||
|
|
@ -58,7 +57,6 @@ class ModifiedFilter extends FileListFilter {
|
|||
|
||||
constructor() {
|
||||
super('files:modified', 50)
|
||||
subscribe('files:navigation:changed', () => this.setPreset())
|
||||
}
|
||||
|
||||
public mount(el: HTMLElement) {
|
||||
|
|
@ -85,6 +83,10 @@ class ModifiedFilter extends FileListFilter {
|
|||
return nodes.filter((node) => node.mtime === undefined || this.currentPreset!.filter(node.mtime.getTime()))
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.setPreset()
|
||||
}
|
||||
|
||||
public setPreset(preset?: ITimePreset) {
|
||||
this.currentPreset = preset
|
||||
this.filterUpdated()
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ class TypeFilter extends FileListFilter {
|
|||
})
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.setPresets()
|
||||
}
|
||||
|
||||
public setPresets(presets?: ITypePreset[]) {
|
||||
this.currentPresets = presets ?? []
|
||||
this.currentInstance!.$props.presets = presets
|
||||
|
|
|
|||
|
|
@ -6,75 +6,130 @@ import type { FilterUpdateChipsEvent, IFileListFilter, IFileListFilterChip } fro
|
|||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import { getFileListFilters } from '@nextcloud/files'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
import logger from '../logger'
|
||||
|
||||
export const useFiltersStore = defineStore('filters', {
|
||||
state: () => ({
|
||||
chips: {} as Record<string, IFileListFilterChip[]>,
|
||||
filters: [] as IFileListFilter[],
|
||||
filtersChanged: false,
|
||||
}),
|
||||
/**
|
||||
* Check if the given value is an instance file list filter with mount function
|
||||
* @param value The filter to check
|
||||
*/
|
||||
function isFileListFilterWithUi(value: IFileListFilter): value is Required<IFileListFilter> {
|
||||
return 'mount' in value
|
||||
}
|
||||
|
||||
getters: {
|
||||
/**
|
||||
* Currently active filter chips
|
||||
* @param state Internal state
|
||||
*/
|
||||
activeChips(state): IFileListFilterChip[] {
|
||||
return Object.values(state.chips).flat()
|
||||
},
|
||||
export const useFiltersStore = defineStore('filters', () => {
|
||||
const chips = ref<Record<string, IFileListFilterChip[]>>({})
|
||||
const filters = ref<IFileListFilter[]>([])
|
||||
const filtersChanged = ref(false)
|
||||
|
||||
/**
|
||||
* Filters sorted by order
|
||||
* @param state Internal state
|
||||
*/
|
||||
sortedFilters(state): IFileListFilter[] {
|
||||
return state.filters.sort((a, b) => a.order - b.order)
|
||||
},
|
||||
/**
|
||||
* Currently active filter chips
|
||||
*/
|
||||
const activeChips = computed<IFileListFilterChip[]>(
|
||||
() => Object.values(chips.value).flat(),
|
||||
)
|
||||
|
||||
/**
|
||||
* All filters that provide a UI for visual controlling the filter state
|
||||
*/
|
||||
filtersWithUI(): Required<IFileListFilter>[] {
|
||||
return this.sortedFilters.filter((filter) => 'mount' in filter) as Required<IFileListFilter>[]
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Filters sorted by order
|
||||
*/
|
||||
const sortedFilters = computed<IFileListFilter[]>(
|
||||
() => filters.value.sort((a, b) => a.order - b.order),
|
||||
)
|
||||
|
||||
actions: {
|
||||
addFilter(filter: IFileListFilter) {
|
||||
filter.addEventListener('update:chips', this.onFilterUpdateChips)
|
||||
filter.addEventListener('update:filter', this.onFilterUpdate)
|
||||
this.filters.push(filter)
|
||||
logger.debug('New file list filter registered', { id: filter.id })
|
||||
},
|
||||
/**
|
||||
* All filters that provide a UI for visual controlling the filter state
|
||||
*/
|
||||
const filtersWithUI = computed<Required<IFileListFilter>[]>(
|
||||
() => sortedFilters.value.filter(isFileListFilterWithUi)
|
||||
)
|
||||
|
||||
removeFilter(filterId: string) {
|
||||
const index = this.filters.findIndex(({ id }) => id === filterId)
|
||||
if (index > -1) {
|
||||
const [filter] = this.filters.splice(index, 1)
|
||||
filter.removeEventListener('update:chips', this.onFilterUpdateChips)
|
||||
filter.removeEventListener('update:filter', this.onFilterUpdate)
|
||||
logger.debug('Files list filter unregistered', { id: filterId })
|
||||
/**
|
||||
* Register a new filter on the store.
|
||||
* This will subscribe the store to the filters events.
|
||||
*
|
||||
* @param filter The filter to add
|
||||
*/
|
||||
function addFilter(filter: IFileListFilter) {
|
||||
filter.addEventListener('update:chips', onFilterUpdateChips)
|
||||
filter.addEventListener('update:filter', onFilterUpdate)
|
||||
|
||||
filters.value.push(filter)
|
||||
logger.debug('New file list filter registered', { id: filter.id })
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a filter from the store.
|
||||
* This will remove the filter from the store and unsubscribe the store from the filer events.
|
||||
* @param filterId Id of the filter to remove
|
||||
*/
|
||||
function removeFilter(filterId: string) {
|
||||
const index = filters.value.findIndex(({ id }) => id === filterId)
|
||||
if (index > -1) {
|
||||
const [filter] = filters.value.splice(index, 1)
|
||||
filter.removeEventListener('update:chips', onFilterUpdateChips)
|
||||
filter.removeEventListener('update:filter', onFilterUpdate)
|
||||
logger.debug('Files list filter unregistered', { id: filterId })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for filter update events
|
||||
* @private
|
||||
*/
|
||||
function onFilterUpdate() {
|
||||
filtersChanged.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for filter chips updates
|
||||
* @param event The update event
|
||||
* @private
|
||||
*/
|
||||
function onFilterUpdateChips(event: FilterUpdateChipsEvent) {
|
||||
const id = (event.target as IFileListFilter).id
|
||||
chips.value = {
|
||||
...chips.value,
|
||||
[id]: [...event.detail],
|
||||
}
|
||||
|
||||
logger.debug('File list filter chips updated', { filter: id, chips: event.detail })
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler that resets all filters if the file list view was changed.
|
||||
* @private
|
||||
*/
|
||||
function onViewChanged() {
|
||||
logger.debug('Reset all file list filters - view changed')
|
||||
|
||||
for (const filter of filters.value) {
|
||||
if (filter.reset !== undefined) {
|
||||
filter.reset()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
onFilterUpdate() {
|
||||
this.filtersChanged = true
|
||||
},
|
||||
// Initialize the store
|
||||
subscribe('files:navigation:changed', onViewChanged)
|
||||
subscribe('files:filter:added', addFilter)
|
||||
subscribe('files:filter:removed', removeFilter)
|
||||
for (const filter of getFileListFilters()) {
|
||||
addFilter(filter)
|
||||
}
|
||||
|
||||
onFilterUpdateChips(event: FilterUpdateChipsEvent) {
|
||||
const id = (event.target as IFileListFilter).id
|
||||
this.chips = { ...this.chips, [id]: [...event.detail] }
|
||||
return {
|
||||
// state
|
||||
chips,
|
||||
filters,
|
||||
filtersWithUI,
|
||||
filtersChanged,
|
||||
|
||||
logger.debug('File list filter chips updated', { filter: id, chips: event.detail })
|
||||
},
|
||||
// getters / computed
|
||||
activeChips,
|
||||
sortedFilters,
|
||||
|
||||
init() {
|
||||
subscribe('files:filter:added', this.addFilter)
|
||||
subscribe('files:filter:removed', this.removeFilter)
|
||||
for (const filter of getFileListFilters()) {
|
||||
this.addFilter(filter)
|
||||
}
|
||||
},
|
||||
},
|
||||
// actions / methods
|
||||
addFilter,
|
||||
removeFilter,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -526,7 +526,6 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
mounted() {
|
||||
this.filtersStore.init()
|
||||
this.fetchContent()
|
||||
|
||||
subscribe('files:node:deleted', this.onNodeDeleted)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ class AccountFilter extends FileListFilter {
|
|||
})
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.currentInstance?.resetFilter()
|
||||
}
|
||||
|
||||
public setAccounts(accounts?: IAccountData[]) {
|
||||
this.filterAccounts = accounts
|
||||
let chips: IFileListFilterChip[] = []
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["settings.scss","../../../core/css/variables.scss","../../../core/css/functions.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCEA;AAAA;AAAA;AAAA,GCFA;AAAA;AAAA;AAAA,GFUC,0BACC,WAKF,OACC,WAID,4BE2BC,2CFvBD,mBEuBC,kDFnBD,qBEmBC,yCFfD,0BEeC,wCFXD,oEEWC,2CFPD,oCACC,oBACA,0BACA,+BACA,mBAGD,4BACC,oBACA,kCAGD,yBACC,WAIA,wCACC,kBACA,yDACC,gBAIA,mOACC,WAKH,uCACC,aAGD,sCACC,WAED,uDACC,WAKD,gBACC,WAIF,mBACC,aACA,aACA,iBACA,uEACA,qBAEA,4BACC,kBACA,SAEA,+BACC,mBAIA,qCACC,iBAKH,kCACC,sBACA,mBACA,gBAGD,mGACC,4BACA,0BACA,WAMF,oBACC,kBACA,wCACC,0BAIF,aACC,oBACA,4CACA,kFACA,8CACA,wCACA,2CACA,8CACA,6CACA,mBACA,yCAEA,sCAEC,oDAGD,+CAEC,6DACA,oDAGD,6BACC,qCACA,WACA,YAIF,6BACC,oBACA,kCAEA,mCACC,WAIA,oCACC,kBACA,oBACA,iBACA,2BACA,WACA,mBACA,QAEA,0CACC,mBACA,uBACA,gBAKD,gIACC,kBACA,qBACA,UACA,oBACA,YAKH,qCACC,kBACA,wBACA,MACA,SAEA,yCACC,qBAIF,4CACC,eAGD,4CACC,sBACA,WACA,YACA,YAMF,qBACC,aACA,sBACA,SACA,YAEA,uBACC,aAGD,uCACC,sBACA,cACA,yBAIF,iBACC,kBACA,eACA,oCACA,qCACA,6CACA,SACA,gBACA,YAEA,8CAEC,+CACA,2CAEA,0FACC,WAIF,uCACC,0BACA,qBACA,gCACA,WACA,eAEA,wDACC,qBACA,sBACA,eAIF,sCACC,kCAGC,4DAEC,iBACA,kBAEA,kFACC,YAGD,mEACC,oDAEA,kFACC,iBAIF,qEACC,WAEA,eAEA,uEACC,eAQN,gBACC,YAIA,2BACC,kCAGD,mBACC,YAIF,sCAEC,aAGD,eACC,WAGD,YACC,qBAIA,aACC,WACA,yBACA,YAGD,WACC,WACA,yBACA,YAMD,oBACC,sBAGD,iBACC,eAKD,iCACC,aACA,eACA,sBACA,SACA,gDACC,aACA,eACA,sBACA,sDACC,oBAIF,kGACC,cACA,YACA,gBAKA,iEACC,kBACA,UAED,+EACC,oBACA,oBACA,wBACA,qBAIF,wCACC,WAGD,iDACC,qBAGD,sDACC,kBACA,qBACA,WACA,0BACA,eACA,gBACA,WAQF,oBACC,gBAGD,wBACC,yBAGD,oDACC,WACA,YACA,wCAOD,oBACC,UACA,cACA,gBACA,uBAGD,2BACC,UAKD,oCAEC,cAKD,wEAEC,aAIF,gBACC,kBACA,QACA,mBAEA,sBACC,YAGD,sBACC,iBAKF,WACC,WAEA,cACC,WACA,UACA,uBACA,4CACA,iBACA,mBAGD,cACC,4CACA,UACA,uBACA,iBACA,mBAKD,gBACC,0BACA,cACA,eACA,uBACA,gBAGD,wBACC,0BAEA,gCACC,kBAIF,sCACC,kBAGD,sDAEC,cACA,eACA,eAEA,0EACC,UACA,qBACA,uBACA,gBAIF,8BACC,eAGD,kCACC,wBACA,cAIF,2BACC,mBAMA,oBACC,mBACA,sBACA,WAGD,gCACC,0BAIA,gGACC,cAOH,SACC,gBAEA,0BACC,4CAID,YACC,oBACA,mBACA,uBACA,eACA,iBACA,gBACA,aAEA,uBACC,aACA,mBACA,uBACA,oCACA,qCACA,yDACA,sBACA,oCAKF,WACC,kBACA,kBACA,oCACA,gBAKF,KACC,mBACA,mBAGD,SACC,aAGD,mBACC,mBAGD,eACC,gBAOA,+IACC,sBAEA,+KACC,aAGD,mKACC,WACA,YACA,kCACA,qBACA,kBAGD,mOACC,sCAGD,mNACC,sCAGD,mNACC,oCAMF,sBACC,aAGD,YACC,oBAGD,kBACC,0BAGD,yBACC,0BAGD,sBACC,0BAGD,oCACC,uBAIF,yCACC,uBAGD,wBACC,qBAGD,2BACC,wBAEA,gBACA,aACA,yBACA,sBAKD,WACC,kBACA,2BACA,WAGD,2DAGC,qBAIA,mCACC,qBACA,YACA,eAGD,+EAEC,YAIF,yBACC,mCACC,YACA,iBACA,cACA,iDAIF,eACC,WAGD,SACC,yBAGD,QACC,qBACA,YACA,WACA,2BAEA,gBACC,kBAIF,qBACC,sBACA,qBACA,YACA,iBAGD,kBACC,qBACA,gBAIA,aACC,sCACA,mCAGD,WACC,oCAGD,mBACC,sCACA,oBAMF,8CACC,yBACA,YAGD,wBACC,WACA,YACA,mBACA,kBACA,+DAIA,oBACC,yBACA,gBAEA,uBACC,cAGD,uBACC,kBAIF,0BACC,YACA,gCAGD,oDACC,yBAGD,wDACC,2BAGD,uBACC,cAKD,oBACC,0BAGD,oCACC,gBAIF,2BACC,aACA,eACA,mDAEA,8BACC,kBAGD,6BACC,WAIF,eACC,mBAEA,iBACC,qBACA,cAIF,SACC,UAGD,eACC,iBACA,mBACA,WAGD,UACI,+CAGJ,2BACE,GACE,YAGJ,mCACE,GACE","file":"settings.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["settings.scss","../../../core/css/variables.scss","../../../core/css/functions.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCEA;AAAA;AAAA;AAAA,GCFA;AAAA;AAAA;AAAA,GFUC,0BACC,WAKF,OACC,WAID,4BE2BC,2CFvBD,mBEuBC,kDFnBD,qBEmBC,yCFfD,0BEeC,wCFXD,oEEWC,2CFPD,oCACC,oBACA,0BACA,+BACA,mBAGD,4BACC,oBACA,kCAGD,yBACC,WAIA,wCACC,kBACA,yDACC,gBAIA,mOACC,WAKH,uCACC,aAGD,sCACC,WAED,uDACC,WAKD,gBACC,WAIF,mBACC,aACA,aACA,iBACA,uEACA,qBAEA,4BACC,kBACA,SAEA,+BACC,mBAIA,qCACC,iBAKH,kCACC,sBACA,mBACA,gBAGD,mGACC,4BACA,0BACA,WAMF,oBACC,kBACA,wCACC,0BAIF,aACC,oBACA,4CACA,kFACA,8CACA,wCACA,2CACA,8CACA,6CACA,mBACA,yCAEA,sCAEC,oDAGD,+CAEC,6DACA,oDAGD,6BACC,qCACA,WACA,YAIF,6BACC,oBACA,kCAEA,mCACC,WAIA,oCACC,kBACA,oBACA,iBACA,2BACA,WACA,mBACA,QAEA,0CACC,mBACA,uBACA,gBAKD,gIACC,kBACA,qBACA,UACA,oBACA,YAKH,qCACC,kBACA,wBACA,MACA,SAEA,yCACC,qBAIF,4CACC,eAGD,4CACC,sBACA,WACA,YACA,YAMF,qBACC,aACA,sBACA,SACA,YAEA,uBACC,aAGD,uCACC,sBACA,cACA,yBAIF,iBACC,kBACA,eACA,oCACA,qCACA,6CACA,SACA,gBACA,YAEA,8CAEC,+CACA,2CAEA,0FACC,WAIF,uCACC,0BACA,qBACA,gCACA,WACA,eAEA,wDACC,qBACA,sBACA,eAIF,sCACC,kCAGC,4DAEC,iBACA,kBAEA,kFACC,YAGD,mEACC,oDAEA,kFACC,iBAIF,qEACC,WAEA,eAEA,uEACC,eAQN,gBACC,YAIA,2BACC,kCAGD,mBACC,YAIF,sCAEC,aAGD,eACC,WAGD,YACC,qBAIA,aACC,WACA,yBACA,YAGD,WACC,WACA,yBACA,YAMD,oBACC,sBAGD,iBACC,eAKD,iCACC,aACA,eACA,sBACA,SACA,gDACC,aACA,eACA,sBACA,sDACC,oBAIF,kGACC,cACA,YACA,gBAKA,iEACC,kBACA,UAED,+EACC,oBACA,oBACA,wBACA,qBAIF,wCACC,WAGD,iDACC,qBAGD,sDACC,kBACA,qBACA,WACA,0BACA,eACA,gBACA,WAQF,oBACC,gBAGD,wBACC,yBAGD,oDACC,WACA,YACA,wCAOD,oBACC,UACA,cACA,gBACA,uBAGD,2BACC,UAKD,oCAEC,cAKD,wEAEC,aAIF,gBACC,kBACA,QACA,mBAEA,sBACC,YAGD,sBACC,iBAKF,WACC,WAEA,cACC,WACA,UACA,uBACA,4CACA,iBACA,mBAGD,cACC,4CACA,UACA,uBACA,iBACA,mBAKD,gBACC,0BACA,cACA,eACA,uBACA,gBAGD,wBACC,0BAEA,gCACC,kBAIF,sCACC,kBAGD,sDAEC,cACA,eACA,eAEA,0EACC,UACA,qBACA,uBACA,gBAIF,8BACC,eAGD,kCACC,wBACA,cAIF,2BACC,mBAMA,oBACC,mBACA,sBACA,WAGD,gCACC,0BAIA,gGACC,cAOH,SACC,gBAEA,0BACC,4CAID,YACC,oBACA,mBACA,uBACA,eACA,iBACA,gBACA,aAEA,uBACC,aACA,mBACA,uBACA,oCACA,qCACA,yDACA,sBACA,oCAKF,WACC,kBACA,kBACA,oCACA,gBAKF,KACC,mBACA,mBAGD,SACC,aAGD,mBACC,mBAGD,eACC,gBAOA,+IACC,sBAEA,+KACC,aAGD,mKACC,WACA,YACA,kCACA,qBACA,kBAGD,mOACC,sCAGD,mNACC,sCAGD,mNACC,oCAMF,sBACC,aAGD,YACC,oBAGD,kBACC,0BAGD,yBACC,0BAGD,sBACC,0BAGD,oCACC,uBAIF,yCACC,uBAGD,wBACC,qBAGD,2BACC,wBAEA,gBACA,aACA,yBACA,sBAKD,WACC,kBACA,2BACA,WAGD,2DAGC,qBAIA,mCACC,qBACA,YACA,eAGD,+EAEC,YAIF,yBACC,mCACC,YACA,iBACA,cACA,iDAIF,eACC,WAGD,SACC,yBAGD,QACC,qBACA,YACA,WACA,2BAEA,gBACC,kBAIF,qBACC,sBACA,qBACA,YACA,iBAGD,kBACC,qBACA,gBAIA,aACC,sCACA,mCAGD,WACC,oCAGD,mBACC,sCACA,oBAMF,8CACC,yBACA,YAGD,wBACC,WACA,YACA,mBACA,kBACA,+DAIA,oBACC,yBACA,gBAEA,uBACC,cAGD,uBACC,kBAIF,0BACC,YACA,gCAGD,oDACC,yBAGD,wDACC,2BAGD,uBACC,cAKD,oBACC,0BAGD,oCACC,gBAIF,2BACC,aACA,eACA,mDAEA,8BACC,SACA,eACA,iBAGD,6BACC,WAIF,eACC,mBAEA,iBACC,qBACA,cAIF,SACC,UAGD,eACC,iBACA,mBACA,WAGD,UACI,+CAGJ,2BACE,GACE,YAGJ,mCACE,GACE","file":"settings.css"}
|
||||
4
dist/files-init.js
vendored
4
dist/files-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-init.js.map
vendored
2
dist/files-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files_sharing-init.js
vendored
4
dist/files_sharing-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_sharing-init.js.map
vendored
2
dist/files_sharing-init.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue