Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Widgets.store.ts « Widget « src « vue « CoreHome « plugins - github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d0ce5467edb1e703c4166f691d3be63d06756896 (plain)
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
/*!
 * Matomo - free/libre analytics platform
 *
 * @link https://matomo.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */

import {
  reactive,
  readonly,
  computed,
} from 'vue';
import Subcategory from '../ReportingMenu/Subcategory';
import MatomoUrl from '../MatomoUrl/MatomoUrl';

export interface WidgetLeaf {
  uniqueId: string;
  module: string;
  action: string;
  viewDataTable: string;
  parameters: Record<string, unknown>;
  subcategory: Subcategory;
  isContainer?: boolean;
  isReport?: boolean;
  middlewareParameters?: QueryParameters;
  documentation?: string;
  layout?: string;
  isWide?: boolean;
}

export interface ContainerWidget extends WidgetLeaf {
  isFirstInPage?: boolean;
  widgets: (WidgetLeaf | ContainerWidget)[];
}

export type Widget = WidgetLeaf | ContainerWidget;

interface WidgetsStoreState {
  isFetchedFirstTime: boolean;
  categorizedWidgets: Record<string, Widget[]>;
}

class WidgetsStore {
  private privateState = reactive<WidgetsStoreState>({
    isFetchedFirstTime: false,
    categorizedWidgets: {},
  });

  private state = computed(() => {
    if (!this.privateState.isFetchedFirstTime) {
      // initiating a side effect in a computed property seems wrong, but it needs to be
      // executed after knowing a user's logged in and it will succeed.
      this.fetchAvailableWidgets();
    }

    return readonly(this.privateState);
  });

  readonly widgets = computed(() => this.state.value.categorizedWidgets);

  private fetchAvailableWidgets(): Promise<typeof WidgetsStore['widgets']['value']> {
    // if there's no idSite, don't make the request since it will just fail
    if (!MatomoUrl.parsed.value.idSite) {
      return Promise.resolve(this.widgets.value);
    }

    this.privateState.isFetchedFirstTime = true;
    return new Promise((resolve, reject) => {
      try {
        window.widgetsHelper.getAvailableWidgets((categorizedWidgets) => {
          this.privateState.categorizedWidgets = categorizedWidgets;
          resolve(this.widgets.value);
        });
      } catch (e) {
        reject(e);
      }
    });
  }

  reloadAvailableWidgets(): Promise<typeof WidgetsStore['widgets']['value']> {
    if (typeof window.widgetsHelper === 'object' && window.widgetsHelper.availableWidgets) {
      // lets also update widgetslist so will be easier to update list of available widgets in
      // dashboard selector immediately
      delete window.widgetsHelper.availableWidgets;
    }

    return this.fetchAvailableWidgets();
  }
}

export default new WidgetsStore();