2023-04-19 20:16:22 +08:00
|
|
|
<template>
|
2023-06-07 20:00:34 +08:00
|
|
|
<div>
|
|
|
|
<div class="text-sn-blue w-full flex justify-center flex-col menu-item"
|
|
|
|
:class="{ 'bg-sn-super-light-blue active': activeItem }"
|
|
|
|
:style="{ 'padding-left': paddingLeft + 'px', 'min-width': (paddingLeft + 182) + 'px' }"
|
|
|
|
:navigator-item-id="item.id"
|
|
|
|
>
|
|
|
|
<div class="min-w-[182px] py-1.5 px-1 flex items-center whitespace-nowrap" :title="this.itemToolTip">
|
|
|
|
<div class="w-6 h-6 flex justify-start shrink-0 mr-2">
|
|
|
|
<i v-if="hasChildren"
|
|
|
|
class="sn-icon cursor-pointer"
|
|
|
|
:class="{'sn-icon-right': !childrenExpanded, 'sn-icon-down': childrenExpanded }"
|
|
|
|
@click="toggleChildren"></i>
|
|
|
|
</div>
|
|
|
|
<i v-if="itemIcon" class="mr-1" :class="itemIcon"></i>
|
|
|
|
<a :href="item.url"
|
|
|
|
class="text-ellipsis overflow-hidden hover:no-underline pr-3"
|
|
|
|
:class="{
|
|
|
|
'text-sn-science-blue-hover': (!item.archived && archived),
|
|
|
|
'no-hover': (!item.archived && archived)
|
|
|
|
}">
|
|
|
|
<template v-if="item.archived">(A)</template>
|
|
|
|
{{ item.name }}
|
|
|
|
</a>
|
2023-04-21 21:25:52 +08:00
|
|
|
</div>
|
2023-04-19 20:16:22 +08:00
|
|
|
</div>
|
2023-04-21 21:25:52 +08:00
|
|
|
<div class="basis-full" :class="{'hidden': !childrenExpanded}">
|
2023-04-25 18:30:45 +08:00
|
|
|
<NavigatorItem v-for="item in sortedMenuItems"
|
2023-06-07 20:00:34 +08:00
|
|
|
@item:expand="treeExpand"
|
|
|
|
:key="item.id"
|
|
|
|
:currentItemId="currentItemId"
|
|
|
|
:paddingLeft="24 + paddingLeft"
|
|
|
|
:reloadCurrentLevel="reloadCurrentLevel"
|
|
|
|
:reloadChildrenLevel="reloadChildrenLevel"
|
|
|
|
:item="item"
|
|
|
|
:archived="archived" />
|
2023-04-19 20:16:22 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
export default {
|
|
|
|
name: 'NavigatorItem',
|
|
|
|
props: {
|
2023-05-16 20:05:01 +08:00
|
|
|
firstLevel: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
2023-04-21 21:25:52 +08:00
|
|
|
item: Object,
|
2023-04-25 18:30:45 +08:00
|
|
|
currentItemId: String,
|
2023-04-26 16:24:50 +08:00
|
|
|
archived: Boolean,
|
2023-06-07 20:00:34 +08:00
|
|
|
paddingLeft: Number,
|
2023-04-26 16:24:50 +08:00
|
|
|
reloadCurrentLevel: Boolean,
|
|
|
|
reloadChildrenLevel: Boolean
|
2023-04-19 20:16:22 +08:00
|
|
|
},
|
|
|
|
data: function() {
|
|
|
|
return {
|
2023-04-21 21:25:52 +08:00
|
|
|
childrenExpanded: false,
|
2023-05-04 20:02:04 +08:00
|
|
|
childrenLoaded: false,
|
2023-04-21 21:25:52 +08:00
|
|
|
children: []
|
|
|
|
};
|
2023-04-19 20:16:22 +08:00
|
|
|
},
|
|
|
|
computed: {
|
2023-04-21 21:25:52 +08:00
|
|
|
hasChildren: function() {
|
2023-05-04 20:02:04 +08:00
|
|
|
return this.item.has_children || this.children.length > 0;
|
2023-04-19 20:16:22 +08:00
|
|
|
},
|
|
|
|
sortedMenuItems: function() {
|
2023-04-26 16:24:50 +08:00
|
|
|
return this.children.sort((a, b) => {
|
2023-05-11 18:38:54 +08:00
|
|
|
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
2023-04-26 16:24:50 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2023-05-11 18:38:54 +08:00
|
|
|
if (a.name.toLowerCase() > b.name.toLowerCase()) {
|
2023-04-26 16:24:50 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
});
|
2023-04-21 21:25:52 +08:00
|
|
|
},
|
|
|
|
activeItem: function() {
|
|
|
|
return this.item.id == this.currentItemId;
|
|
|
|
},
|
|
|
|
itemIcon: function() {
|
|
|
|
switch(this.item.type) {
|
|
|
|
case 'folder':
|
2023-05-17 17:47:25 +08:00
|
|
|
return 'sn-icon mini sn-icon-mini-folder-left';
|
2023-04-21 21:25:52 +08:00
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
2023-05-08 05:52:05 +08:00
|
|
|
},
|
|
|
|
itemToolTip: function() {
|
2023-05-09 04:06:37 +08:00
|
|
|
if (this.item.type == 'folder')
|
|
|
|
return this.item.name;
|
|
|
|
return this.i18n.t('sidebar.elements_tooltip', { type: this.i18n.t(`activerecord.models.${this.item.type}`), name: this.item.name});
|
2023-04-21 21:25:52 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
created: function() {
|
|
|
|
if (this.item.children) this.children = this.item.children;
|
|
|
|
},
|
|
|
|
mounted: function() {
|
|
|
|
this.selectItem();
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
currentItemId: function() {
|
|
|
|
this.selectItem();
|
2023-04-26 16:24:50 +08:00
|
|
|
},
|
|
|
|
reloadChildrenLevel: function() {
|
|
|
|
if (this.reloadChildrenLevel && this.item.id == this.currentItemId) {
|
|
|
|
this.loadChildren();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
reloadCurrentLevel: function() {
|
|
|
|
if (this.reloadCurrentLevel && this.children.find((item) => item.id == this.currentItemId)) {
|
|
|
|
this.loadChildren();
|
|
|
|
}
|
2023-05-04 20:02:04 +08:00
|
|
|
},
|
|
|
|
children: function() {
|
|
|
|
if (this.children.length > 0) {
|
|
|
|
this.childrenExpanded = true;
|
|
|
|
} else if (this.childrenLoaded) {
|
|
|
|
this.item.has_children = false;
|
|
|
|
}
|
2023-04-21 21:25:52 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
toggleChildren: function() {
|
|
|
|
this.childrenExpanded = !this.childrenExpanded;
|
|
|
|
if (this.childrenExpanded) this.loadChildren();
|
|
|
|
},
|
|
|
|
loadChildren: function() {
|
2023-04-25 18:30:45 +08:00
|
|
|
$.get(this.item.children_url, {archived: this.archived}, (data) => {
|
2023-04-21 21:25:52 +08:00
|
|
|
this.children = data.items;
|
2023-05-04 20:02:04 +08:00
|
|
|
this.childrenLoaded = true;
|
2023-04-21 21:25:52 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
treeExpand: function() {
|
|
|
|
this.childrenExpanded = true;
|
|
|
|
this.$emit('item:expand');
|
|
|
|
},
|
|
|
|
selectItem: function() {
|
|
|
|
if (this.activeItem && !this.childrenExpanded) {
|
|
|
|
this.$emit('item:expand');
|
|
|
|
if (this.hasChildren) {
|
|
|
|
this.childrenExpanded = true;
|
|
|
|
this.loadChildren();
|
|
|
|
}
|
|
|
|
}
|
2023-04-19 20:16:22 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
</script>
|