381 lines
12 KiB
Vue
381 lines
12 KiB
Vue
![]() |
<template>
|
|||
|
<vue3-tree-vue
|
|||
|
dir="ltr"
|
|||
|
:items="treeItems"
|
|||
|
:isCheckable="false"
|
|||
|
:hideGuideLines="false"
|
|||
|
@onCheck="onItemChecked"
|
|||
|
@dropValidator="onBeforeItemDropped"
|
|||
|
@onSelect="onClick"
|
|||
|
@onExpand="onItemExpanded"
|
|||
|
>
|
|||
|
<!-- Applying some simple styling to tree-items -->
|
|||
|
<template v-slot:item-prepend-icon="treeViewItem">
|
|||
|
<!-- :src="prependIcon(treeViewItem)" -->
|
|||
|
<!-- <img
|
|||
|
src="assets/common/img/vue3-treevue/folder.svg"
|
|||
|
alt="folder"
|
|||
|
height="20"
|
|||
|
width="20"
|
|||
|
/> -->
|
|||
|
<svg class="icon icon-folder-2">
|
|||
|
<use xlink:href="#icon-folder-2"></use>
|
|||
|
</svg>
|
|||
|
</template>
|
|||
|
</vue3-tree-vue>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
import "vue3-tree-vue/dist/style.css"; // remember to add this in your component or maint.[ts/js]
|
|||
|
import { mapState } from "pinia";
|
|||
|
import entityApi from "~/apis/entityApi";
|
|||
|
import { useCommonStore } from "~/stores/commonStore";
|
|||
|
|
|||
|
export default {
|
|||
|
props: {
|
|||
|
treeItems: {
|
|||
|
default() {
|
|||
|
return [];
|
|||
|
},
|
|||
|
},
|
|||
|
},
|
|||
|
watch: {
|
|||
|
treeItems(newVal) {
|
|||
|
this.dicTreePath = {};
|
|||
|
this.rootTreeItems.children = newVal;
|
|||
|
// this.rootTreeItems.children.forEach((element) => {
|
|||
|
// this.dicTreePath[element.keyId] = "" + element.index;
|
|||
|
// });
|
|||
|
},
|
|||
|
},
|
|||
|
|
|||
|
data() {
|
|||
|
return {
|
|||
|
dicTreePath: {},
|
|||
|
rootTreeItems: [
|
|||
|
{
|
|||
|
name: "Rejection Emails",
|
|||
|
type: "emails",
|
|||
|
expanded: true,
|
|||
|
children: [
|
|||
|
{
|
|||
|
name: "List of Rejection Emails",
|
|||
|
type: "excel",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Handling Rejection Through Open-sourcing User Guide",
|
|||
|
type: "doc",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Leet Code Tracking Sheet",
|
|||
|
type: "folder",
|
|||
|
expanded: true,
|
|||
|
children: [
|
|||
|
{
|
|||
|
name: "Solved Problems (30)",
|
|||
|
type: "excel",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Unsolved Problems (5000)",
|
|||
|
type: "folder",
|
|||
|
id: 6,
|
|||
|
expanded: true,
|
|||
|
children: [
|
|||
|
{
|
|||
|
name: "Inverting a linked list (lol)",
|
|||
|
id: 7,
|
|||
|
type: "playlist",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Decoding hieroglyphs",
|
|||
|
id: 8,
|
|||
|
type: "playlist",
|
|||
|
children: [
|
|||
|
{
|
|||
|
name: "List of Rejection Emails",
|
|||
|
id: 24334,
|
|||
|
type: "excel",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Handling Rejection Through Open-sourcing User Guide",
|
|||
|
id: 354545,
|
|||
|
type: "doc",
|
|||
|
},
|
|||
|
],
|
|||
|
},
|
|||
|
],
|
|||
|
},
|
|||
|
],
|
|||
|
},
|
|||
|
],
|
|||
|
},
|
|||
|
{
|
|||
|
name: "System Design Playlist",
|
|||
|
id: 993029302938,
|
|||
|
type: "playlist",
|
|||
|
children: [
|
|||
|
{
|
|||
|
name: "Space Station Design",
|
|||
|
id: 10,
|
|||
|
type: "playlist",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Gabbage Collector Design",
|
|||
|
id: 11,
|
|||
|
type: "playlist",
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Design Extra-Terrestrial Life Support",
|
|||
|
type: "playlist",
|
|||
|
id: 12,
|
|||
|
},
|
|||
|
],
|
|||
|
},
|
|||
|
{
|
|||
|
name: "Lazyloaded",
|
|||
|
id: 389813,
|
|||
|
type: "playlist",
|
|||
|
disabled: true,
|
|||
|
},
|
|||
|
],
|
|||
|
dicTreePath: {},
|
|||
|
};
|
|||
|
},
|
|||
|
computed: {
|
|||
|
...mapState(useCommonStore, ["paginationGetter"]),
|
|||
|
},
|
|||
|
|
|||
|
methods: {
|
|||
|
// new tree methods.
|
|||
|
onItemChecked(checkedItems) {
|
|||
|
console.log(checkedItems);
|
|||
|
},
|
|||
|
onItemSelected(item) {
|
|||
|
console.log(item);
|
|||
|
},
|
|||
|
onBeforeItemDropped(droppedItem, dropHost) {
|
|||
|
// dropHost == undefined means dropping at the root of the tree.
|
|||
|
|
|||
|
// Here you can specify any kind of drop validation you will like.
|
|||
|
// this function should return true if the drop operation is valid.
|
|||
|
|
|||
|
if (dropHost.type !== playlist) return false;
|
|||
|
return true;
|
|||
|
},
|
|||
|
onItemExpanded(expandedItem) {
|
|||
|
console.log(expandedItem);
|
|||
|
|
|||
|
//to use this feature properly you need to set lazyLoad property as true
|
|||
|
//fetch data
|
|||
|
// const lazyLoadedItems = fetchFromApi(...);
|
|||
|
// expandedItem.children.push(...lazyLoadedItems)
|
|||
|
},
|
|||
|
|
|||
|
// old tree methods.
|
|||
|
/**
|
|||
|
* حذف یک نود.
|
|||
|
* این متد یک نود را حذف میکند.
|
|||
|
*
|
|||
|
* @param {HTMLElement} node - نودی که قرار است حذف شود
|
|||
|
*/
|
|||
|
onDel(node) {
|
|||
|
node.remove();
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* تغییر نام.
|
|||
|
* این متد نام یک مورد را تغییر میدهد.
|
|||
|
*
|
|||
|
* @param {object} params - پارامترهای مورد نیاز
|
|||
|
*/
|
|||
|
onChangeName(params) {},
|
|||
|
|
|||
|
/**
|
|||
|
* افزودن یک نود جدید.
|
|||
|
*
|
|||
|
* @param {object} params - پارامترهای مورد نیاز
|
|||
|
*/
|
|||
|
onAddNode(params) {},
|
|||
|
|
|||
|
/**
|
|||
|
* رویداد کلیک.
|
|||
|
* این متد وظیفه اعمال تغییرات پس از کلیک را دارد.
|
|||
|
*
|
|||
|
* @param {object} params - پارامترهای مورد نیاز
|
|||
|
*/
|
|||
|
onClick(params) {
|
|||
|
if (this.classId !== "") {
|
|||
|
let id = document.getElementById(this.classId);
|
|||
|
if (id) id.classList.remove("selected");
|
|||
|
const element = document.getElementById(params.id);
|
|||
|
if (element) element.classList.add("selected");
|
|||
|
} else {
|
|||
|
const element = document.getElementById(params.id);
|
|||
|
if (element) element.classList.add("selected");
|
|||
|
}
|
|||
|
this.classId = structuredClone(params.id);
|
|||
|
this.$emit("on-click", params);
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* اضافه کردن یک نود جدید.
|
|||
|
*
|
|||
|
* @param {object} item - مورد جدید برای افزودن
|
|||
|
*/
|
|||
|
addNode(item) {
|
|||
|
var node = new TreeNode({ item: item, isLeaf: false });
|
|||
|
if (!this.rootTreeItems.children) this.rootTreeItems.children = [];
|
|||
|
this.rootTreeItems.addChildren(node);
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* بهروزرسانی فرزندان.
|
|||
|
* این متد فرزندان یک المان را بهروزرسانی میکند.
|
|||
|
*
|
|||
|
* @param {object} element - المانی که فرزندانش باید بهروز شود
|
|||
|
* @param {array} childs - فرزندان جدید
|
|||
|
*/
|
|||
|
updateChildren(element, childs) {
|
|||
|
var parent = this.rootTreeItems;
|
|||
|
if (element.parent != null) parent = element.parent;
|
|||
|
|
|||
|
const index = parent.children.findIndex((item) => item.id === element.id);
|
|||
|
if (index !== -1) {
|
|||
|
parent.children[index].children = childs;
|
|||
|
}
|
|||
|
},
|
|||
|
/**
|
|||
|
* دریافت درخت جدید.
|
|||
|
* این متد یک درخت جدید از دادههای فعلی دریافت میکند.
|
|||
|
*/
|
|||
|
getNewTree() {
|
|||
|
var vm = this;
|
|||
|
function _dfs(oldNode) {
|
|||
|
var newNode = {};
|
|||
|
|
|||
|
for (var k in oldNode) {
|
|||
|
if (k !== "children" && k !== "parent") {
|
|||
|
newNode[k] = oldNode[k];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (oldNode.children && oldNode.children.length > 0) {
|
|||
|
newNode.children = [];
|
|||
|
for (var i = 0, len = oldNode.children.length; i < len; i++) {
|
|||
|
newNode.children.push(_dfs(oldNode.children[i]));
|
|||
|
}
|
|||
|
}
|
|||
|
return newNode;
|
|||
|
}
|
|||
|
|
|||
|
vm.newTree = _dfs(vm.rootTreeItems);
|
|||
|
},
|
|||
|
},
|
|||
|
// components: {
|
|||
|
// VJstree,
|
|||
|
// VJstree: () => import("vue-jstree"),
|
|||
|
// },
|
|||
|
};
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
.icon-tree {
|
|||
|
color: #dbc056;
|
|||
|
font-size: 0.6rem;
|
|||
|
}
|
|||
|
.vtl-node-main {
|
|||
|
padding: 5px 1rem 5px 0 !important;
|
|||
|
|
|||
|
.vtl-node-content {
|
|||
|
// margin-right: 7px;
|
|||
|
}
|
|||
|
|
|||
|
&.vtl-drag-disabled {
|
|||
|
// background-color: #d0cfcf;
|
|||
|
background-color: inherit !important;
|
|||
|
}
|
|||
|
|
|||
|
&:hover {
|
|||
|
cursor: pointer;
|
|||
|
background-color: #f0f0f0 !important;
|
|||
|
}
|
|||
|
|
|||
|
.vtl-caret {
|
|||
|
// margin-left: 0;
|
|||
|
// margin-right: -1rem;
|
|||
|
// margin-top: 8px;
|
|||
|
// transform: rotateY(180deg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.vtl-tree-margin {
|
|||
|
// margin-right: 2em;
|
|||
|
// margin-left: auto;
|
|||
|
}
|
|||
|
|
|||
|
.vtl {
|
|||
|
.vtl-drag-disabled {
|
|||
|
background-color: #d0cfcf;
|
|||
|
|
|||
|
&:hover {
|
|||
|
background-color: #d0cfcf;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.vtl-disabled {
|
|||
|
background-color: #d0cfcf;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.vtl {
|
|||
|
}
|
|||
|
.tree-icon {
|
|||
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAABgCAMAAABblVsaAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAdRQTFRFAAAAHR0bubm5MzMz////28BW28BW28BW28BW28BW28BW28BW28BWeHh428BW28BW28BW28BWeHh4eHh428BWeHh4eHh4eHh428BW28BW28BW28BW28BW28BW28BWubm5ubm5ubm5dHZ7qKepgIKJXGNwVVdbALq6ALq6ALq6ALq6ALq6ALq6ALq670RE7kRE7kRE70RE70RE70RE70RE7e3tmJmY09PUALq6ALq670RE70RE70RE/Pv77Oztr6/jArW1EL6+3/b2ALq670REhISEAjawAbi47/v7ALq670REgICAALq6fn5+fHx8e3t7IMPD7EREJiYm39/gf3+4ALq670REscS0BAAABAoCfn5+ODg4+CgoAAAA9vX25+fnM6wABAQEpbml/v//8fLx1NPURm1D/Pr709TU/////v7/+/v68PLxOTk5OTk6//3+//7/PT49/v3+//7+Pj4+/f39//3//fz8/fv7/Pv8Nzc3PT09+vn5+vr6/Pr69fP19vb2/Pv7PDw88PHw8vPy8vTy8fLy8fPxOTk5+vr5+Pj59/f39vX19/b3+Pf4+/n6/Pv6dHZ7dXd8dXd8dnh9dnd8dHZ8dXZ7CQ4GCA4GCA4HCA0G1tXEywAAAJx0Uk5TAP////8krf+xKsrRSOT++64W7f9+8/b543tF2u2lE/z9/v//////QI/P79+fIECQ0O/fnyD///8Q/xCP/////0L//zAw//+y/6+v/+D/////Mf///7+//wkWgFr/Jv///0H//////////v///1ta/P9b+/9b+v////8BW/n///r//lr8/////1r9//////////39/Pz8/v4WFxcXHg+V+QAABbNJREFUeJztnM1vG0UYh99xHMVJFTsfFEpRaHFJqFoUoUagBpBaUSQkxAUh0ZRWyiIEJ0BC6glunJA4gcSJA0ECBP8AXPgqStsISCulgNrSuIQDVUlbN6b5ol4vO7t2vOuZ2fU4r+Pd8D5VJ+N9be/o6W9nZ+1NGeDCrObWW40wPtaSYWwisAVSAgk9KIF6UAKxoQTqQQnEhhKoR4wTmPA/LGHXG8QjsM273RSfGlZ330+ZoPW+fcJnoCQKWl+9nXEVjC2Le/YSlMA2U96vtx5Cm2dXluztQ+pNFtjl7jK5KO45EGyBAQlsvsC1bQl9gR3ln+23xF17CE+gt/WDkkDLbVsrsHNZLRA6VgFSjOXFEUjBFhiWwCgITLOFAIEu3dfEEXAogQC9JQgXCKviCKT4BZbPhKZKYGDdfT/L/8fzcgZWZZ+WqV9HEJixzUGfydtGBf6/E5gBWOgvcn/NSiBsboHcIDj+KIENzoGZsr8mJlDs11sPIRrrwMyC4vVoCRT79dZDiPiVCEYCvdsbvRZWE/Fr4W3+lXPfFXEEHPo0RlXfzioqCpAGxv6sc1jxERgNYpzAiEIC9aAEYkMC9aAEYkMC9aAEYoMucJN/MUwJxIYSqAclEBtKoB6UQGwogXpQArGhBOoR4wTuYGxurW9Zc7V1rPsDs4zZlhIX6xwW+ncigQl6gDmcU9WH3frPstrOrd5H83/U1hMj3kfTosCQeoVH8lZ/Hqzf5dUWfisHsP9mwvlmG/LnpfVH2dIWp2OdlFTvu8P76Nrl2vr6BQ46LYNSf97WpDBYC7rAgATu7q30/vlFVn9sbTDL02K1DkFrrxppTKDzjzLK/rrnSi6riGAL70yAg/yr1pR7D23XN2J9OF3tp74WyogCe24qBD7Bf3y7M0CgALpAdQKfKthNqsO5NaDnK7H+dKHaT38plPEE3jmVbVhgKxP4zHXe/vQwbxd+E+v7uqr9xbNCGU3gtlPQuEABhPsD1bcE+uujtj13i+3wtFh/HGDK3bIfYFLYPYLAnG0O7j7J2zgmcK8zx2VWV+y28KtY9yZw6YxQRhEI2e2T3F+E50A1D3bz1hUomwNHOqv9Js2BOd7Jyl9fOQsD3DsQzQQeWuJtZ/qq3d64INafna/2CzNCGWUOzJX9yRfS7kIQzIH+c2DmJE+QsJELaTeCHPlKuhpB2Uoa5ySSy6peb/Mcb2bMAdg605P6QTbE1l6JrK2k8z1T0nplJW1Zp8Ri869EXIaG4cw+W+Os6gl+Nu7+QM6hq6XMwt4ZyfHr8mS+tGVx8Lx4/MLGXQsfts9fZtLq/VFapU9jlPUGiY/AaBDjBEYUEqgHJRAbEqgHJRAbEqgHJRAbEqgHJRAbEqgHJRAbEqgHJRAbEqgHJRAbEqhHcxM4Zv/9XF0+4u6MfYq5z1ajI/AYfFLT8TPGklC01AaPfsHbF9jtzzR2GjHqTKABE5Ktx8AVV/lZy1j7HOwq3lYadASOstXp52NssBapQAOkAsvmVP7gSGr2/ksBBh2B44xZFwZia7CuBBoKf647pT8ucHcxwKB7CL9kJs/Cno/qGW0ckAg0lP4cg0p/jkCwDa4o5sGj6Q/t9hXGZoaW43oiCUpgeeIzAvwFHL9QFmgb3KGI4GtFLhDGPx7dcyuuAgV8Ark5I8xfSAIDBL7OPij3Xp2Pq8DAOdCw3Rmh+QueA4MO4TfY++MA3W3vARyOq0AB3xxo8GZC/eTws3DgSeQ4/x0QsBKTp18uxFVgyFnYqGv+UxkMWca8ydiJ4T74+67vYGglrgIFas7CxkTAc0OvREIW0m8lL2fdm0R3XYyrwKZeC4ddyr1d/t/W2ey/ZlwFCmzkhwnvuL8Jxy4NHo/tSaSlnwe++BDXZybZu3BgM1+JNI0xduDEQcZK3wMEHOjRhj6RxoYE6kEJxIYE6kEJxIYE6kEJxOY/TrEkjkDL/tIAAAAASUVORK5CYII=") !important;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
.label {
|
|||
|
position: relative;
|
|||
|
background-color: #fafafa;
|
|||
|
// background-color: #fff;
|
|||
|
padding: 0.3em;
|
|||
|
border-radius: 0.5em;
|
|||
|
margin-left: 1.4em;
|
|||
|
margin-top: 0.5rem;
|
|||
|
border: 1px solid #9e00b1;
|
|||
|
span {
|
|||
|
position: absolute;
|
|||
|
top: -0.5em;
|
|||
|
left: -1.2em;
|
|||
|
display: -webkit-box;
|
|||
|
display: -ms-flexbox;
|
|||
|
display: flex;
|
|||
|
}
|
|||
|
}
|
|||
|
.icon {
|
|||
|
&:hover {
|
|||
|
cursor: pointer;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.muted {
|
|||
|
color: gray;
|
|||
|
font-size: 80%;
|
|||
|
}
|
|||
|
|
|||
|
.tree {
|
|||
|
text-align: right;
|
|||
|
}
|
|||
|
|
|||
|
.tree-list-container {
|
|||
|
.tree-list-content {
|
|||
|
width: 100%;
|
|||
|
height: calc(100vh - 20em);
|
|||
|
overflow-y: auto;
|
|||
|
}
|
|||
|
|
|||
|
// }
|
|||
|
}
|
|||
|
</style>
|