Newer
Older
smart-home-server / webclient-vue / src / stores / scripts.js
@Eugene Sukhodolskiy Eugene Sukhodolskiy 1 day ago 4 KB Add script detail pages with scope grouping
import { defineStore } from "pinia";
import { scriptsApi } from "../api/modules/scripts";

export const useScriptsStore = defineStore("scripts", {
  state: () => ({
    actions: [],
    regular: [],
    scopes: [],
    isLoadingActions: false,
    isLoadingRegular: false,
    isLoadingScopes: false,
    errorActions: null,
    errorRegular: null,
    errorScopes: null,
    runningAliases: new Set(),
    lastRunResult: null,
    _actionsAbortController: null,
    _regularAbortController: null,
    _scopesAbortController: null,
  }),

  getters: {
    totalActions: (state) => state.actions.length,
    totalRegular: (state) => state.regular.length,
    totalScopes: (state) => state.scopes.length,
    isRunning: (state) => (alias) => state.runningAliases.has(alias),
    actionByAlias: (state) => (alias) => state.actions.find((s) => s.alias === alias) || null,
    regularByAlias: (state) => (alias) => state.regular.find((s) => s.alias === alias) || null,
    scopeByName: (state) => (name) => state.scopes.find((s) => s.name === name) || null,
    actionsByScope: (state) => (scopeName) => state.actions.filter((s) => s.scope === scopeName),
    regularByScope: (state) => (scopeName) => state.regular.filter((s) => s.scope === scopeName),
  },

  actions: {
    async loadActions() {
      this._actionsAbortController?.abort();
      const controller = new AbortController();
      this._actionsAbortController = controller;

      this.isLoadingActions = true;
      this.errorActions = null;

      const result = await scriptsApi.actionsList({ signal: controller.signal });
      this._actionsAbortController = null;
      this.isLoadingActions = false;

      if (!result.ok) {
        if (result.error?.type === "timeout") {
          return result;
        }
        this.errorActions = result.error;
        return result;
      }

      this.actions = result.data?.data?.scripts || [];
      return result;
    },

    async loadRegular() {
      this._regularAbortController?.abort();
      const controller = new AbortController();
      this._regularAbortController = controller;

      this.isLoadingRegular = true;
      this.errorRegular = null;

      const result = await scriptsApi.regularList({ signal: controller.signal });
      this._regularAbortController = null;
      this.isLoadingRegular = false;

      if (!result.ok) {
        if (result.error?.type === "timeout") {
          return result;
        }
        this.errorRegular = result.error;
        return result;
      }

      this.regular = result.data?.data?.scripts || [];
      return result;
    },

    async loadScopes() {
      this._scopesAbortController?.abort();
      const controller = new AbortController();
      this._scopesAbortController = controller;

      this.isLoadingScopes = true;
      this.errorScopes = null;

      const result = await scriptsApi.scopesList({ signal: controller.signal });
      this._scopesAbortController = null;
      this.isLoadingScopes = false;

      if (!result.ok) {
        if (result.error?.type === "timeout") {
          return result;
        }
        this.errorScopes = result.error;
        return result;
      }

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

    async runScript(alias, params = {}) {
      this.runningAliases.add(alias);
      this.lastRunResult = null;

      const result = await scriptsApi.runAction(alias, params);

      this.runningAliases.delete(alias);

      if (!result.ok) {
        this.lastRunResult = { alias, ok: false, error: result.error };
        return result;
      }

      this.lastRunResult = {
        alias,
        ok: true,
        data: result.data?.data?.return?.result,
        execTime: result.data?.data?.return?.exec_time,
      };
      return result;
    },

    async setActionState(alias, enabled) {
      const result = await scriptsApi.setActionState(alias, enabled);

      if (result.ok) {
        const idx = this.actions.findIndex((s) => s.alias === alias);
        if (idx !== -1) {
          this.actions[idx] = { ...this.actions[idx], state: enabled ? "enabled" : "disabled" };
        }
      }

      return result;
    },

    async setRegularState(alias, enabled) {
      const result = await scriptsApi.setRegularState(alias, enabled);

      if (result.ok) {
        const idx = this.regular.findIndex((s) => s.alias === alias);
        if (idx !== -1) {
          this.regular[idx] = { ...this.regular[idx], state: enabled ? "enabled" : "disabled" };
        }
      }

      return result;
    },

    async setScopeState(name, enabled) {
      const result = await scriptsApi.setScopeState(name, enabled);

      if (result.ok) {
        const idx = this.scopes.findIndex((s) => s.name === name);
        if (idx !== -1) {
          this.scopes[idx] = { ...this.scopes[idx], state: enabled ? "enabled" : "disabled" };
        }
      }

      return result;
    },
  },
});