completely refactor the backend
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
} from '@/components/ui/context-menu';
|
||||
import { deleteWarrenEntry } from '~/lib/api/warrens';
|
||||
import { deleteWarrenDirectory, deleteWarrenFile } from '~/lib/api/warrens';
|
||||
import type { DirectoryEntry } from '~/types';
|
||||
|
||||
const route = useRoute();
|
||||
@@ -21,7 +21,11 @@ const deleting = ref(false);
|
||||
async function submitDelete() {
|
||||
deleting.value = true;
|
||||
|
||||
await deleteWarrenEntry(warrenRoute.value, entry.name, entry.fileType);
|
||||
if (entry.fileType === 'directory') {
|
||||
await deleteWarrenDirectory(warrenRoute.value, entry.name);
|
||||
} else {
|
||||
await deleteWarrenFile(warrenRoute.value, entry.name);
|
||||
}
|
||||
|
||||
deleting.value = false;
|
||||
}
|
||||
@@ -32,7 +36,13 @@ async function submitDelete() {
|
||||
<ContextMenuTrigger>
|
||||
<NuxtLink
|
||||
:to="joinPaths(route.path, entry.name)"
|
||||
:class="['select-none', { 'pointer-events-none': disabled }]"
|
||||
:class="[
|
||||
'select-none',
|
||||
{
|
||||
'pointer-events-none':
|
||||
disabled || entry.fileType === 'file',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<Button
|
||||
class="w-44 h-12"
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import { toast } from 'vue-sonner';
|
||||
import type { DirectoryEntry, FileType } from '~/types';
|
||||
import type { ApiResponse } from '~/types/api';
|
||||
import type { Warren } from '~/types/warrens';
|
||||
|
||||
export async function getWarrens(): Promise<Record<string, Warren>> {
|
||||
const { data: arr, error } = await useFetch<Warren[]>(
|
||||
const { data, error } = await useFetch<ApiResponse<{ warrens: Warren[] }>>(
|
||||
getApiUrl('warrens'),
|
||||
{
|
||||
method: 'GET',
|
||||
}
|
||||
);
|
||||
|
||||
if (arr.value == null) {
|
||||
if (data.value == null) {
|
||||
throw error.value?.name;
|
||||
}
|
||||
|
||||
const warrens: Record<string, Warren> = {};
|
||||
|
||||
for (const warren of arr.value) {
|
||||
for (const warren of data.value.data.warrens) {
|
||||
warrens[warren.id] = warren;
|
||||
}
|
||||
|
||||
@@ -30,23 +31,31 @@ export async function getWarrenDirectory(
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '';
|
||||
rest = '/';
|
||||
} else {
|
||||
rest = '/' + rest;
|
||||
rest = '/' + decodeURI(rest);
|
||||
}
|
||||
|
||||
const { data: entries, error } = await useFetch<DirectoryEntry[]>(
|
||||
getApiUrl(`warrens/${warrenId}/get${rest}`),
|
||||
{
|
||||
method: 'GET',
|
||||
}
|
||||
);
|
||||
const { data, error } = await useFetch<
|
||||
ApiResponse<{ files: DirectoryEntry[] }>
|
||||
>(getApiUrl(`warrens/files`), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
warrenId,
|
||||
path: rest,
|
||||
}),
|
||||
});
|
||||
|
||||
if (entries.value == null) {
|
||||
if (data.value == null) {
|
||||
throw error.value?.name;
|
||||
}
|
||||
|
||||
return entries.value;
|
||||
const { files } = data.value.data;
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function createDirectory(
|
||||
@@ -57,17 +66,23 @@ export async function createDirectory(
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '';
|
||||
rest = '/';
|
||||
} else {
|
||||
rest += '/';
|
||||
rest = '/' + rest + '/';
|
||||
}
|
||||
|
||||
const { status } = await useFetch(
|
||||
getApiUrl(`warrens/${warrenId}/create/${rest}${directoryName}`),
|
||||
{
|
||||
method: 'POST',
|
||||
}
|
||||
);
|
||||
rest += directoryName;
|
||||
|
||||
const { status } = await useFetch(getApiUrl(`warrens/files/directory`), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
warrenId,
|
||||
path: rest,
|
||||
}),
|
||||
});
|
||||
|
||||
if (status.value !== 'success') {
|
||||
toast.error('Directory', {
|
||||
@@ -87,44 +102,93 @@ export async function createDirectory(
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function deleteWarrenEntry(
|
||||
export async function deleteWarrenDirectory(
|
||||
path: string,
|
||||
directoryName: string,
|
||||
fileType: FileType
|
||||
directoryName: string
|
||||
): Promise<{ success: boolean }> {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '';
|
||||
rest = '/';
|
||||
} else {
|
||||
rest = '/' + rest;
|
||||
rest = '/' + rest + '/';
|
||||
}
|
||||
|
||||
const { status } = await useFetch(
|
||||
getApiUrl(
|
||||
`warrens/${warrenId}/delete${rest}/${directoryName}?fileType=${fileType}`
|
||||
),
|
||||
{
|
||||
method: 'DELETE',
|
||||
}
|
||||
);
|
||||
rest += directoryName;
|
||||
|
||||
const toastTitle = fileType.slice(0, 1).toUpperCase() + fileType.slice(1);
|
||||
const { status } = await useFetch(getApiUrl(`warrens/files/directory`), {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
warrenId,
|
||||
path: rest,
|
||||
force: false,
|
||||
}),
|
||||
});
|
||||
|
||||
const TOAST_TITLE = 'Directory';
|
||||
|
||||
if (status.value !== 'success') {
|
||||
toast.error(toastTitle, {
|
||||
toast.error(TOAST_TITLE, {
|
||||
id: 'DELETE_DIRECTORY_TOAST',
|
||||
description: `Failed to delete ${fileType}`,
|
||||
description: `Failed to delete directory`,
|
||||
});
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
await refreshNuxtData('current-directory');
|
||||
|
||||
toast.success(toastTitle, {
|
||||
toast.success(TOAST_TITLE, {
|
||||
id: 'DELETE_DIRECTORY_TOAST',
|
||||
description: `Successfully deleted ${fileType}: ${directoryName}`,
|
||||
description: `Successfully deleted ${directoryName}`,
|
||||
});
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function deleteWarrenFile(
|
||||
path: string,
|
||||
fileName: string
|
||||
): Promise<{ success: boolean }> {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '/';
|
||||
} else {
|
||||
rest = '/' + rest + '/';
|
||||
}
|
||||
|
||||
rest += fileName;
|
||||
|
||||
const { status } = await useFetch(getApiUrl(`warrens/files/file`), {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
warrenId,
|
||||
path: rest,
|
||||
}),
|
||||
});
|
||||
|
||||
const TOAST_TITLE = 'File';
|
||||
|
||||
if (status.value !== 'success') {
|
||||
toast.error(TOAST_TITLE, {
|
||||
id: 'DELETE_FILE_TOAST',
|
||||
description: `Failed to delete file`,
|
||||
});
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
await refreshNuxtData('current-directory');
|
||||
|
||||
toast.success(TOAST_TITLE, {
|
||||
id: 'DELETE_FILE_TOAST',
|
||||
description: `Successfully deleted ${fileName}`,
|
||||
});
|
||||
return { success: true };
|
||||
}
|
||||
@@ -134,22 +198,17 @@ export async function uploadToWarren(
|
||||
files: FileList,
|
||||
onProgress: ((loaded: number, total: number) => void) | undefined
|
||||
): Promise<{ success: boolean }> {
|
||||
const body = new FormData();
|
||||
for (const file of files) {
|
||||
body.append('files', file);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '';
|
||||
rest = '/';
|
||||
} else {
|
||||
rest = '/' + rest;
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', getApiUrl(`warrens/${warrenId}/upload${rest}`));
|
||||
xhr.open('POST', getApiUrl(`warrens/files/upload`));
|
||||
xhr.upload.onprogress = (e) => {
|
||||
onProgress?.(e.loaded, e.total);
|
||||
};
|
||||
@@ -160,7 +219,7 @@ export async function uploadToWarren(
|
||||
return;
|
||||
}
|
||||
|
||||
if (xhr.status === 200) {
|
||||
if (xhr.status >= 200 && xhr.status <= 300) {
|
||||
res();
|
||||
} else {
|
||||
rej();
|
||||
@@ -168,6 +227,13 @@ export async function uploadToWarren(
|
||||
};
|
||||
});
|
||||
|
||||
const body = new FormData();
|
||||
body.set('warrenId', warrenId);
|
||||
body.set('path', rest);
|
||||
for (const file of files) {
|
||||
body.append('files', file);
|
||||
}
|
||||
|
||||
xhr.send(body);
|
||||
|
||||
try {
|
||||
|
||||
4
frontend/types/api.ts
Normal file
4
frontend/types/api.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type ApiResponse<T> = {
|
||||
status: number;
|
||||
data: T;
|
||||
};
|
||||
Reference in New Issue
Block a user