Skip to content

Commit 9303c0d

Browse files
committed
feat(FilePicker): Expose canPick option to gray out nodes
Signed-off-by: Louis Chmn <[email protected]>
1 parent 24bb191 commit 9303c0d

File tree

6 files changed

+49
-4
lines changed

6 files changed

+49
-4
lines changed

lib/components/FilePicker/FileList.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
:key="file.fileid || file.path"
6868
:allow-pick-directory="allowPickDirectory"
6969
:show-checkbox="multiselect"
70-
:can-pick="multiselect || selectedFiles.length === 0 || selectedFiles.includes(file)"
70+
:can-pick="(multiselect || selectedFiles.length === 0 || selectedFiles.includes(file)) && (canPick === undefined || canPick(file))"
7171
:selected="selectedFiles.includes(file)"
7272
:node="file"
7373
:crop-image-previews="cropImagePreviews"
@@ -82,6 +82,7 @@
8282
<script setup lang="ts">
8383
import type { FilesSortingMode, INode } from '@nextcloud/files'
8484
import type { FileListViews } from '../../composables/filesSettings.ts'
85+
import type { IFilePickerCanPick } from '../types.ts'
8586
8687
import { FileType, sortNodes } from '@nextcloud/files'
8788
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
@@ -125,6 +126,10 @@ const props = defineProps<{
125126
* Files to show
126127
*/
127128
files: INode[]
129+
/**
130+
* Custom function to decide if a node can be picked
131+
*/
132+
canPick?: IFilePickerCanPick
128133
}>()
129134
130135
/// sorting related stuff

