2023-11-23 08:47:44 +07:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
|
import { storeToRefs } from 'pinia'
|
|
|
|
|
|
2023-12-11 15:51:59 +07:00
|
|
|
import FileIcon from './FileIcon.vue'
|
|
|
|
|
import FileItemAction from './FileItemAction.vue'
|
|
|
|
|
import DialogDelete from './DialogDelete.vue'
|
|
|
|
|
import FileFormWrapper from './FileFormWrapper.vue'
|
|
|
|
|
import FolderFormWrapper from './FolderFormWrapper.vue'
|
|
|
|
|
|
2023-11-23 18:00:43 +07:00
|
|
|
import { useFileInfoStore } from '@/stores/file-info-data'
|
2023-12-11 15:51:59 +07:00
|
|
|
import useStorage from '@/stores/storage'
|
|
|
|
|
|
|
|
|
|
const TREE_LEVEL_NAME = ['ตู้เอกสาร', 'ลิ้นชัก', 'แฟ้ม', 'แฟ้มย่อย'] as const
|
2023-11-23 08:47:44 +07:00
|
|
|
|
2023-11-28 16:30:48 +07:00
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{ action: boolean; viewMode: 'view_list' | 'view_module' }>(),
|
2023-12-11 15:51:59 +07:00
|
|
|
{ action: false },
|
2023-11-28 16:30:48 +07:00
|
|
|
)
|
2023-12-04 11:16:07 +07:00
|
|
|
const { getFileInfo } = useFileInfoStore()
|
2023-12-11 15:51:59 +07:00
|
|
|
|
|
|
|
|
const storageStore = useStorage()
|
|
|
|
|
const { folder, file, currentInfo } = storeToRefs(storageStore)
|
|
|
|
|
const { goto, deleteFolder, deleteFile } = storageStore
|
|
|
|
|
|
|
|
|
|
const fileFormComponent = ref<InstanceType<typeof FileFormWrapper>>()
|
|
|
|
|
const folderFormComponent = ref<InstanceType<typeof FolderFormWrapper>>()
|
|
|
|
|
|
|
|
|
|
const deleteState = ref<boolean>(false)
|
|
|
|
|
const deletePath = ref<string>('')
|
|
|
|
|
const deleteTarget = ref<'deleteFolder' | 'deleteFile'>()
|
|
|
|
|
const deleteMap = { deleteFolder, deleteFile }
|
2023-11-28 09:22:44 +07:00
|
|
|
|
2023-11-23 08:47:44 +07:00
|
|
|
const currentIcon = computed(() =>
|
2023-12-11 15:51:59 +07:00
|
|
|
currentInfo.value.dept === 0
|
2023-11-23 08:47:44 +07:00
|
|
|
? 'mdi-file-cabinet'
|
2023-12-11 15:51:59 +07:00
|
|
|
: currentInfo.value.dept === 1
|
2023-12-06 14:53:57 +07:00
|
|
|
? 'o_inbox'
|
2023-12-04 16:41:10 +07:00
|
|
|
: 'o_folder_open',
|
2023-11-23 08:47:44 +07:00
|
|
|
)
|
2023-11-28 16:30:48 +07:00
|
|
|
|
2023-11-29 17:11:21 +07:00
|
|
|
function triggerFolderDelete(pathname: string) {
|
2023-12-11 15:51:59 +07:00
|
|
|
deleteTarget.value = 'deleteFolder'
|
|
|
|
|
deletePath.value = pathname
|
|
|
|
|
deleteState.value = !deleteState.value
|
2023-11-29 17:11:21 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function triggerFileDelete(pathname: string) {
|
2023-12-11 15:51:59 +07:00
|
|
|
deleteTarget.value = 'deleteFile'
|
|
|
|
|
deletePath.value = pathname
|
|
|
|
|
deleteState.value = !deleteState.value
|
2023-11-28 16:30:48 +07:00
|
|
|
}
|
2023-11-23 08:47:44 +07:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2023-12-11 15:51:59 +07:00
|
|
|
<file-form-wrapper ref="fileFormComponent" />
|
|
|
|
|
<folder-form-wrapper ref="folderFormComponent" />
|
|
|
|
|
<dialog-delete
|
|
|
|
|
v-model:open="deleteState"
|
|
|
|
|
@confirm="() => deleteTarget && deleteMap[deleteTarget](deletePath)"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class="text-h6 q-mt-md"
|
|
|
|
|
v-if="currentInfo.dept > 2 && currentInfo.dept < 4"
|
|
|
|
|
>
|
2023-12-07 15:06:02 +07:00
|
|
|
<div class="flex justify-between items-center">
|
2023-12-11 15:51:59 +07:00
|
|
|
<div>{{ TREE_LEVEL_NAME[currentInfo.dept] }}</div>
|
2023-12-07 14:33:46 +07:00
|
|
|
<q-btn
|
|
|
|
|
outline
|
|
|
|
|
push
|
2023-12-11 15:51:59 +07:00
|
|
|
dense
|
|
|
|
|
id="listViewFolderCreate"
|
2023-12-07 14:33:46 +07:00
|
|
|
class="q-px-md q-ml-md"
|
|
|
|
|
type="submit"
|
|
|
|
|
color="primary"
|
|
|
|
|
icon="add"
|
2023-12-11 15:51:59 +07:00
|
|
|
v-if="action"
|
|
|
|
|
:label="'สร้าง' + TREE_LEVEL_NAME[currentInfo.dept]"
|
|
|
|
|
@click.stop="() => folderFormComponent?.triggerFolderCreate()"
|
2023-12-07 14:33:46 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
2023-11-29 15:26:18 +07:00
|
|
|
</div>
|
2023-12-11 15:51:59 +07:00
|
|
|
<div
|
|
|
|
|
class="grid q-mt-md"
|
|
|
|
|
v-if="currentInfo.dept < 4 && folder[currentInfo.path]"
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
v-for="value in folder[currentInfo.path]"
|
|
|
|
|
:data-pathname="value.pathname"
|
|
|
|
|
>
|
2023-11-23 08:47:44 +07:00
|
|
|
<div
|
2023-12-11 15:51:59 +07:00
|
|
|
class="box"
|
2023-11-29 15:26:18 +07:00
|
|
|
:style="{
|
|
|
|
|
position: 'relative',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
gap: '0.5rem',
|
|
|
|
|
alignItems: 'center',
|
2023-12-11 15:51:59 +07:00
|
|
|
flexDirection: currentInfo.dept > 2 ? 'row' : 'column',
|
|
|
|
|
padding: currentInfo.dept > 2 ? '.5rem 0' : '.5rem',
|
2023-11-29 15:26:18 +07:00
|
|
|
}"
|
2023-12-11 15:51:59 +07:00
|
|
|
@click="() => goto(value.pathname)"
|
2023-11-23 08:47:44 +07:00
|
|
|
>
|
2023-11-29 15:26:18 +07:00
|
|
|
<div class="q-px-md flex items-center justify-center">
|
|
|
|
|
<q-icon
|
|
|
|
|
:name="currentIcon"
|
2023-12-11 15:51:59 +07:00
|
|
|
:size="currentInfo.dept > 2 ? '3em' : '6em'"
|
2023-11-29 15:26:18 +07:00
|
|
|
color="primary"
|
|
|
|
|
class="col"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="absolute flex items-center justify-center"
|
|
|
|
|
style="top: 0.5rem; right: 0.5rem"
|
|
|
|
|
v-if="props.action"
|
2023-12-11 15:51:59 +07:00
|
|
|
:style="{ bottom: currentInfo.dept > 2 ? '0.5rem' : 'unset' }"
|
2023-11-29 15:26:18 +07:00
|
|
|
>
|
|
|
|
|
<file-item-action
|
2023-12-04 16:41:10 +07:00
|
|
|
:nameId="value.pathname"
|
2023-11-29 17:11:21 +07:00
|
|
|
@delete="() => triggerFolderDelete(value.pathname)"
|
2023-12-11 15:51:59 +07:00
|
|
|
@edit="
|
|
|
|
|
() =>
|
|
|
|
|
folderFormComponent?.triggerFolderEdit(
|
|
|
|
|
value.name,
|
|
|
|
|
value.pathname,
|
|
|
|
|
)
|
|
|
|
|
"
|
2023-11-29 15:26:18 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="text-overflow-handle block text-center"
|
2023-12-11 15:51:59 +07:00
|
|
|
style="max-width: 100%"
|
2023-11-29 15:26:18 +07:00
|
|
|
:class="{
|
2023-12-11 15:51:59 +07:00
|
|
|
'q-px-md': currentInfo.dept < 3,
|
|
|
|
|
'q-pr-xl': currentInfo.dept > 2,
|
2023-11-29 15:26:18 +07:00
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
{{ value.name }}
|
2023-11-23 08:47:44 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-11-29 15:26:18 +07:00
|
|
|
</div>
|
2023-12-11 15:51:59 +07:00
|
|
|
<div v-if="props.action && currentInfo.dept < 4">
|
2023-11-23 17:33:15 +07:00
|
|
|
<div
|
2023-12-11 15:51:59 +07:00
|
|
|
id="triggerFolderCreateFileItem"
|
2023-11-29 15:26:18 +07:00
|
|
|
class="dashed"
|
|
|
|
|
:style="{
|
|
|
|
|
position: 'relative',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
gap: '0.5rem',
|
|
|
|
|
alignItems: 'center',
|
2023-12-11 15:51:59 +07:00
|
|
|
flexDirection: currentInfo.dept > 2 ? 'row' : 'column',
|
|
|
|
|
padding: currentInfo.dept > 2 ? '.5rem 0' : '.5rem',
|
2023-11-29 15:26:18 +07:00
|
|
|
}"
|
2023-12-11 15:51:59 +07:00
|
|
|
@click.stop="() => folderFormComponent?.triggerFolderCreate()"
|
2023-11-23 17:33:15 +07:00
|
|
|
>
|
2023-11-29 15:26:18 +07:00
|
|
|
<div
|
|
|
|
|
class="q-px-md flex items-center justify-center"
|
|
|
|
|
style="position: relative"
|
|
|
|
|
>
|
|
|
|
|
<q-icon
|
|
|
|
|
:name="currentIcon"
|
2023-12-11 15:51:59 +07:00
|
|
|
:size="currentInfo.dept > 2 ? '3em' : '6em'"
|
2023-11-29 15:26:18 +07:00
|
|
|
color="primary"
|
|
|
|
|
class="col"
|
|
|
|
|
/>
|
|
|
|
|
<q-btn
|
|
|
|
|
round
|
|
|
|
|
color="white"
|
|
|
|
|
size="10px"
|
|
|
|
|
style="position: absolute; bottom: 0"
|
2023-12-11 15:51:59 +07:00
|
|
|
:dense="currentInfo.dept > 2"
|
|
|
|
|
:style="{ right: currentInfo.dept > 2 ? '.5rem' : '1rem' }"
|
2023-11-29 15:26:18 +07:00
|
|
|
>
|
|
|
|
|
<q-icon name="add" color="primary" size="1.5rem" />
|
|
|
|
|
</q-btn>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="text-overflow-handle block text-center"
|
|
|
|
|
:class="{
|
2023-12-11 15:51:59 +07:00
|
|
|
'q-px-md': currentInfo.dept < 3,
|
|
|
|
|
'q-pr-xl': currentInfo.dept > 2,
|
2023-11-29 15:26:18 +07:00
|
|
|
}"
|
|
|
|
|
style="max-width: 100%"
|
|
|
|
|
>
|
2023-12-11 15:51:59 +07:00
|
|
|
สร้าง{{ TREE_LEVEL_NAME[currentInfo.dept] }}
|
2023-11-23 08:47:44 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-11-29 15:26:18 +07:00
|
|
|
</div>
|
2023-12-11 15:51:59 +07:00
|
|
|
<div
|
|
|
|
|
style="grid-column: 1 / span 5"
|
|
|
|
|
class="q-mt-md"
|
|
|
|
|
v-if="currentInfo.dept > 2 && file[currentInfo.path]"
|
|
|
|
|
>
|
2023-12-07 14:33:46 +07:00
|
|
|
<div class="flex justify-between">
|
2023-12-07 15:06:02 +07:00
|
|
|
<div>
|
|
|
|
|
<span class="text-h6 q-mr-md">เอกสาร</span>
|
|
|
|
|
<span class="text-body text-grey"
|
2023-12-11 15:51:59 +07:00
|
|
|
>จำนวน {{ file[currentInfo.path].length }} รายการ</span
|
2023-12-07 15:06:02 +07:00
|
|
|
>
|
|
|
|
|
</div>
|
2023-12-07 14:33:46 +07:00
|
|
|
<q-btn
|
|
|
|
|
outline
|
|
|
|
|
push
|
2023-12-11 15:51:59 +07:00
|
|
|
dense
|
|
|
|
|
id="listViewFileCreate"
|
2023-12-07 14:33:46 +07:00
|
|
|
class="q-px-md q-ml-md"
|
|
|
|
|
label="สร้างเอกสาร"
|
|
|
|
|
type="submit"
|
|
|
|
|
color="primary"
|
|
|
|
|
icon="add"
|
2023-12-11 15:51:59 +07:00
|
|
|
v-if="action"
|
|
|
|
|
@click.stop="() => fileFormComponent?.triggerFileCreate()"
|
2023-12-07 14:33:46 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
2023-11-29 15:26:18 +07:00
|
|
|
</div>
|
|
|
|
|
<div class="grid q-mt-md">
|
2023-12-11 15:51:59 +07:00
|
|
|
<div
|
|
|
|
|
v-for="(value, index) in file[currentInfo.path]"
|
|
|
|
|
:data-pathname="value.pathname"
|
|
|
|
|
>
|
2023-11-28 09:24:20 +07:00
|
|
|
<div
|
2023-11-29 15:26:18 +07:00
|
|
|
class="box"
|
2023-12-04 09:28:40 +07:00
|
|
|
:id="`getFileInfoFileItem${index}`"
|
2023-12-11 15:51:59 +07:00
|
|
|
@click="() => getFileInfo(value)"
|
2023-11-28 09:24:20 +07:00
|
|
|
>
|
2023-11-29 15:26:18 +07:00
|
|
|
<div class="q-px-md flex items-center justify-center">
|
|
|
|
|
<file-icon
|
|
|
|
|
size="preview"
|
2023-12-11 15:51:59 +07:00
|
|
|
:fileMimeType="value.fileType ? value.fileType : '-'"
|
|
|
|
|
:fileName="value.fileName ? value.fileName : '-'"
|
2023-11-29 15:26:18 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="absolute"
|
|
|
|
|
style="top: 0.5rem; right: 0.5rem"
|
|
|
|
|
v-if="props.action"
|
|
|
|
|
>
|
|
|
|
|
<file-item-action
|
2023-12-04 16:41:10 +07:00
|
|
|
:nameId="value.pathname"
|
2023-11-29 15:26:18 +07:00
|
|
|
@edit="
|
|
|
|
|
() =>
|
2023-12-11 15:51:59 +07:00
|
|
|
fileFormComponent?.triggerFileEdit(
|
2023-11-29 15:26:18 +07:00
|
|
|
{
|
|
|
|
|
title: value.title,
|
|
|
|
|
description: value.description,
|
2023-12-01 09:26:34 +07:00
|
|
|
keyword: value.keyword,
|
|
|
|
|
category: value.category,
|
2024-01-10 18:03:28 +07:00
|
|
|
author: value.author,
|
2023-11-29 15:26:18 +07:00
|
|
|
},
|
2023-12-04 02:45:11 +00:00
|
|
|
value.pathname,
|
2023-12-12 17:32:16 +07:00
|
|
|
value.fileName,
|
2023-11-29 15:26:18 +07:00
|
|
|
)
|
|
|
|
|
"
|
2023-11-29 17:11:21 +07:00
|
|
|
@delete="() => triggerFileDelete(value.pathname)"
|
2023-11-29 15:26:18 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="text-overflow-handle block q-px-md text-center"
|
|
|
|
|
style="max-width: 100%"
|
|
|
|
|
>
|
2023-12-01 16:15:06 +07:00
|
|
|
{{ value.title }}
|
2023-11-28 09:24:20 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-11-29 15:26:18 +07:00
|
|
|
</div>
|
2023-12-11 15:51:59 +07:00
|
|
|
<div v-if="props.action && currentInfo.dept > 2">
|
2023-11-28 09:24:20 +07:00
|
|
|
<div
|
2023-12-11 15:51:59 +07:00
|
|
|
id="triggerFileCreateFileItem"
|
|
|
|
|
class="dashed"
|
2023-11-29 15:26:18 +07:00
|
|
|
:style="{
|
|
|
|
|
display: 'flex',
|
|
|
|
|
gap: '0.5rem',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
padding: '1rem',
|
|
|
|
|
maxWidth: '100%',
|
|
|
|
|
}"
|
2023-12-11 15:51:59 +07:00
|
|
|
@click.stop="() => fileFormComponent?.triggerFileCreate()"
|
2023-11-28 09:24:20 +07:00
|
|
|
>
|
2023-11-29 15:26:18 +07:00
|
|
|
<div
|
|
|
|
|
class="q-px-md flex items-center justify-center"
|
|
|
|
|
style="position: relative"
|
|
|
|
|
>
|
|
|
|
|
<q-icon name="mdi-file" class="add-icon" size="6em" color="primary" />
|
|
|
|
|
<q-btn
|
|
|
|
|
round
|
|
|
|
|
color="white"
|
|
|
|
|
size="10px"
|
2023-12-07 17:06:53 +07:00
|
|
|
style="position: absolute; right: 1rem; bottom: 0"
|
2023-11-29 15:26:18 +07:00
|
|
|
>
|
|
|
|
|
<q-icon name="add" color="primary" size="1.5rem" />
|
|
|
|
|
</q-btn>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="text-overflow-handle block q-px-md text-center"
|
|
|
|
|
style="max-width: 100%"
|
|
|
|
|
>
|
2023-12-07 14:33:46 +07:00
|
|
|
สร้างเอกสาร
|
2023-11-28 09:24:20 +07:00
|
|
|
</div>
|
2023-11-23 08:47:44 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-11-28 16:30:48 +07:00
|
|
|
</div>
|
2023-11-23 08:47:44 +07:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.box {
|
2023-11-28 09:24:20 +07:00
|
|
|
border: 2px solid $separator-color;
|
2023-11-23 08:47:44 +07:00
|
|
|
border-radius: 8px;
|
2023-12-11 15:51:59 +07:00
|
|
|
position: relative;
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 0.5rem;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 1rem;
|
|
|
|
|
max-width: 100%;
|
2023-11-23 08:47:44 +07:00
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dashed {
|
|
|
|
|
opacity: 0.4;
|
|
|
|
|
display: inline-block;
|
2023-11-28 09:24:20 +07:00
|
|
|
border: 2px solid #6985c2;
|
2023-11-23 08:47:44 +07:00
|
|
|
border-radius: 8px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-style: dashed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.add-icon {
|
|
|
|
|
margin: auto auto;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-28 09:24:20 +07:00
|
|
|
.text-overflow-handle {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
}
|
2023-11-29 15:26:18 +07:00
|
|
|
|
|
|
|
|
.grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
width: 100%;
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
gap: 1rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (min-width: $breakpoint-md-min) {
|
|
|
|
|
.grid {
|
|
|
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.grid .box {
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
2023-11-23 08:47:44 +07:00
|
|
|
</style>
|