Fix indent

This commit is contained in:
Leo Vasanko 2023-11-02 18:51:34 +00:00
parent a4f95d730b
commit 7e5901a2cf

View File

@ -1,227 +1,215 @@
<template>
<main>
<context-holder />
<!-- <h2 v-if="!documentStore.loading && documentStore.error"> {{ documentStore.error }} </h2> -->
<div class="carousel-container" v-if="!documentStore.loading && documentStore.mainDocument[0] && documentStore.mainDocument[0].type === 'file'">
<FileCarousel></FileCarousel>
</div>
<main>
<context-holder />
<!-- <h2 v-if="!documentStore.loading && documentStore.error"> {{ documentStore.error }} </h2> -->
<div class="carousel-container" v-if="!documentStore.loading && documentStore.mainDocument[0] && documentStore.mainDocument[0].type === 'file'">
<FileCarousel></FileCarousel>
</div>
<table v-else-if="!documentStore.loading && documentStore.mainDocument">
<thead>
<tr>
<th class="selection"><input type="checkbox" v-model="allSelected" :indeterminate="selectionIndeterminate"></th>
<th class="sortcolumn" :class="{sortactive: sort === 'name'}" @click="toggleSort('name')">Name</th>
<th class="sortcolumn modified right" :class="{sortactive: sort === 'modified'}" @click="toggleSort('modified')">Modified</th>
<th class="sortcolumn size right" :class="{sortactive: sort === 'size'}" @click="toggleSort('size')">Size</th>
</tr>
</thead>
<tbody>
<tr v-for="doc of sorted(documentStore.mainDocument as FolderDocument[])" :key="doc.key" :class="doc.type === 'folder' ? 'folder' : 'file'">
<td class="selection"><input type="checkbox" v-model="doc.selected"></td>
<td class="name">
<template v-if="editing === doc"><FileRenameInput :doc="doc" :rename="rename" :exit="() => { editing = null}"/></template>
<template v-else>
<a :href="url_for(doc)">{{doc.name}}</a>
<button @click="() => editing = doc">🖊</button>
</template>
</td>
<td class="right">{{doc.modified}}</td>
<td class="right">{{doc.sizedisp}}</td>
</tr>
</tbody>
</table>
<table v-else-if="!documentStore.loading && documentStore.mainDocument">
<thead>
<tr>
<th class="selection"><input type="checkbox" v-model="allSelected" :indeterminate="selectionIndeterminate"></th>
<th class="sortcolumn" :class="{sortactive: sort === 'name'}" @click="toggleSort('name')">Name</th>
<th class="sortcolumn modified right" :class="{sortactive: sort === 'modified'}" @click="toggleSort('modified')">Modified</th>
<th class="sortcolumn size right" :class="{sortactive: sort === 'size'}" @click="toggleSort('size')">Size</th>
</tr>
</thead>
<tbody>
<tr v-for="doc of sorted(documentStore.mainDocument as FolderDocument[])" :key="doc.key" :class="doc.type === 'folder' ? 'folder' : 'file'">
<td class="selection"><input type="checkbox" v-model="doc.selected"></td>
<td class="name">
<template v-if="editing === doc"><FileRenameInput :doc="doc" :rename="rename" :exit="() => { editing = null}"/></template>
<template v-else>
<a :href="url_for(doc)">{{doc.name}}</a>
<button @click="() => editing = doc">🖊</button>
</template>
</td>
<td class="right">{{doc.modified}}</td>
<td class="right">{{doc.sizedisp}}</td>
</tr>
</tbody>
</table>
</main>
</template>
</main>
</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 path = Router.currentRoute.value.path
return path === '/' ? '' : path
})
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) => {
const oldName = doc.name
const control = createWebSocket("/api/control", (ev: MessageEvent) => {
const msg = JSON.parse(ev.data)
if ("error" in msg) {
console.error("Rename failed", msg.error.message, msg.error)
doc.name = oldName
} else {
console.log("Rename succeeded", msg)
}
})
control.onopen = () => {
control.send(JSON.stringify({
"op": "rename",
"path": `${linkBasePath.value}/${oldName}`,
"to": newName
}))
}
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 = {
"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 cmp = sortCompare[sort.value as keyof typeof sortCompare]
const sorted = [...documents]
if (cmp) sorted.sort(cmp)
return sorted
}
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({
get: () => {
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.every((doc: Document) => doc.selected)
},
set: (value: boolean) => {
if (documentStore.mainDocument) {
documentStore.mainDocument.forEach((doc: Document) => doc.selected = value)
}
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) => (
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) => {
const oldName = doc.name
const control = createWebSocket("/api/control", (ev: MessageEvent) => {
const msg = JSON.parse(ev.data)
if ("error" in msg) {
console.error("Rename failed", msg.error.message, msg.error)
doc.name = oldName
} else {
console.log("Rename succeeded", msg)
}
})
</script>
control.onopen = () => {
control.send(JSON.stringify({
"op": "rename",
"path": `${linkBasePath.value}/${oldName}`,
"to": newName
}))
}
doc.name = newName // We should get an update from watch but this is quicker
}
<style>
table {
width: 100%;
table-layout: fixed;
// 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 cmp = sortCompare[sort.value as keyof typeof sortCompare]
const sorted = [...documents]
if (cmp) sorted.sort(cmp)
return sorted
}
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({
get: () => {
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.every((doc: Document) => doc.selected)
},
set: (value: boolean) => {
if (documentStore.mainDocument) {
documentStore.mainDocument.forEach((doc: Document) => doc.selected = value)
}
}
table input[type=checkbox] {
width: 1em;
height: 1em;
}
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 {
white-space: nowrap;
text-overflow: initial;
overflow: initial;
}
.name button {
visibility: hidden;
padding-left: 1em;
}
.name:hover button {
visibility: visible;
}
.name button {
cursor: pointer;
border: 0;
background: transparent;
}
thead tr {
border: 1px solid #ddd;
background: #ddd;
}
tbody tr {
background: #444;
color: #ddd;
}
tbody tr:hover {
background: #00f8;
}
.right {
text-align: right;
}
.selection {
width: 2em;
}
.sortcolumn:hover {
cursor: pointer;
}
.sortcolumn:hover::after {
color: #f80;
}
.sortcolumn {
padding-right: 1.7em;
}
.sortcolumn::after {
content: "▸";
color: #888;
margin: 0 1em 0 .5em;
position: absolute;
transition: transform 0.2s linear;
}
.sortactive::after {
transform: rotate(90deg);
color: #000;
}
main {
padding: 5px;
height: 100%;
}
.more-action{
display: flex;
flex-direction: column;
justify-content: start;
}
.action-container{
display: flex;
align-items: center;
}
.edit-action{
min-width: 5%;
}
.carousel-container{
height: inherit;
}
.name a {
text-decoration: none;
}
.file .name::before {
content: '📄 ';
font-size: 1.5em;
}
.folder .name::before {
content: '📁 ';
font-size: 1.5em;
}
</style>
})
</script>
<style>
table {
width: 100%;
table-layout: fixed;
}
table input[type=checkbox] {
width: 1em;
height: 1em;
}
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 {
white-space: nowrap;
text-overflow: initial;
overflow: initial;
}
.name button {
visibility: hidden;
padding-left: 1em;
}
.name:hover button {
visibility: visible;
}
.name button {
cursor: pointer;
border: 0;
background: transparent;
}
thead tr {
border: 1px solid #ddd;
background: #ddd;
}
tbody tr {
background: #444;
color: #ddd;
}
tbody tr:hover {
background: #00f8;
}
.right {
text-align: right;
}
.selection {
width: 2em;
}
.sortcolumn:hover {
cursor: pointer;
}
.sortcolumn:hover::after {
color: #f80;
}
.sortcolumn {
padding-right: 1.7em;
}
.sortcolumn::after {
content: "▸";
color: #888;
margin: 0 1em 0 .5em;
position: absolute;
transition: transform 0.2s linear;
}
.sortactive::after {
transform: rotate(90deg);
color: #000;
}
main {
padding: 5px;
height: 100%;
}
.more-action{
display: flex;
flex-direction: column;
justify-content: start;
}
.action-container{
display: flex;
align-items: center;
}
.edit-action{
min-width: 5%;
}
.carousel-container{
height: inherit;
}
.name a {
text-decoration: none;
}
.file .name::before {
content: '📄 ';
font-size: 1.5em;
}
.folder .name::before {
content: '📁 ';
font-size: 1.5em;
}
</style>