lib/components/FilePicker/FileListRow.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
:class="[
1111
{
1212
'file-picker__row--selected': selected && !showCheckbox,
13+
'file-picker__row--not-pickable': !isPickable,
1314
},
1415
]"
1516
:data-filename="node.basename"
@@ -108,6 +109,10 @@ function toggleSelected() {
108109
* Handle clicking the table row, if it is a directory it is opened, else selected
109110
*/
110111
function handleClick() {
112+
if (!isPickable.value) {
113+
return
114+
}
115+
111116
if (isDirectory.value) {
112117
emit('enterDirectory', props.node)
113118
} else {
@@ -135,6 +140,12 @@ function handleKeyDown(event: KeyboardEvent) {
135140
&--selected {
136141
background-color: var(--color-background-dark);
137142
}
143+
144+
&--not-pickable {
145+
filter: saturate(0.7);
146+
opacity: 0.7;
147+
}
148+
138149
&:hover {
139150
background-color: var(--color-background-hover);
140151
}

lib/components/FilePicker/FilePicker.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
:multiselect="multiselect"
4444
:loading="isLoading"
4545
:name="viewHeadline"
46+
:can-pick="canPickFn"
4647
@update:path="currentView = 'files'" />
4748
<NcEmptyContent
4849
v-else-if="filterString"
@@ -67,7 +68,7 @@
6768
<script setup lang="ts">
6869
import type { Node } from '@nextcloud/files'
6970
import type { IFilesViewId } from '../../composables/views.ts'
70-
import type { IDialogButton, IFilePickerButton, IFilePickerButtonFactory, IFilePickerFilter } from '../types.ts'
71+
import type { IDialogButton, IFilePickerButton, IFilePickerButtonFactory, IFilePickerCanPick, IFilePickerFilter } from '../types.ts'
7172
7273
import { emit as emitOnEventBus } from '@nextcloud/event-bus'
7374
import { computed, onMounted, ref, shallowRef, toRef, watch } from 'vue'
@@ -108,6 +109,11 @@ const props = withDefaults(defineProps<{
108109
*/
109110
filterFn?: IFilePickerFilter
110111
112+
/**
113+
* Custom function to decide if a node can be picked
114+
*/
115+
canPickFn?: IFilePickerCanPick
116+
111117
/**
112118
* List of allowed mime types
113119
* You can use placeholders for e.g. allowing all subtypes of images `['image/*']`.
@@ -132,6 +138,7 @@ const props = withDefaults(defineProps<{
132138
allowPickDirectory: false,
133139
disabledNavigation: false,
134140
filterFn: undefined,
141+
canPickFn: undefined,
135142
mimetypeFilter: () => [],
136143
multiselect: false,
137144
path: undefined,

lib/components/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import type { Node } from '@nextcloud/files'
6+
import type { INode, Node } from '@nextcloud/files'
77

88
export type IDialogSeverity = 'info' | 'warning' | 'error'
99

@@ -58,3 +58,8 @@ export type IFilePickerButtonFactory = (selectedNodes: Node[], currentPath: stri
5858
* Type of filter functions to filter the FilePicker's file list
5959
*/
6060
export type IFilePickerFilter = (node: Node) => boolean
61+
62+
/**
63+
* Type of functions to allow or not picking a node
64+
*/
65+
export type IFilePickerCanPick = (node: INode) => boolean

lib/filepicker-builder.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import type { Node } from '@nextcloud/files'
7-
import type { IFilePickerButton, IFilePickerButtonFactory, IFilePickerFilter } from './components/types.ts'
7+
import type { IFilePickerButton, IFilePickerButtonFactory, IFilePickerCanPick, IFilePickerFilter } from './components/types.ts'
88

99
import IconMove from '@mdi/svg/svg/folder-move.svg?raw'
1010
import IconCopy from '@mdi/svg/svg/folder-multiple.svg?raw'
@@ -37,6 +37,7 @@ export class FilePicker<IsMultiSelect extends boolean> {
3737
private buttons: IFilePickerButton[] | IFilePickerButtonFactory
3838
private path?: string
3939
private filter?: IFilePickerFilter
40+
private canPick?: IFilePickerCanPick
4041
private container?: string
4142
private disabledNavigation: boolean
4243

@@ -48,6 +49,7 @@ export class FilePicker<IsMultiSelect extends boolean> {
4849
buttons: IFilePickerButton[] | IFilePickerButtonFactory,
4950
path?: string,
5051
filter?: IFilePickerFilter,
52+
canPick?: IFilePickerCanPick,
5153
container?: string,
5254
disabledNavigation = false,
5355
) {
@@ -57,6 +59,7 @@ export class FilePicker<IsMultiSelect extends boolean> {
5759
this.directoriesAllowed = directoriesAllowed
5860
this.path = path
5961
this.filter = filter
62+
this.canPick = canPick
6063
this.buttons = buttons
6164
this.container = container
6265
this.disabledNavigation = disabledNavigation
@@ -78,6 +81,7 @@ export class FilePicker<IsMultiSelect extends boolean> {
7881
mimetypeFilter: this.mimeTypeFilter,
7982
multiselect: this.multiSelect,
8083
filterFn: this.filter,
84+
canPickFn: this.canPick,
8185
disabledNavigation: this.disabledNavigation,
8286
}, {
8387
container: this.container,
@@ -112,6 +116,7 @@ export class FilePickerBuilder<IsMultiSelect extends boolean> {
112116
private directoriesAllowed = false
113117
private path?: string
114118
private filter?: IFilePickerFilter
119+
private canPick?: IFilePickerCanPick
115120
private buttons: IFilePickerButton[] | IFilePickerButtonFactory = []
116121
private container?: string
117122
private disabledNavigation = false
@@ -269,6 +274,16 @@ export class FilePickerBuilder<IsMultiSelect extends boolean> {
269274
return this
270275
}
271276

277+
/**
278+
* Add function to allow or not picking a node
279+
*
280+
* @param canPick Function to decide if a node can be picked
281+
*/
282+
public setCanPick(canPick: IFilePickerCanPick) {
283+
this.canPick = canPick
284+
return this
285+
}
286+
272287
/**
273288
* Disable navigation (view selection)
274289
*/
@@ -289,6 +304,7 @@ export class FilePickerBuilder<IsMultiSelect extends boolean> {
289304
this.buttons,
290305
this.path,
291306
this.filter,
307+
this.canPick,
292308
this.container,
293309
this.disabledNavigation,
294310
)

lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ export type {
5757
IDialogButton,
5858
IDialogSeverity,
5959
IFilePickerButton,
60+
IFilePickerCanPick,
6061
IFilePickerFilter,
6162
} from './components/types.ts'

0 commit comments

Comments
 (0)