Files
mixtape/zero.Backoffice.UI/app/modules/pages/partials/page-tree.vue
T
2022-01-12 23:52:37 +01:00

209 lines
5.0 KiB
Vue

<template>
<div ref="scrollable" class="app-tree page-tree" xv-resizable="resizable">
<ui-tree ref="tree" :get="getItems" :config="treeConfig" @select="onSelect" :active="id" :header="'Pages'">
<template v-slot:actions="props">
<template v-if="!props.item || props.id !== 'recyclebin'">
<ui-dropdown-button label="@ui.create" icon="fth-plus" @click="create(props.item)" />
<ui-dropdown-button v-if="props.item" label="@ui.move.title" icon="fth-corner-down-right" @click="move(props.item)" />
<ui-dropdown-button v-if="props.item" label="@ui.copy.title" icon="fth-copy" @click="copy(props.item)" />
<ui-dropdown-button label="@ui.sort.title" icon="fth-arrow-down" @click="sort(props.item)" />
<ui-dropdown-separator v-if="props.item" />
<ui-dropdown-button v-if="props.item" label="@ui.delete" icon="fth-trash" @click="remove(props.item)" />
</template>
</template>
</ui-tree>
<div class="app-tree-resizable ui-resizable"></div>
</div>
</template>
<script lang="ts">
import api from '../api';
import { defineComponent } from 'vue';
import { useUiStore } from '../../../ui/store';
import * as notifications from '../../../services/notification';
import actions from '../actions';
export default defineComponent({
props: {
id: {
type: String,
default: null
}
},
data: () => ({
flavors: [],
cache: {},
resizable: {
axis: 'x',
min: 260,
max: 520,
save: 'page-tree',
handle: '.ui-resizable'
},
actions: [],
treeConfig: {
}
}),
created()
{
const ui = useUiStore();
this.flavors = ui.flavors.pages.flavors;
},
mounted()
{
this.zero.events.off('page.update');
this.zero.events.on('page.update', page =>
{
this.cache = [];
this.$refs.tree.refresh();
});
},
methods: {
async getItems(parent)
{
const key = !parent ? '__root' : parent;
if (this.cache[key])
{
return this.cache[key];
}
const response = await api.tree.getChildren(parent || 'root', this.id);
const items = response.data.map(x => this.buildItem(x));
this.cache[key] = items;
return items;
},
buildItem(item)
{
if (item.id === 'recyclebin')
{
item.hasActions = false;
item.disabled = true;
//item.url = {
// name: 'recyclebin'
//};
}
else
{
item.url = {
name: 'pages-edit',
params: { id: item.id }
};
}
return item;
},
onSelect(item)
{
if (item.id == 'recyclebin')
{
notifications.error('Not implemented', 'Recycle bin has not been implemented yet');
}
},
async create(item)
{
await actions.create(this.$router, item);
},
async move(item)
{
await actions.move(item);
},
async copy(item)
{
await actions.copy(item);
},
async sort(item)
{
await actions.sort(item);
},
async remove(item)
{
await actions.remove(item);
}
//watch: {
// '$route'()
// {
// var $ela = document.querySelector('.app-tree .ui-tree-item.is-active');
// var centerOffset = this.$el.offsetHeight * 0.5 - $ela.offsetHeight * 0.5;
// this.$nextTick(() =>
// {
// this.$el.scrollTo({ top: $ela.offsetTop, behavior: 'smooth' });
// });
// console.info({
// elOffsetHeight: this.$el.offsetHeight,
// aOffsetHeight: $ela.offsetHeight,
// aOffsetTop: $ela.offsetTop,
// centerOffset,
// scrollTop: $ela.offsetTop - centerOffset
// });
// }
//},
//onActiveSet(val)
//{
// this.$nextTick(() =>
// {
// let container = this.$refs.scrollable;
// let child = val.$el;
// let centerOffset = container.offsetHeight * 0.5 - child.offsetHeight * 0.5;
// let threshold = container.offsetHeight * 0.1;
// let activeRange = {
// from: container.scrollTop + threshold,
// to: container.scrollTop + container.offsetHeight - threshold
// };
// let rect = child.getBoundingClientRect();
// let scrollTop = rect.top + container.offsetTop;
// let scrollTo = child.offsetTop;
// //console.info(child.offsetTop + ' [ ' + activeRange.from + ' - ' + activeRange.to + ' ]', rect);
// //if (activeRange.from <= scrollTo && activeRange.to >= scrollTo)
// //{
// // console.info('in range');
// // return;
// //}
// //console.info('scroll to: ' + scrollTo);
// container.scrollTo({ top: scrollTo, behavior: 'smooth' });
// });
//},
}
});
</script>
<style lang="scss">
</style>