Files
mixtape/zero.Backoffice.UI/app/components/ui-tree-item.vue
T

379 lines
7.9 KiB
Vue
Raw Normal View History

2020-06-04 15:50:21 +02:00
<template>
<div class="ui-tree-item" :class="getClasses(value)" v-on:contextmenu="onRightClicked(value, $event)">
2021-04-16 14:09:39 +02:00
<button :disabled="value.disabled" v-if="value.hasChildren" @click="toggle(value)" type="button" class="ui-tree-item-toggle" :style="{ 'width': ((depth * 15) + 32) + 'px' }">
<ui-icon class="ui-tree-item-arrow" :symbol="'fth-chevron-' + (value.isOpen ? 'up' : 'down')" :size="14" />
2020-06-04 15:50:21 +02:00
</button>
2021-04-16 14:09:39 +02:00
<span v-if="!value.hasChildren" class="ui-tree-item-toggle" :style="{ 'width': ((depth * 15) + 32) + 'px' }"></span>
2020-06-05 15:34:13 +02:00
<component :disabled="value.disabled" :is="tag" type="button" :to="value.url" class="ui-tree-item-link" @click="onClick(value, $event)">
2021-04-16 14:09:39 +02:00
<ui-icon class="ui-tree-item-icon" v-if="value.icon" :class="{'is-dashed': value.isDashed }" :symbol="value.icon" :size="18" />
<ui-icon v-if="value.modifier" :title="value.modifier.name" class="ui-tree-item-modifier" :symbol="modifier" :class="modifierClass" :size="10" :stroke="2.5" />
2021-03-22 16:00:00 +01:00
<span class="ui-tree-item-text">
<ui-localize :value="value.name" />
<span class="ui-tree-item-description" v-if="value.description">
<br />
<ui-localize :value="value.description" />
</span>
</span>
2021-02-08 15:54:34 +01:00
2020-06-04 15:50:21 +02:00
</component>
2020-06-05 15:34:13 +02:00
<ui-dot-button :disabled="value.disabled" class="ui-tree-item-actions" v-if="value.hasActions" @click="onActionsClicked(value, $event)" />
2021-04-16 14:09:39 +02:00
<span class="ui-tree-item-count" v-if="value.countOutput != null">{{value.countOutput}}</span>
2020-06-04 15:50:21 +02:00
</div>
</template>
2021-12-10 14:59:35 +01:00
<script lang="ts">
import { defineComponent } from 'vue';
2020-06-04 15:50:21 +02:00
2021-12-10 14:59:35 +01:00
export default defineComponent({
2020-06-04 15:50:21 +02:00
name: 'uiTreeItem',
props: {
value: {
type: Object,
required: true
},
activeId: {
type: String,
default: null
2021-02-10 14:53:56 +01:00
},
selected: {
type: Boolean,
default: false
2021-04-16 14:09:39 +02:00
},
depth: {
type: Number,
default: 0
},
2020-06-04 15:50:21 +02:00
},
2021-09-07 15:10:40 +02:00
data: () => ({
_isActive: false
}),
2020-06-04 15:50:21 +02:00
computed: {
isLink()
{
return this.value && this.value.url;
},
tag()
{
return this.isLink ? 'router-link' : 'button';
2021-03-01 22:58:35 +01:00
},
modifier()
{
return this.value && this.value.modifier ? this.value.modifier.icon.split(' ')[0] : null;
},
modifierClass()
{
return this.value && this.value.modifier ? this.value.modifier.icon.split(' ')[1] : null;
2021-09-07 15:10:40 +02:00
},
isActive()
{
2022-01-04 12:58:42 +01:00
return this.value && this.isLink && (
(!!this.value.id && this.value.id === this.activeId)
|| this.value.id == this.$route.params.id
|| (this.value.url && !this.value.url.params && this.value.url.name === this.$route.name && !this.$route.params.id)
);
2021-09-07 15:10:40 +02:00
}
},
watch: {
isActive(val)
{
if (val)
{
this.$emit('setactive', {
$el: this.$el,
model: this.value
});
}
}
},
mounted()
{
if (this.isActive)
{
this.$emit('setactive', {
$el: this.$el,
model: this.value
});
2020-06-04 15:50:21 +02:00
}
},
methods: {
onClick(item, ev)
{
if (this.isLink)
{
return;
}
else
{
this.$emit('click', item, ev);
}
},
// get all classes for a tree item
getClasses(item)
{
2021-12-10 14:59:35 +01:00
return {
2021-04-16 14:09:39 +02:00
'has-icon': !!item.icon,
2020-06-04 15:50:21 +02:00
'has-children': item.hasChildren,
'is-inactive': item.isInactive,
2020-06-05 15:34:13 +02:00
'is-open': item.isOpen,
2021-02-10 14:53:56 +01:00
'is-selected': this.selected || item.isSelected,
2020-08-13 14:58:01 +02:00
'is-disabled': item.disabled,
2021-09-07 15:10:40 +02:00
'is-active': this.isActive
2020-06-04 15:50:21 +02:00
};
},
// toggles children of an item
toggle(item)
{
this.$emit('open', item);
},
// right clicked on an item
onRightClicked(item, ev)
{
2020-06-05 15:34:13 +02:00
if (!item.disabled)
{
this.$emit('rightclick', item, ev);
}
2020-06-04 15:50:21 +02:00
},
// actions button clicked on item
onActionsClicked(item, ev)
{
2020-06-05 15:34:13 +02:00
if (!item.disabled)
{
this.$emit('actions', item, ev);
}
2020-06-04 15:50:21 +02:00
}
}
2021-12-10 14:59:35 +01:00
})
2020-06-04 15:50:21 +02:00
</script>
<style lang="scss">
.ui-tree-item
{
display: grid;
2022-01-04 12:58:42 +01:00
grid-template-columns: auto 1fr auto auto;
2020-06-04 15:50:21 +02:00
align-items: center;
font-size: var(--font-size);
2021-04-16 14:09:39 +02:00
padding: 0 var(--padding) 0 0;
2022-01-04 12:58:42 +01:00
//height: 54px;
height: 58px;
border-top: 1px dashed var(--color-line-dashed);
color: var(--color-text);
2020-06-04 15:50:21 +02:00
position: relative;
transition: color 0.2s ease;
2020-08-13 14:58:01 +02:00
position: relative;
2020-06-04 15:50:21 +02:00
2022-01-04 12:58:42 +01:00
.theme-dark &
{
border-top: 1px dashed var(--color-line);
}
2020-06-04 15:50:21 +02:00
&:hover > .ui-tree-item-actions
{
opacity: 1;
2021-04-16 14:09:39 +02:00
}
2020-06-05 15:34:13 +02:00
&.is-disabled
{
cursor: not-allowed;
2020-09-22 13:27:54 +02:00
opacity: .5;
2020-06-05 15:34:13 +02:00
}
2020-08-13 14:58:01 +02:00
2021-04-16 14:09:39 +02:00
&.is-active:before, &.is-selected:before, &:hover:before
2020-08-13 14:58:01 +02:00
{
content: ' ';
position: absolute;
top: 0;
bottom: 0;
2021-08-25 15:54:09 +02:00
left: 0;
right: 0;
background: var(--color-tree-selected);
2020-08-13 14:58:01 +02:00
}
2021-01-06 12:03:21 +01:00
2021-02-10 14:53:56 +01:00
&.is-selected:after
2021-01-06 12:03:21 +01:00
{
2021-02-10 14:53:56 +01:00
font-family: "Feather";
content: "\e83e";
font-size: 16px;
2022-01-04 12:58:42 +01:00
color: var(--color-primary);
2021-02-10 14:53:56 +01:00
z-index: 2;
}
&.is-selected .ui-tree-item-text
{
font-weight: bold;
}
2020-06-04 15:50:21 +02:00
}
2022-01-04 12:58:42 +01:00
.ui-tree-header + .ui-tree-item
{
margin-top: -8px;
}
2020-06-04 15:50:21 +02:00
.ui-tree-item-link
{
display: grid;
2021-08-22 22:35:21 +02:00
grid-template-columns: 28px 1fr auto;
gap: 6px;
2020-06-04 15:50:21 +02:00
height: 100%;
align-items: center;
2020-06-09 20:02:47 +02:00
position: relative;
color: var(--color-text);
2020-06-09 20:02:47 +02:00
&:hover
{
color: var(--color-text);
2020-06-09 20:02:47 +02:00
}
2020-06-04 15:50:21 +02:00
&.is-active
{
color: var(--color-text);
2020-06-04 15:50:21 +02:00
font-weight: bold;
2020-08-16 15:51:12 +02:00
//color: var(--color-primary);
2020-06-04 15:50:21 +02:00
}
}
2020-09-30 16:56:23 +02:00
.ui-tree-item-text
{
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
2021-02-08 15:54:34 +01:00
.ui-tree-item-description
{
color: var(--color-text-dim);
font-size: var(--font-size-xs);
}
2020-06-04 15:50:21 +02:00
.ui-tree-item-toggle
{
color: var(--color-text-dim);
2020-06-04 15:50:21 +02:00
height: 100%;
text-align: right;
2021-08-22 22:35:21 +02:00
padding-right: 4px;
2020-06-04 15:50:21 +02:00
transition: color 0.2s ease;
2021-04-16 14:09:39 +02:00
z-index: 1;
2020-06-04 15:50:21 +02:00
&:hover
{
color: var(--color-text);
2020-06-04 15:50:21 +02:00
}
}
.ui-tree-item-icon
{
position: relative;
top: -2px;
2021-01-06 12:03:21 +01:00
color: var(--color-text-dim);
2020-06-04 15:50:21 +02:00
transition: color 0.2s ease;
}
2021-03-23 14:55:27 +01:00
.ui-tree-item-icon.is-dashed
{
stroke-dasharray: 3.5px;
}
2021-01-06 12:03:21 +01:00
.ui-tree-item:hover .ui-tree-item-icon
{
color: var(--color-text);
}
.ui-tree-item.is-active .ui-tree-item-icon
{
2021-03-20 09:54:16 +01:00
color: var(--color-text);
2021-01-06 12:03:21 +01:00
}
2020-06-04 15:50:21 +02:00
.ui-tree-item-loading
{
display: block;
overflow: hidden;
position: absolute;
left: 0;
right: 0;
height: 2px;
i
{
background-color: var(--color-bg-shade-4);
2020-06-04 15:50:21 +02:00
transform: translateX(-100%) scaleX(1);
animation: treeitemloading 1s linear infinite;
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
}
@keyframes treeitemloading
{
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
.ui-tree-item-modifier
{
position: absolute;
left: 10px;
2021-04-16 14:09:39 +02:00
bottom: 17px;
2021-03-16 13:57:52 +01:00
color: var(--color-text-dim);
background: var(--color-tree);
2020-06-04 15:50:21 +02:00
border-radius: 50%;
2021-04-16 14:09:39 +02:00
padding: 2px;
width: 14px;
height: 14px;
transition: color 0.2s ease;
2021-03-16 13:57:52 +01:00
.ui-tree-item.is-active &, .ui-tree-item:hover &
{
color: var(--color-text);
}
2020-09-05 17:35:47 +02:00
.ui-tree-item.is-active &
2020-09-05 17:35:47 +02:00
{
2021-03-16 13:57:52 +01:00
background: var(--color-tree-selected);
2020-09-05 17:35:47 +02:00
}
2020-06-04 15:50:21 +02:00
}
.ui-tree-item-actions
{
opacity: 0;
color: var(--color-text-dim);
2020-09-10 18:32:38 +02:00
&:focus
{
opacity: 1;
}
2020-06-04 15:50:21 +02:00
}
2021-04-16 14:09:39 +02:00
.ui-tree-item-count
{
display: inline-block;
font-size: 11px;
font-weight: 400;
text-transform: uppercase;
background: var(--color-box-nested);
color: var(--color-text);
height: 22px;
line-height: 22px;
padding: 0 10px;
border-radius: 16px;
font-style: normal;
grid-column: 3;
margin-right: -4px;
margin-left: 8px;
}
2020-06-04 15:50:21 +02:00
</style>