119 lines
3.1 KiB
Vue
119 lines
3.1 KiB
Vue
<template>
|
|
<div class="folder-item">
|
|
<div @click="selectFolder" class="folder-name" :class="{ selected: folder.id === selectedFolder?.id }">
|
|
<span v-if="!noActionItems" class="action-items">
|
|
<span @click="$emit('edit-folder', folder)" class="icon edit-icon" title="Edit folder">✎</span>
|
|
<span @click="$emit('delete-folder', folder)" class="icon delete-icon" title="Delete folder">✖</span>
|
|
</span>
|
|
<template v-for="i in depth">
|
|
<span v-if="showPipe(i)" class="marker filler">|</span>
|
|
<span v-else class="marker filler"> </span>
|
|
</template>
|
|
<span v-if="isLastItem" class="end-marker marker">⌞</span>
|
|
<span v-else class="marker">├</span>
|
|
<span class="folder-name-text"> {{ folder.name }}</span>
|
|
</div>
|
|
|
|
<template v-if="folder.children && folder.children.length" class="children">
|
|
<folder-item v-for="(child, index) in folder.children" :key="child.id" :folder="child"
|
|
:selected-folder="selectedFolder" @select-folder="forwardSelectFolderEvent"
|
|
@edit-folder="$emit('edit-folder', $event)" @delete-folder="$emit('delete-folder', $event)"
|
|
:depth="depth + 1" :isLastItem="index === folder.children.length - 1"
|
|
:parentsWithChildren="getNewParentsWithChildrenList(index)" :noActionItems="noActionItems">
|
|
</folder-item>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
folder: Object,
|
|
isLastItem: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
depth: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
parentsWithChildren: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
noActionItems: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
selectedFolder: Object,
|
|
},
|
|
methods: {
|
|
selectFolder() {
|
|
this.$emit('select-folder', this.folder);
|
|
},
|
|
forwardSelectFolderEvent(selectedFolder) {
|
|
this.$emit('select-folder', selectedFolder);
|
|
},
|
|
showPipe(index) {
|
|
return this.parentsWithChildren[index - 1];
|
|
},
|
|
getNewParentsWithChildrenList(index) {
|
|
const newParentsWithChildren = [...this.parentsWithChildren];
|
|
newParentsWithChildren.push(index < this.folder.children.length - 1);
|
|
return newParentsWithChildren;
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.selected {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.children {
|
|
margin-left: 20px;
|
|
}
|
|
|
|
.end-marker {
|
|
font-size: 1.2em;
|
|
vertical-align: middle;
|
|
margin-top: -22px;
|
|
padding-left: 3px;
|
|
}
|
|
|
|
.marker {
|
|
display: inline-block;
|
|
width: 10px;
|
|
}
|
|
|
|
.filler {
|
|
padding-left: 3.5px;
|
|
}
|
|
|
|
.folder-item {
|
|
margin: -2px 0;
|
|
}
|
|
|
|
.folder-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
|
|
.icon {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.edit-icon {
|
|
color: green;
|
|
}
|
|
|
|
.delete-icon {
|
|
color: red;
|
|
}
|
|
|
|
.folder-name-text {
|
|
cursor: pointer;
|
|
}
|
|
</style>
|