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

Widget.vue « Widget « src « vue « CoreHome « plugins - github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 725aa6f6941d63c46f5d0e942c62bc451cba7793 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<!--
  Matomo - free/libre analytics platform
  @link https://matomo.org
  @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->

<template>
  <div
    v-if="actualWidget"
    v-show="showWidget"
    class="matomo-widget"
    :class="{'isFirstWidgetInPage': actualWidget.isFirstInPage}"
    :id="actualWidget.uniqueId"
    v-tooltips="{ content: tooltipContent }"
  >
    <WidgetLoader
      v-if="!actualWidget.isContainer && actualWidget.parameters"
      :widget-params="actualWidget.parameters"
      :widget-name="actualWidget.name"
    />
    <div v-if="actualWidget.isContainer
      && actualWidget.layout !== 'ByDimension'
      && !this.preventRecursion"
    >
      <div>
        <WidgetContainer :container="actualWidget.widgets" />
      </div>
    </div>
    <div v-if="actualWidget.isContainer && actualWidget.layout === 'ByDimension'">
      <div>
        <WidgetByDimensionContainer :widgets="actualWidget.widgets" />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import JQuery = JQuery;
import WidgetLoader from '../WidgetLoader/WidgetLoader.vue';
import WidgetContainer from '../WidgetContainer/WidgetContainer.vue';
import WidgetByDimensionContainer from '../WidgetByDimensionContainer/WidgetByDimensionContainer.vue';
import WidgetsStoreInstance, { Widget as WidgetData, ContainerWidget } from './Widgets.store';
import AjaxHelper from '../AjaxHelper/AjaxHelper';
import ReportMetadataStoreInstance from '../ReportMetadata/ReportMetadata.store';
import Tooltips from '../Tooltips/Tooltips';

function findContainer(
  widgetsByCategory: typeof WidgetsStoreInstance.widgets.value,
  containerId: string,
): ContainerWidget|undefined {
  let widget: ContainerWidget;
  Object.values(widgetsByCategory || {}).some((widgets) => {
    widget = widgets.find((w) => w && w.isContainer && w.parameters.containerId === containerId);
    return widget;
  });
  return widget;
}

/**
 * Renders any kind of widget. If you have a widget and you want to have it rendered, use this
 * directive. It will display a name on top and the actual widget below. It can handle any kind
 * of widget, no matter whether it is a regular widget or a container.
 *
 * @param {Object} piwikWidget  A widget object as returned by the WidgetMetadata API.
 * @param {Object} piwikWidget.middlewareParameters   If present, we will request a URL using the
 *                                                    given parameters and only if this URL
 *                                                    returns a JSON `true` the widget will be
 *                                                    shown. Otherwise the widget won't be shown.
 * @param {String} containerId  If you do not have a widget object but a containerId we will find
 *                              the correct widget object based on the given containerId. Be aware
 *                              that we might not find the widget if it is for example not
 *                              available for the current user or period/date.
 * @param {Boolean} widgetized  true if the widget is widgetized (eg in Dashboard or exported).
 *                              In this case we will add a URL parameter widget=1 to all widgets.
 *                              Eg sparklines will be then displayed one after another
 *                              (vertically aligned) instead of two next to each other.
 *
 * Example:
 * <Widget :widget="widget"></Widget>
 * // in this case we will find the correct widget automatically
 * <Widget :containerid="widgetGoalsOverview"></Widget>
 * // disables rating feature, no initial headline
 * <Widget :widget="widget" :widetized="true"></Widget>
 */
export default defineComponent({
  props: {
    widget: Object,
    widgetized: Boolean,
    containerid: String,
    preventRecursion: Boolean,
  },
  components: {
    WidgetLoader,
    WidgetContainer,
    WidgetByDimensionContainer,
  },
  directives: {
    Tooltips,
  },
  data() {
    return {
      showWidget: false,
    };
  },
  setup() {
    function tooltipContent() {
      const $this = window.$(this) as JQuery;
      if ($this.attr('piwik-field') === '' || $this.hasClass('matomo-form-field')) {
        // do not show it for form fields
        return '';
      }

      const title = window.$(this).attr('title');
      return window.vueSanitize(title.replace(/\n/g, '<br />'));
    }

    return {
      tooltipContent,
    };
  },
  created() {
    const { actualWidget } = this;

    if (!actualWidget || !actualWidget.middlewareParameters) {
      this.showWidget = true;
    } else {
      AjaxHelper.fetch(actualWidget.middlewareParameters).then((response) => {
        this.showWidget = !!response;
      });
    }
  },
  computed: {
    allWidgets() {
      return WidgetsStoreInstance.widgets.value;
    },
    actualWidget() {
      const { widget }: { widget: WidgetData } = this;

      if (widget) {
        const result = { ...widget };

        if (widget && widget.isReport && !widget.documentation) {
          const report = ReportMetadataStoreInstance.findReport(widget.module, widget.action);
          if (report && report.documentation) {
            result.documentation = report.documentation;
          }
        }

        return widget;
      }

      if (this.containerid) {
        const containerWidget = findContainer(this.allWidgets, this.containerid);
        if (containerWidget) {
          const result = { ...containerWidget };

          if (this.widgetized) {
            result.isFirstInPage = true;
            result.parameters = { ...result.parameters, widget: '1' };
            if (result.widgets) {
              result.widgets = result.widgets.map((w) => ({
                ...w,
                parameters: {
                  ...w.parameters,
                  widget: '1',
                  containerId: this.containerid,
                },
              }));
            }
          }

          return result;
        }
      }

      return null;
    },
  },
});
</script>