Fix indent
This commit is contained in:
		| @@ -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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Leo Vasanko
					Leo Vasanko