Initial commit

This commit is contained in:
2022-08-17 21:59:51 +02:00
commit cc6feb3171
48 changed files with 42841 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
import { defineEmits, defineProps, inject } from 'vue';
import {
check_token,
delete_node,
download_file,
GetNodeResponse,
TokenInjectType
} from '@/api';
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
const props = defineProps<{
node: GetNodeResponse;
}>();
const emit = defineEmits<{
(e: 'reloadNode'): void;
}>();
async function del() {
const token = await check_token(jwt);
if (!token) return;
await delete_node(token, props.node.id);
emit('reloadNode');
}
async function download() {
const token = await check_token(jwt);
if (!token) return;
download_file(token, props.node.id);
}
</script>
<template>
<td>
<router-link :to="'/fs/' + props.node.id">{{ node.name }}</router-link>
</td>
<td>
<a href="#" @click="download()" v-if="props.node.isFile">Download</a>
</td>
<td>
<a href="#" @click="del()" v-if="props.node.name !== '..'">delete</a>
</td>
</template>
<style scoped></style>

View File

@@ -0,0 +1,111 @@
<script setup lang="ts">
import { defineEmits, defineProps, inject, reactive, ref, watch } from 'vue';
import {
GetNodeResponse,
create_folder,
get_node,
check_token,
TokenInjectType
} from '@/api';
import DirEntry from '@/components/FSView/DirEntry.vue';
import UploadFileDialog from '@/components/UploadDialog/UploadFileDialog.vue';
import { NModal } from 'naive-ui';
const props = defineProps<{
node: GetNodeResponse;
}>();
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
const emit = defineEmits<{
(e: 'reloadNode'): void;
(e: 'gotoRoot'): void;
}>();
const fileInput = ref<HTMLInputElement>();
const uploadDialog = ref();
const uploadDialogShow = ref(false);
const new_folder_name = ref('');
const files = ref<File[]>([]);
const nodes = ref<GetNodeResponse[]>([]);
const hasParent = ref(false);
const parentNode = reactive<GetNodeResponse>({
id: 0,
statusCode: 200,
isFile: false,
parent: null,
name: '..'
});
watch(
() => props.node,
async (to) => {
parentNode.id = to.parent ?? 0;
hasParent.value = to.parent != null;
nodes.value = [];
const token = await check_token(jwt);
if (!token) return;
await Promise.all(
to.children?.map(async (child) => {
nodes.value.push(
(await get_node(token, child)) as GetNodeResponse
);
}) ?? []
);
},
{ immediate: true }
);
async function newFolder() {
const token = await check_token(jwt);
if (!token) return;
await create_folder(token, props.node.id, new_folder_name.value);
emit('reloadNode');
}
async function uploadFiles() {
files.value = Array.from(fileInput.value?.files ?? []);
if (files.value.length == 0) return;
uploadDialogShow.value = true;
}
async function uploadFilesDialogOpen() {
await uploadDialog.value?.startUpload(props.node.id);
uploadDialogShow.value = false;
if (fileInput.value) fileInput.value.value = '';
emit('reloadNode');
}
</script>
<template>
<div>
<input
type="text"
placeholder="Folder name"
v-model="new_folder_name"
/>
<a href="#" @click="newFolder()">create folder</a>
</div>
<div>
<input type="file" ref="fileInput" multiple />
<a href="#" @click="uploadFiles()">upload files</a>
</div>
<table>
<tr v-if="hasParent">
<DirEntry :node="parentNode" @reloadNode="emit('reloadNode')" />
</tr>
<tr v-for="n in nodes" :key="n.id">
<DirEntry :node="n" @reloadNode="emit('reloadNode')" />
</tr>
</table>
<n-modal
v-model:show="uploadDialogShow"
:close-on-esc="false"
:mask-closable="false"
:on-after-enter="uploadFilesDialogOpen"
>
<UploadFileDialog ref="uploadDialog" :files="files" />
</n-modal>
</template>
<style scoped></style>

View File

