implement filtering and sorting in drive

The `sort` parameter for /api/drive/show is now more unified with
other endpoints which use +createdAt for sort instead of +created.

closes FoundKeyGang/FoundKey#109

Changelog: Added
This commit is contained in:
Johann150 2023-03-26 12:03:43 +02:00
parent aac6a93bae
commit 134c3b43e6
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
2 changed files with 38 additions and 9 deletions

View file

@ -46,8 +46,8 @@ export const paramDef = {
sort: {
type: 'string',
enum: [
'+created',
'-created',
'+createdAt',
'-createdAt',
'+name',
'-name',
],
@ -58,6 +58,11 @@ export const paramDef = {
nullable: true,
default: null
},
name: {
description: 'Filters the output for files and folders that contain the given string (case insensitive).',
type: 'string',
default: '',
},
},
required: [],
} as const;
@ -66,10 +71,10 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => {
let orderBy = 'type ASC, id DESC';
switch (ps.sort) {
case '+created':
case '+createdAt':
orderBy = '"createdAt" DESC';
break;
case '-created':
case '-createdAt':
orderBy = '"createdAt" ASC';
break;
case '+name':
@ -84,11 +89,11 @@ export default define(meta, paramDef, async (ps, user) => {
const ids = await db.query(
'SELECT id FROM (SELECT id, "userId", "parentId", "createdAt", name, 0 AS type FROM drive_folder'
+ ' UNION SELECT id, "userId", "parentId", "createdAt", name, 1 AS type FROM drive_file) AS x'
+ ' WHERE "userId" = $1 AND "parentId"'
+ (ps.folderId ? '= $4' : 'IS NULL')
+ ' WHERE "userId" = $1 AND name ILIKE $2 AND "parentId"'
+ (ps.folderId ? '= $5' : 'IS NULL')
+ ' ORDER BY ' + orderBy
+ ' LIMIT $2 OFFSET $3',
[user.id, ps.limit, ps.offset, ...(ps.folderId ? [ps.folderId] : [])]
+ ' LIMIT $3 OFFSET $4',
[user.id, '%' + ps.name + '%', ps.limit, ps.offset, ...(ps.folderId ? [ps.folderId] : [])]
).then(items => items.map(({ id }) => id));
const [folders, files] = await Promise.all([

View file

@ -35,6 +35,24 @@
@drop.prevent.stop="onDrop"
@contextmenu.stop="onContextmenu"
>
<FormFolder>
<template #icon><i class="fas fa-search"></i></template>
<template #label>{{ i18n.ts.search }}</template>
<FormInput v-model="searchName" :debounce="true" :spellcheck="false">
<template #label>{{ i18n.ts.name }}</template>
<template #prefix><i class="fas fa-filter"></i></template>
</FormInput>
<FormSelect v-model="sort">
<template #label>{{ i18n.ts.sort }}</template>
<template #prefix><i class="fas fa-arrow-down-wide-short"></i></template>
<option :value="undefined">{{ i18n.ts.default }}</option>
<option value="+createdAt">{{ i18n.ts.createdAt }} ({{ i18n.ts.descendingOrder }})</option>
<option value="-createdAt">{{ i18n.ts.createdAt }} ({{ i18n.ts.ascendingOrder }})</option>
<option value="+name">{{ i18n.ts.name }} ({{ i18n.ts.descendingOrder }})</option>
<option value="-name">{{ i18n.ts.name }} ({{ i18n.ts.ascendingOrder }})</option>
</FormSelect>
</FormFolder>
<MkPagination
ref="paginationElem"
:pagination="pagination"
@ -91,6 +109,9 @@ import XFolder from './drive.folder.vue';
import XFile from './drive.file.vue';
import MkButton from './ui/button.vue';
import MkPagination from './ui/pagination.vue';
import FormFolder from '@/components/form/folder.vue';
import FormSelect from '@/components/form/select.vue';
import FormInput from '@/components/form/input.vue';
import * as os from '@/os';
import { stream } from '@/stream';
import { defaultStore } from '@/store';
@ -115,7 +136,6 @@ const emit = defineEmits<{
}>();
let paginationElem = $ref<InstanceType<typeof MkPagination>>();
let fileInput = $ref<HTMLInputElement>();
const uploadings = uploads;
@ -125,6 +145,8 @@ let folder = $ref<foundkey.entities.DriveFolder | null>(null);
let hierarchyFolders = $ref<foundkey.entities.DriveFolder[]>([]);
let selected = $ref<Array<foundkey.entities.DriveFile | foundkey.entities.DriveFolder>>([]);
let keepOriginal = $ref<boolean>(defaultStore.state.keepOriginalUploading);
let searchName = $ref<string>('');
let sort = $ref<undefined | string>(undefined);
//
let draghover = $ref(false);
@ -486,6 +508,8 @@ const pagination = {
limit: 30,
offsetMode: true,
params: computed(() => ({
sort,
name: searchName,
folderId: folder?.id ?? null,
})),
};