Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
fix(FilePicker): Stop default close event in case of button press
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Apr 12, 2024
commit 2dcf65f3d2913263284b2e9b48021a258d80c089
4 changes: 2 additions & 2 deletions lib/components/DialogBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ const props = withDefaults(defineProps<{
* </style>
* ```
*/
navigationClasses?: string[]
navigationClasses?: string|Record<string, boolean>|(string|Record<string, boolean>)[]
/**
* Optionally pass additionaly classes which will be set on the content wrapper for custom styling
* @default []
*/
contentClasses?: string[]
contentClasses?: string|Record<string, boolean>|(string|Record<string, boolean>)[]
/**
* Optionally pass additionaly classes which will be set on the dialog itself
* (the default `class` attribute will be set on the modal wrapper)
Expand Down
57 changes: 37 additions & 20 deletions lib/components/FilePicker/FilePicker.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<template>
<DialogBase v-bind="dialogProps" @close="emit('close')">
<DialogBase :container="container"
:name="name"
:buttons="dialogButtons"
size="large"
content-classes="file-picker__content"
dialog-classes="file-picker"
navigation-classes="file-picker__navigation"
@close="handleClose">
<template #navigation="{ isCollapsed }">
<FilePickerNavigation :is-collapsed="isCollapsed" :current-view.sync="currentView" :filter-string.sync="filterString" />
</template>
Expand Down Expand Up @@ -44,7 +51,7 @@
</template>

<script setup lang="ts">
import type { IFilePickerButton, IFilePickerButtonFactory, IFilePickerFilter } from '../types'
import type { IDialogButton, IFilePickerButton, IFilePickerButtonFactory, IFilePickerFilter } from '../types'
import type { Node } from '@nextcloud/files'

import IconFile from 'vue-material-design-icons/File.vue'
Expand Down Expand Up @@ -122,19 +129,6 @@ const emit = defineEmits<{
*/
const { isPublic } = useIsPublic()

/**
* Props to be passed to the underlying Dialog component
*/
const dialogProps = computed(() => ({
container: props.container,
name: props.name,
buttons: dialogButtons.value,
size: 'large',
contentClasses: ['file-picker__content'],
dialogClasses: ['file-picker'],
navigationClasses: ['file-picker__navigation'],
}))

/**
* Map buttons to Dialog buttons by wrapping the callback function to pass the selected files
*/
Expand All @@ -146,13 +140,36 @@ const dialogButtons = computed(() => {
return buttons.map((button) => ({
...button,
callback: async () => {
const nodes = selectedFiles.value.length === 0 && props.allowPickDirectory ? [await getFile(currentPath.value)] : selectedFiles.value as Node[]
button.callback(nodes)
emit('close', selectedFiles.value as Node[])
isHandlingCallback = true
handleButtonClick(button.callback)
},
} as IFilePickerButton))
} as IDialogButton))
})

/**
* Flag that is set when a button was clicked to prevent the default close event to be emitted
* This is needed as `handleButtonClick` is async and thus might execute after NcDialog already closed
*/
let isHandlingCallback = false

const handleButtonClick = async (callback: IFilePickerButton['callback']) => {
const nodes = selectedFiles.value.length === 0 && props.allowPickDirectory ? [await getFile(currentPath.value)] : selectedFiles.value as Node[]
callback(nodes)
emit('close', nodes)
// Unlock close
isHandlingCallback = false
}

/**
* Handle closing of the dialog
* Do not emit close event on button press as this is handled by `handleButtonClick`
*/
const handleClose = () => {
if (!isHandlingCallback) {
emit('close')
}
}

/**
* Name of the currently active view
*/
Expand Down Expand Up @@ -225,7 +242,7 @@ const filteredFiles = computed(() => {
filtered = filtered.filter((file) => file.basename.toLowerCase().includes(filterString.value.toLowerCase()))
}
if (props.filterFn) {
filtered = filtered.filter((f) => props.filterFn(f as Node))
filtered = filtered.filter((f) => props.filterFn!(f as Node))
}
return filtered
})
Expand Down