Frontend created and rewritten a few times, with some backend fixes #1

Merged
leo merged 110 commits from plaintable into main 2023-11-08 20:38:40 +00:00
Showing only changes of commit 7e5901a2cf - Show all commits

View File

@ -32,43 +32,31 @@
</table>
</main>
</template>
</template>
<script setup lang="ts">
import { ref, h, computed, reactive, watchEffect } from 'vue'
import type { UnwrapRef } from 'vue'
import { useDocumentStore } from '@/stores/documents'
import Router from '@/router/index';
import { message } from 'ant-design-vue';
import type { Document, FolderDocument } from '@/repositories/Document';
import FileCarousel from './FileCarousel.vue';
import FileRenameInput from './FileRenameInput.vue'
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useDocumentStore } from '@/stores/documents'
import Router from '@/router/index';
import type { Document, FolderDocument } from '@/repositories/Document';
import FileCarousel from './FileCarousel.vue';
import FileRenameInput from './FileRenameInput.vue'
import createWebSocket from '@/repositories/WS';
const [messageApi, contextHolder] = message.useMessage();
type Key = string | number;
const documentStore = useDocumentStore()
const editableData: UnwrapRef<Record<string, Document>> = reactive({});
const state = reactive<{
selectedRowKeys: Key[];
}>({
selectedRowKeys: [],
});
const linkBasePath = computed(()=>{
const documentStore = useDocumentStore()
const linkBasePath = computed(()=>{
const path = Router.currentRoute.value.path
return path === '/' ? '' : path
})
const filesBasePath = computed(() => `/files${linkBasePath.value}`)
const url_for = (doc: FolderDocument) => (
})
const filesBasePath = computed(() => `/files${linkBasePath.value}`)
const url_for = (doc: FolderDocument) => (
doc.type === "folder" ?
`#${linkBasePath.value}/${doc.name}` :
`${filesBasePath.value}/${doc.name}`
)
// File rename
const editing = ref<FolderDocument | null>(null)
const rename = (doc: FolderDocument, newName: string) => {
)
// File rename
const editing = ref<FolderDocument | null>(null)
const rename = (doc: FolderDocument, newName: string) => {
const oldName = doc.name
const control = createWebSocket("/api/control", (ev: MessageEvent) => {
const msg = JSON.parse(ev.data)
@ -87,29 +75,29 @@ import createWebSocket from '@/repositories/WS';
}))
}
doc.name = newName // We should get an update from watch but this is quicker
}
}
// Column sort
const toggleSort = (name: string) => { sort.value = sort.value === name ? "" : name }
const sort = ref<string>("")
const sortCompare = {
// Column sort
const toggleSort = (name: string) => { sort.value = sort.value === name ? "" : name }
const sort = ref<string>("")
const sortCompare = {
"name": (a: Document, b: Document) => a.name.localeCompare(b.name),
"modified": (a: FolderDocument, b: FolderDocument) => b.mtime - a.mtime,
"size": (a: FolderDocument, b: FolderDocument) => b.size - a.size
}
const sorted = (documents: FolderDocument[]) => {
}
const sorted = (documents: FolderDocument[]) => {
const cmp = sortCompare[sort.value as keyof typeof sortCompare]
const sorted = [...documents]
if (cmp) sorted.sort(cmp)
return sorted
}
const selectionIndeterminate = computed({
}
const selectionIndeterminate = computed({
get: () => {
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.some((doc: Document) => doc.selected) && !allSelected.value
},
set: (value: boolean) => {}
})
const allSelected = computed({
})
const allSelected = computed({
get: () => {
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.every((doc: Document) => doc.selected)
},
@ -118,110 +106,110 @@ import createWebSocket from '@/repositories/WS';
documentStore.mainDocument.forEach((doc: Document) => doc.selected = value)
}
}
})
</script>
})
</script>
<style>
table {
<style>
table {
width: 100%;
table-layout: fixed;
}
table input[type=checkbox] {
}
table input[type=checkbox] {
width: 1em;
height: 1em;
}
table .modified { width: 10em; }
table .size { width: 6em; }
table th, table td {
}
table .modified { width: 10em; }
table .size { width: 6em; }
table th, table td {
padding: .5em;
font-weight: normal;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.name {
}
.name {
white-space: nowrap;
text-overflow: initial;
overflow: initial;
}
.name button {
}
.name button {
visibility: hidden;
padding-left: 1em;
}
.name:hover button {
}
.name:hover button {
visibility: visible;
}
.name button {
}
.name button {
cursor: pointer;
border: 0;
background: transparent;
}
thead tr {
}
thead tr {
border: 1px solid #ddd;
background: #ddd;
}
tbody tr {
}
tbody tr {
background: #444;
color: #ddd;
}
tbody tr:hover {
}
tbody tr:hover {
background: #00f8;
}
.right {
}
.right {
text-align: right;
}
.selection {
}
.selection {
width: 2em;
}
.sortcolumn:hover {
}
.sortcolumn:hover {
cursor: pointer;
}
.sortcolumn:hover::after {
}
.sortcolumn:hover::after {
color: #f80;
}
.sortcolumn {
}
.sortcolumn {
padding-right: 1.7em;
}
.sortcolumn::after {
}
.sortcolumn::after {
content: "▸";
color: #888;
margin: 0 1em 0 .5em;
position: absolute;
transition: transform 0.2s linear;
}
.sortactive::after {
}
.sortactive::after {
transform: rotate(90deg);
color: #000;
}
main {
}
main {
padding: 5px;
height: 100%;
}
.more-action{
}
.more-action{
display: flex;
flex-direction: column;
justify-content: start;
}
.action-container{
}
.action-container{
display: flex;
align-items: center;
}
.edit-action{
}
.edit-action{
min-width: 5%;
}
.carousel-container{
}
.carousel-container{
height: inherit;
}
.name a {
}
.name a {
text-decoration: none;
}
.file .name::before {
}
.file .name::before {
content: '📄 ';
font-size: 1.5em;
}
.folder .name::before {
}
.folder .name::before {
content: '📁 ';
font-size: 1.5em;
}
</style>
}
</style>