fix(04): service tree view
This commit is contained in:
parent
55a6e03bcf
commit
76a08ac368
3 changed files with 159 additions and 14 deletions
|
|
@ -1,5 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { Icon } from '@iconify/vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
type Node = {
|
||||
[key: string]: any;
|
||||
|
|
@ -13,6 +14,8 @@ type Props = {
|
|||
keyTitle?: string;
|
||||
keySubtitle?: string;
|
||||
expandable?: boolean;
|
||||
hideCheckBox?: boolean;
|
||||
iconSize?: string;
|
||||
decoration?: {
|
||||
level?: number;
|
||||
bg?: string;
|
||||
|
|
@ -27,6 +30,11 @@ const nodes = defineModel<Node[]>('nodes', { required: true });
|
|||
const emits = defineEmits<{ (e: 'checked'): void }>();
|
||||
|
||||
const dec = props.decoration?.find((v) => v.level === (props.level || 0));
|
||||
const maxLevel = computed(() =>
|
||||
props.decoration?.reduce((max, v) => {
|
||||
return v.level && v.level > max ? v.level : max;
|
||||
}, 0),
|
||||
);
|
||||
|
||||
function recursiveDeselect(node: Node) {
|
||||
if (node.children) {
|
||||
|
|
@ -48,8 +56,22 @@ function toggleExpand(node: Node) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tree-container">
|
||||
<div v-for="(node, i) in nodes" class="tree-item" :key="i">
|
||||
<div
|
||||
class="tree-container"
|
||||
:class="{
|
||||
'q-pl-lg': level && level > 0,
|
||||
'last-children': level && level === maxLevel,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="(node, i) in nodes"
|
||||
class="tree-item"
|
||||
:class="{
|
||||
'q-pt-sm': level !== 0 && level !== maxLevel && i !== 0,
|
||||
'q-pt-xs': level === maxLevel && i === 0,
|
||||
}"
|
||||
:key="i"
|
||||
>
|
||||
<slot
|
||||
v-if="$slots['item']"
|
||||
name="item"
|
||||
|
|
@ -61,7 +83,23 @@ function toggleExpand(node: Node) {
|
|||
class="item__content row items-center no-wrap"
|
||||
@click="toggleExpand(node)"
|
||||
>
|
||||
<label class="flex items-center item__checkbox" @click.stop>
|
||||
<div
|
||||
v-if="level !== maxLevel"
|
||||
class="q-mr-md"
|
||||
style="color: var(--stone-4)"
|
||||
>
|
||||
<q-icon
|
||||
name="mdi-chevron-down-circle"
|
||||
size="sm"
|
||||
:style="`transform: rotate(${node.opened ? '180deg' : '0'})`"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label
|
||||
v-if="!hideCheckBox"
|
||||
class="flex items-center item__checkbox"
|
||||
@click.stop
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="node.selected"
|
||||
|
|
@ -71,9 +109,17 @@ function toggleExpand(node: Node) {
|
|||
|
||||
<div
|
||||
class="item__icon flex items-center justify-center"
|
||||
:style="`background: ${dec?.bg}; color: ${dec?.fg}`"
|
||||
:style="`background: ${dec?.bg}; color: ${dec?.fg}; height: ${iconSize}; width: ${iconSize}`"
|
||||
>
|
||||
<Icon v-if="dec && dec.icon" :icon="dec.icon" />
|
||||
<div
|
||||
:style="`height: calc(${iconSize} - 40%); width: calc(${iconSize} - 40%)`"
|
||||
>
|
||||
<Icon
|
||||
v-if="dec && dec.icon"
|
||||
:icon="dec.icon"
|
||||
class="full-width full-height"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
|
@ -86,14 +132,13 @@ function toggleExpand(node: Node) {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<q-separator v-if="!level"></q-separator>
|
||||
<q-separator v-if="!level" spaced="md"></q-separator>
|
||||
|
||||
<transition name="slide">
|
||||
<div
|
||||
class="q-pl-lg q-pt-sm"
|
||||
v-if="node.opened && node.children && node.children.length > 0"
|
||||
>
|
||||
<div v-if="node.opened && node.children && node.children.length > 0">
|
||||
<TreeView
|
||||
:iconSize
|
||||
:hideCheckBox
|
||||
class="item__children"
|
||||
v-if="node.children"
|
||||
v-model:nodes="node.children"
|
||||
|
|
@ -153,6 +198,10 @@ function toggleExpand(node: Node) {
|
|||
}
|
||||
}
|
||||
|
||||
.last-children {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.slide-enter-active {
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue