Files
yourpart3/frontend/src/components/FolderItem.vue
2024-12-04 19:08:26 +01:00

123 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 tee">|</span>
<span v-else class="marker filler">&nbsp;</span>
</template>
<span v-if="isLastItem" class="end-marker marker"></span>
<span v-else class="marker tee">&#x251C;</span>
<span class="folder-name-text">&nbsp;{{ 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;
}
.tee {
margin: 0 1px 0 -1px;
}
</style>