Newer
Older
smart-home-server / webclient-vue / src / features / areas / components / AreaTreeNode.vue
@Eugene Sukhodolskiy Eugene Sukhodolskiy 23 hours ago 2 KB Add script detail pages with scope grouping
<template>
  <li v-if="!isCycle" class="area-tree-node" :class="{ 'is-open': isOpen, 'is-leaf': isLeaf }">
    <article class="area-tree-card" @click="goToDetail">
      <button
        class="tree-toggle"
        type="button"
        :disabled="isLeaf"
        :aria-expanded="isOpen"
        @click.stop="isOpen = !isOpen"
      >
        {{ isLeaf ? "·" : isOpen ? "−" : "+" }}
      </button>

      <div class="area-tree-info">
        <h2>{{ area.display_name }}</h2>
        <p>
          <GnBadge variant="secondary">{{ area.type }}</GnBadge>
          <code>{{ area.alias }}</code>
        </p>
      </div>

      <div class="area-tree-actions">
        <GnButton
          :variant="isFavorite ? 'warning' : 'secondary'"
          :icon="isFavorite ? 'ph-star' : 'ph-star'"
          @click.stop="favoritesStore.toggle(area.id)"
        >
          {{ isFavorite ? "Unstar" : "Star" }}
        </GnButton>
      </div>
    </article>

    <ul v-if="area.children?.length && isOpen" class="area-tree-children">
      <AreaTreeNode
        v-for="child in area.children"
        :key="child.id"
        :area="child"
        :ancestors="nextAncestors"
      />
    </ul>
  </li>
  <li v-else class="area-tree-node">
    <article class="area-tree-card area-tree-cycle">
      Cycle skipped for area ID {{ area.id }}
    </article>
  </li>
</template>

<script setup>
import { computed, ref } from "vue";
import { useRouter } from "vue-router";
import { useFavoritesStore } from "../../../stores/favorites";
import { GnBadge, GnButton } from "gnexus-ui-kit/vue";

const props = defineProps({
  area: {
    type: Object,
    required: true,
  },
  ancestors: {
    type: Array,
    default: () => [],
  },
});

const router = useRouter();
const favoritesStore = useFavoritesStore();
const isOpen = ref(false);
const isLeaf = computed(() => !props.area.children?.length);
const isFavorite = computed(() => favoritesStore.has(props.area.id));
const isCycle = computed(() => props.ancestors.includes(String(props.area.id)));
const nextAncestors = computed(() => [...props.ancestors, String(props.area.id)]);

function goToDetail() {
  router.push({ name: "area-detail", params: { id: String(props.area.id) } });
}
</script>