
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<li @click="handleClick(idx, $event, item)" class="cursor">
<div
:class="{
'tree-container flex align-center': true,
selected: item.id === selectItem.id,
}"
>
<p v-if="item.children.length != 0">
<svg-icon
type="mdi"
:width="18"
:height="18"
:path="arrowPath"
></svg-icon>
</p>
<p>
<svg-icon
type="mdi"
:width="18"
:height="18"
:path="folderPath"
:color="'#fbbe28'"
></svg-icon>
</p>
<p class="node-text">{{ item.text }}</p>
</div>
<ul
v-if="item.children"
class="children-node"
:style="{ height: toggleSelect === idx ? 'auto' : '0' }"
>
<TreeItem
:connection="connection"
:selectedNode="parentSelectNode"
:closeModal="isCloseModal"
:selectItem="selectItem"
:parentSelectItem="item"
v-for="(child, idx) in item.children"
:item="child"
:idx="child.id"
:key="idx"
@selectFolder="emit"
@isLoading="handleIsLoading"
@selectItem="emitFolder"
/>
</ul>
</li>
</template>
<script>
import axios from "axios";
import SvgIcon from "@jamescoyle/vue-icon";
import {
mdiFolder,
mdiChevronRight,
mdiChevronDown,
mdiFileMultiple,
mdiFolderOpen,
} from "@mdi/js";
export default {
props: {
item: {
type: Object,
default: {
id: null,
},
},
idx: String,
selectedNode: String,
connection: {
type: Object,
default: {},
},
closeModal: Boolean,
isLoading: Boolean,
selectedId: String,
selectItem: {
type: Object,
default: {
id: null,
},
},
parentSelectItem: {
type: Object,
default: {
id: null,
},
},
},
data() {
return {
toggleSelect: null,
clidrunNode: false,
folderPath: mdiFolder,
arrowPath: mdiChevronRight,
filePath: mdiFileMultiple,
selectedId: null,
// host_code: null,
parentSelectNode: null,
isCloseModal: false,
isLoading: this.isLoading,
parentSelectedItem: {},
};
},
methods: {
handleClick: function (idx, event, item) {
this.$emit("isLoading", true); // 부모 컴포넌트에게 로딩중임을 알림
event.stopPropagation();
// 클릭한 폴더가 최상위 폴더일 때
if (item.id == "/home") {
this.parentSelectedItem = item; // 최상위 폴더일 때는 부모 폴더가 없으므로 현재 폴더 정보를 저장
}
// 이미 열려있는 같은 폴더를 클릭했을 때 (폴더별 열림상태 관리 필요)
if (this.toggleSelect === idx) {
if (idx === this.connection.path) {
// 선택된 폴더가 최상위 폴더일 때
if (!item.parent) {
this.selectedId = null;
this.toggleSelect = null;
this.parentSelectNode = null;
// this.parentSelectedItem = {};
this.parentSelectedItem = item; // 최상위 폴더일 때는 부모 폴더가 없으므로 현재 폴더 정보를 저장
} else {
this.selectedId = item.parent;
this.toggleSelect = item.parent;
this.parentSelectNode = item.parent;
this.parentSelectedItem = this.parentSelectItem;
}
this.emit(item.parent);
this.arrowPath = mdiChevronRight;
this.folderPath = mdiFolder;
} else {
this.parentSelectNode = idx;
if (!item.parent) {
this.parentSelectedItem = item; // 최상위 폴더일 때는 부모 폴더가 없으므로 현재 폴더 정보를 저장
} else {
this.parentSelectedItem = this.parentSelectItem;
}
if (item.children.length === 0) {
this.getChildren(idx, item.children);
} else {
this.emit(idx);
}
this.selectedId = this.selectItem.id;
this.toggleSelect = idx;
this.arrowPath = mdiChevronDown;
this.folderPath = mdiFolderOpen;
}
// 다른 폴더를 클릭했을 때 (열려있지 않은 폴더를 클릭했을 때가 되어야 함)
} else {
this.parentSelectNode = idx;
if (!item.parent) {
this.parentSelectedItem = item; // 최상위 폴더일 때는 부모 폴더가 없으므로 현재 폴더 정보를 저장
} else {
this.parentSelectedItem = this.parentSelectItem;
}
if (item.children.length === 0) {
this.getChildren(idx, item.children);
} else {
this.emit(idx);
}
this.selectedId = this.selectItem.id;
this.toggleSelect = idx;
this.arrowPath = mdiChevronDown;
this.folderPath = mdiFolderOpen;
}
this.emitFolder(item, this.parentSelectItem);
},
emit(path) {
this.$emit("selectFolder", path);
},
// 자식 파일 정보 조회
getChildren(path, children) {
const vm = this;
vm.connection.path = path;
vm.connection.type = "folder";
vm.connection.depth = 1;
axios
.get("/files/list", { params: vm.connection })
.then((response) => {
let childrenList = response.data.resultData.fileList;
childrenList.forEach((item) => {
children.push(item);
});
this.emit(path);
})
.catch((error) => {});
},
// 로딩 상태 변경
handleIsLoading(isLoadingValue) {
this.$emit("isLoading", true); // 자식 컴포넌트에게 로딩중임을 알림
},
// 선택 폴더 정보 전달
emitFolder(item, parentItem) {
this.$emit("selectItem", item, parentItem);
},
},
watch: {
closeModal: function (newValue) {
if (newValue) {
this.toggleSelect = null;
this.selectedId = null;
this.arrowPath = mdiChevronRight;
this.folderPath = mdiFolder;
this.isCloseModal = newValue;
} else {
this.isCloseModal = newValue;
}
},
},
components: {
SvgIcon: SvgIcon,
},
beforeCreate() {
this.$options.components.TreeItem = require("./FileTree.vue").default;
},
};
</script>
<style scoped>
.tree-container {
padding: 5px 10px;
}
.children-node {
padding: 0 0 0 10px;
overflow: hidden;
transition: max-height 0.5s ease-in-out;
}
.node-text {
font-size: 1.4rem;
margin-left: 5px;
}
</style>