Newer
Older
smart-home-server / webclient-vue / src / stores / areas.js
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 25 Apr 1 KB Add Vue areas tree page
import { defineStore } from "pinia";
import { areasApi } from "../api/modules/areas";

function buildAreaTree(areas) {
  const map = {};
  const roots = [];

  for (const area of areas) {
    map[area.id] = { ...area, children: [] };
  }

  for (const area of areas) {
    const node = map[area.id];
    const isSelfReference = area.parent_id && area.parent_id == area.id;
    const parentExists = area.parent_id && map[area.parent_id];

    if (!isSelfReference && parentExists) {
      map[area.parent_id].children.push(node);
    } else {
      roots.push(node);
    }
  }

  if (roots.length === 0 && areas.length > 0) {
    return Object.values(map);
  }

  return roots;
}

export const useAreasStore = defineStore("areas", {
  state: () => ({
    areas: [],
    isLoading: false,
    error: null,
  }),

  getters: {
    areasById(state) {
      return Object.fromEntries(state.areas.map((area) => [String(area.id), area]));
    },

    areaTree(state) {
      return buildAreaTree(state.areas);
    },
  },

  actions: {
    async loadAreas() {
      this.isLoading = true;
      this.error = null;

      const result = await areasApi.list();
      this.isLoading = false;

      if (!result.ok) {
        this.error = result.error;
        return result;
      }

      this.areas = result.data?.data?.areas || [];
      return result;
    },
  },
});