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(files): File type filter UI sync with filter state #49259

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions apps/files/src/components/FileListFilter/FileListFilterType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export default defineComponent({
},

props: {
preset: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
preset: {
presets: {

We should use either singular or plural everywhere to minimize confusion

type: Array as PropType<ITypePreset[]>,
default: () => [],
},
typePresets: {
type: Array as PropType<ITypePreset[]>,
required: true,
Expand All @@ -71,6 +75,10 @@ export default defineComponent({
},

watch: {
/** Reset selected options if property is changed */
preset() {
this.selectedOptions = this.preset || []
},
selectedOptions(newValue, oldValue) {
if (this.selectedOptions.length === 0) {
if (oldValue.length !== 0) {
Expand All @@ -82,6 +90,10 @@ export default defineComponent({
},
},

mounted() {
this.selectedOptions = this.preset || []
},

methods: {
resetFilter() {
this.selectedOptions = []
Expand Down
21 changes: 17 additions & 4 deletions apps/files/src/filters/TypeFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import type { IFileListFilterChip, INode } from '@nextcloud/files'

import { subscribe } from '@nextcloud/event-bus'

Check failure on line 7 in apps/files/src/filters/TypeFilter.ts

View workflow job for this annotation

GitHub Actions / NPM lint

'subscribe' is defined but never used
import { FileListFilter, registerFileListFilter } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'
import Vue from 'vue'
Expand Down Expand Up @@ -89,12 +89,12 @@
class TypeFilter extends FileListFilter {

private currentInstance?: Vue
private currentPresets?: ITypePreset[]
private currentPresets: ITypePreset[]
private allPresets?: ITypePreset[]

constructor() {
super('files:type', 10)
subscribe('files:navigation:changed', () => this.setPreset())
this.currentPresets = []
}

public async mount(el: HTMLElement) {
Expand All @@ -103,13 +103,16 @@
this.allPresets = await getTypePresets()
}

// Already mounted
if (this.currentInstance) {
this.currentInstance.$destroy()
delete this.currentInstance
}

const View = Vue.extend(FileListFilterType as never)
this.currentInstance = new View({
propsData: {
preset: this.currentPresets,
typePresets: this.allPresets!,
},
el,
Expand Down Expand Up @@ -142,7 +145,8 @@
}

public setPreset(presets?: ITypePreset[]) {
this.currentPresets = presets
this.currentPresets = presets ?? []
this.currentInstance!.$props.preset = presets
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.currentInstance!.$props.preset = presets
this.currentInstance!.$props.preset = presets ?? []

The proptype is an array so we could do this and remove the || [] in FileListFilterType?

this.filterUpdated()

const chips: IFileListFilterChip[] = []
Expand All @@ -151,7 +155,7 @@
chips.push({
icon: preset.icon,
text: preset.label,
onclick: () => this.setPreset(presets.filter(({ id }) => id !== preset.id)),
onclick: () => this.removeFilterPreset(preset.id),
})
}
} else {
Expand All @@ -160,6 +164,15 @@
this.updateChips(chips)
}

/**

Check warning on line 167 in apps/files/src/filters/TypeFilter.ts

View workflow job for this annotation

GitHub Actions / NPM lint

Missing JSDoc @param "presetId" declaration
* Helper callback that removed a preset from selected.
* This is used when clicking on "remove" on a filter-chip.
*/
private removeFilterPreset(presetId: string) {
const filtered = this.currentPresets.filter(({ id }) => id !== presetId)
this.setPreset(filtered)
}

}

/**
Expand Down
49 changes: 49 additions & 0 deletions cypress/e2e/files/files-filtering.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,55 @@ describe('files: Filter in files list', { testIsolation: true }, () => {
getRowForFile('text.txt').should('not.exist')
})

/** Regression test of https://github.com/nextcloud/server/issues/47251 */
it.only('keeps filter state when changing the directory', () => {
// files are visible
getRowForFile('folder').should('be.visible')
getRowForFile('file.txt').should('be.visible')

// enable type filter for folders
filesFilters.filterContainter()
.findByRole('button', { name: 'Type' })
.should('be.visible')
.click()
cy.findByRole('menuitemcheckbox', { name: 'Folders' })
.should('be.visible')
.click()
// assert the button is checked
cy.findByRole('menuitemcheckbox', { name: 'Folders' })
.should('have.attr', 'aria-checked', 'true')
// close the menu
filesFilters.filterContainter()
.findByRole('button', { name: 'Type' })
.click()

// See the chips are active
filesFilters.activeFilters()
.should('have.length', 1)
.contains(/Folder/).should('be.visible')

// See that folder is visible but file not
getRowForFile('folder').should('be.visible')
getRowForFile('file.txt').should('not.exist')

// Change the directory
navigateToFolder('folder')
getRowForFile('folder').should('not.exist')

// See that the chip is still
filesFilters.activeFilters()
.should('have.length', 1)
.contains(/Folder/).should('be.visible')
// And also the button should be active
filesFilters.filterContainter()
.findByRole('button', { name: 'Type' })
.should('be.visible')
.click()
cy.findByRole('menuitemcheckbox', { name: 'Folders' })
.should('be.visible')
.and('have.attr', 'aria-checked', 'true')
})

it('resets filter when changing the view', () => {
// All are visible by default
getRowForFile('folder').should('be.visible')
Expand Down
4 changes: 2 additions & 2 deletions dist/6028-6028.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/6028-6028.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-init.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/systemtags-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/systemtags-init.js.map

Large diffs are not rendered by default.

Loading