scinote-web/app/javascript/vue/navigation/navigator_item.vue

160 lines
4.6 KiB
Vue
Raw Normal View History

<template>
<div>
2023-09-18 21:32:53 +08:00
<div class="text-sn-blue w-full flex justify-center flex-col menu-item rounded"
: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),
'disabled-link': item.disabled
}">
<template v-if="item.archived">(A)</template>
{{ item.name }}
</a>
2023-04-21 21:25:52 +08:00
</div>
</div>
2023-04-21 21:25:52 +08:00
<div class="basis-full" :class="{'hidden': !childrenExpanded}">
<NavigatorItem v-for="item in sortedMenuItems"
@item:expand="treeExpand"
:key="item.id"
:currentItemId="currentItemId"
:paddingLeft="24 + paddingLeft"
:reloadCurrentLevel="reloadCurrentLevel"
:reloadChildrenLevel="reloadChildrenLevel"
:item="item"
:archived="archived" />
</div>
</div>
</template>
<script>
export default {
name: 'NavigatorItem',
props: {
firstLevel: {
type: Boolean,
default: false
},
2023-04-21 21:25:52 +08:00
item: Object,
currentItemId: String,
2023-04-26 16:24:50 +08:00
archived: Boolean,
paddingLeft: Number,
2023-04-26 16:24:50 +08:00
reloadCurrentLevel: Boolean,
reloadChildrenLevel: Boolean
},
data() {
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: []
};
},
computed: {
hasChildren() {
if (this.item.disabled) return false;
if (this.item.has_children) return true;
if (this.children && this.children.length > 0) return true;
return false;
},
sortedMenuItems() {
if (!this.children) return [];
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() {
2023-04-21 21:25:52 +08:00
return this.item.id == this.currentItemId;
},
itemIcon() {
switch (this.item.type) {
2023-04-21 21:25:52 +08:00
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;
}
},
itemToolTip() {
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() {
2023-04-21 21:25:52 +08:00
if (this.item.children) this.children = this.item.children;
},
mounted() {
2023-04-21 21:25:52 +08:00
this.selectItem();
},
watch: {
currentItemId() {
2023-04-21 21:25:52 +08:00
this.selectItem();
2023-04-26 16:24:50 +08:00
},
reloadChildrenLevel() {
2023-04-26 16:24:50 +08:00
if (this.reloadChildrenLevel && this.item.id == this.currentItemId) {
this.loadChildren();
}
},
reloadCurrentLevel() {
2023-04-26 16:24:50 +08:00
if (this.reloadCurrentLevel && this.children.find((item) => item.id == this.currentItemId)) {
this.loadChildren();
}
2023-05-04 20:02:04 +08:00
},
children() {
2023-07-19 15:55:27 +08:00
if (this.children && this.children.length > 0) {
2023-05-04 20:02:04 +08:00
this.childrenExpanded = true;
} else if (this.childrenLoaded) {
this.item.has_children = false;
}
},
archived() {
if (this.childrenExpanded) {
this.loadChildren();
}
2023-04-21 21:25:52 +08:00
}
},
methods: {
toggleChildren() {
2023-04-21 21:25:52 +08:00
this.childrenExpanded = !this.childrenExpanded;
if (this.childrenExpanded) this.loadChildren();
},
loadChildren() {
$.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() {
2023-04-21 21:25:52 +08:00
this.childrenExpanded = true;
this.$emit('item:expand');
},
selectItem() {
2023-04-21 21:25:52 +08:00
if (this.activeItem && !this.childrenExpanded) {
this.$emit('item:expand');
if (this.hasChildren) {
this.childrenExpanded = true;
this.loadChildren();
}
}
}
}
};
</script>