All files / features/areas/components AreaTreeNode.vue

90.32% Statements 28/31
100% Branches 39/39
83.33% Functions 15/18
88.88% Lines 24/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99  26x 2x           1x         2x     23x         2x       1x     18x         1x     18x       1x     18x       1x   19x           1x                       2x                     19x                     19x   19x 19x 23x 24x 24x 19x    
<template>
  <li v-if="!isCycle" class="area-tree-node" :class="{ 'is-open': isOpen, 'is-leaf': isLeaf }">
    <article class="area-tree-card">
      <button
        class="tree-toggle"
        type="button"
        :disabled="isLeaf"
        :aria-expanded="isOpen"
        @click="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="secondary"
          icon="ph-pencil"
          @click="emit('rename', area)"
        >
          Rename
        </GnButton>
        <GnButton
          variant="secondary"
          icon="ph-arrow-up"
          :disabled="area.parent_id == null || area.parent_id === 0"
          @click="emit('unassign', area)"
        >
          Unassign
        </GnButton>
        <GnButton
          variant="danger"
          icon="ph-trash"
          @click="emit('remove', area)"
        >
          Remove
        </GnButton>
        <GnButton
          :variant="isFavorite ? 'warning' : 'secondary'"
          :icon="isFavorite ? 'ph-star' : 'ph-star'"
          @click="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"
        @rename="(a) => emit('rename', a)"
        @remove="(a) => emit('remove', a)"
        @unassign="(a) => emit('unassign', a)"
      />
    </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 { 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 emit = defineEmits(["rename", "remove", "unassign"]);
 
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)]);
</script>