@@ -0,0 +1,44 @@
<script setup lang="ts">
import { defineProps, inject } from 'vue';
import {
check_token,
delete_node,
download_file,
GetNodeResponse,
TokenInjectType
} from '@/api';
const props = defineProps<{
node: GetNodeResponse;
}>();
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
async function del() {
const token = await check_token(jwt);
if (!token) return;
await delete_node(token, props.node.id);
}
async function download() {
const token = await check_token(jwt);
if (!token) return;
download_file(token, props.node.id);
}
</script>
<template>
<div>
<router-link :to="'/fs/' + props.node.parent ?? 0">..</router-link>
</div>
<div>
<a href="#" @click="download()" v-if="props.node.isFile">Download</a>
</div>
<div>
<router-link :to="'/fs/' + props.node.parent ?? 0" @click="del()">
delete
</router-link>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,156 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this
project,<br />
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
>vue-cli documentation</a
>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
target="_blank"
rel="noopener"
>babel</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
target="_blank"
rel="noopener"
>router</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
target="_blank"
rel="noopener"
>vuex</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
target="_blank"
rel="noopener"
>eslint</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript"
target="_blank"
rel="noopener"
>typescript</a
>
</li>
</ul>
<h3>Essential Links</h3>
<ul>
<li>
<a href="https://vuejs.org" target="_blank" rel="noopener"
>Core Docs</a
>
</li>
<li>
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
>Forum</a
>
</li>
<li>
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
>Community Chat</a
>
</li>
<li>
<a
href="https://twitter.com/vuejs"
target="_blank"
rel="noopener"
>Twitter</a
>
</li>
<li>
<a href="https://news.vuejs.org" target="_blank" rel="noopener"
>News</a
>
</li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li>
<a
href="https://router.vuejs.org"
target="_blank"
rel="noopener"
>vue-router</a
>
</li>
<li>
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener"
>vuex</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-devtools#vue-devtools"
target="_blank"
rel="noopener"
>vue-devtools</a
>
</li>
<li>
<a
href="https://vue-loader.vuejs.org"
target="_blank"
rel="noopener"
>vue-loader</a
>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
rel="noopener"
>awesome-vue</a
>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
}
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
import { defineProps, defineExpose, ref } from 'vue';
import { isErrorResponse, upload_file } from '@/api';
import { NProgress } from 'naive-ui';
import filesize from 'filesize';
const props = defineProps<{
file: File;
}>();
const progress = ref(0);
const percentage = ref(0);
const err = ref('');
const status = ref('info');
async function startUpload(parent: number, token: string) {
const resp = await upload_file(token, parent, props.file, (e) => {
progress.value = e.loaded;
percentage.value = (e.loaded / e.total) * 100;
});
percentage.value = 100;
if (isErrorResponse(resp)) {
err.value = resp.message ?? 'Error';
status.value = 'error';
} else status.value = 'success';
}
defineExpose({
startUpload
});
</script>
<template>
<div v-if="percentage < 100">
{{ file.name }} - {{ filesize(progress) }} / {{ filesize(file.size) }} -
{{ Math.floor(percentage * 1000) / 1000 }}%
</div>
<div v-else-if="err !== ''">{{ file.name }} - Error: {{ err }}</div>
<div v-else>{{ file.name }} - Completed</div>
<n-progress
type="line"
:percentage="percentage"
:height="20"
:status="status"
border-radius="10px 0"
fill-border-radius="10px 0"
:show-indicator="false"
/>
</template>
<style scoped></style>

View File

@@ -0,0 +1,48 @@
<script setup lang="ts">
import { defineProps, defineExpose, ref, inject } from 'vue';
import { check_token, TokenInjectType } from '@/api';
import UploadEntry from '@/components/UploadDialog/UploadEntry.vue';
import { NCard } from 'naive-ui';
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
const entries = ref<typeof UploadEntry[]>([]);
const done = ref(false);
let canCloseResolve = null;
const canClose = new Promise((r) => (canCloseResolve = r));
async function startUpload(parent: number) {
const token = await check_token(jwt);
if (!token) return;
await Promise.all(
entries.value.map((entry) => entry.startUpload(parent, token))
);
done.value = true;
await canClose;
}
defineExpose({
startUpload
});
defineProps<{
files: File[];
}>();
</script>
<template>
<n-card title="Upload Files">
<div>
<UploadEntry
v-for="f in files"
:key="f.name"
ref="entries"
:file="f"
/>
</div>
<div>
<button v-if="done" @click="canCloseResolve()">Close</button>
</div>
</n-card>
</template>
<style scoped></style>