panels-origin/web-panel/components/AppModuleTree.vue
2026-08-21 16:55:01 -05:00

105 lines
3 KiB
Vue

<template>
<div class="desk-side module-tree-panel">
<div class="desk-side-title module-tree-title">
<span>{{ treeTitle }}</span>
<i class="pi pi-list module-tree-title-icon" aria-hidden="true" />
</div>
<Tree
:value="tree"
filter
:filter-placeholder="filterPlaceholder"
selection-mode="single"
:selection-keys="keys"
:expanded-keys="expanded"
class="desk-tree"
@update:selection-keys="onKeys"
@update:expanded-keys="onExpand"
@node-select="onSelect"
>
<template #default="{ node }">
<span class="tree-row">
<span>{{ node.label }}</span>
<Badge v-if="node.data?.count != null" :value="node.data.count" />
</span>
</template>
</Tree>
<div class="desk-tree-footer">
<Button
icon="pi pi-star"
text
rounded
aria-label="Todos"
:disabled="!hasAll"
@click="selectTree('all')"
/>
<Button
icon="pi pi-clock"
text
rounded
aria-label="Historial"
:disabled="!hasHistory"
@click="selectTree('bajas')"
/>
<Button
icon="pi pi-cog"
text
rounded
aria-label="Configuracion"
@click="navigateTo('/configuracion')"
/>
</div>
</div>
</template>
<script setup lang="ts">
import type { TreeNode } from "primevue/treenode";
import type { TreeSelectionKeys } from "primevue/tree";
const { tree, treeKey, treeTitle, selectTree } = useDesktop();
const keys = computed<TreeSelectionKeys>(() =>
treeKey.value ? { [treeKey.value]: true } : {},
);
const expanded = ref<Record<string, boolean>>({ projects: true, statuses: true });
const filterPlaceholder = computed(() => `Buscar en ${treeTitle.value.toLocaleLowerCase("es-MX")}...`);
function findNode(nodes: TreeNode[] | undefined, key: string): TreeNode | undefined {
for (const node of nodes || []) {
if (node.key === key) return node;
const hit = findNode(node.children, key);
if (hit) return hit;
}
}
const hasAll = computed(() => Boolean(findNode(tree.value, "all")));
const hasHistory = computed(() => Boolean(findNode(tree.value, "bajas")));
watch(tree, (nodes) => {
const next = { ...expanded.value, projects: true, statuses: true, companies: true };
function walk(list: TreeNode[] | undefined, depth: number) {
for (const node of list || []) {
if (node.key && depth < 4) next[String(node.key)] = true;
if (node.children?.length) walk(node.children, depth + 1);
}
}
walk(nodes, 0);
expanded.value = next;
}, { deep: true });
function onKeys(value: TreeSelectionKeys) {
const next = Object.entries(value || {}).find(([, on]) => on)?.[0];
if (!next) return;
const node = findNode(tree.value, next);
if (node?.selectable === false) return;
selectTree(next);
}
function onExpand(value: Record<string, boolean>) {
expanded.value = value;
}
function onSelect(node: TreeNode) {
if (node.selectable === false) return;
if (node.key) selectTree(node.key);
}
</script>