HEX
Server: Microsoft-IIS/10.0
System: Windows NT ITPWINWEBSVR22 10.0 build 20348 (Windows Server 2022) AMD64
User: www.conferencesearch.co.uk (0)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: D:/web/matomo.vdk/plugins/MultiSites/vue/src/AllWebsitesDashboard/SitesTable.vue
<!--
  Matomo - free/libre analytics platform

  @link    https://matomo.org
  @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->

<template>
  <div class="sitesTableContainer">
    <table class="card-table dataTable sitesTable" v-tooltips>
      <thead>
        <tr>
          <th
              @click="sortBy('label')"
              class="label"
              :title="translate('MultiSites_MetricDocumentationWebsite')"
          >
            {{ translate('General_Website') }}
            <span
                v-if="sortColumn === 'label'"
                :class="sortColumnClass"
            />
          </th>

          <th @click="sortBy('nb_visits')"
              :title="translate('MultiSites_MetricDocumentationVisits')">
            <span
                v-if="sortColumn === 'nb_visits'"
                :class="sortColumnClass"
            />
            {{ translate('General_ColumnNbVisits') }}
          </th>

          <th @click="sortBy('nb_pageviews')"
              :title="translate('MultiSites_MetricDocumentationPageviews')">
            <span
                v-if="sortColumn === 'nb_pageviews'"
                :class="sortColumnClass"
            />
            {{ translate('General_ColumnPageviews') }}
          </th>

          <th v-if="showAiChatbotsRequests && !isSegmented"
              @click="sortBy('ai_chatbots_requests')"
              :title="translate('MultiSites_MetricDocumentationAiChatbotsRequests')">
            <span
                v-if="sortColumn === 'ai_chatbots_requests'"
                :class="sortColumnClass"
            />
            {{ translate('MultiSites_AiChatbotsRequests') }}
          </th>

          <th @click="sortBy('hits')"
              :title="translate(showAiChatbotsRequests && !isSegmented
                ? 'MultiSites_MetricDocumentationHitsIncludingAi'
                : 'MultiSites_MetricDocumentationHits')">
            <span
                v-if="sortColumn === 'hits'"
                :class="sortColumnClass"
            />
            {{ translate('General_ColumnHits') }}
          </th>

          <th v-if="displayRevenue"
              @click="sortBy('revenue')"
              :title="translate('MultiSites_MetricDocumentationRevenue')"
          >
            <span
                v-if="sortColumn === 'revenue'"
                :class="sortColumnClass"
            />
            {{ translate('General_ColumnRevenue') }}
          </th>

          <th @click="sortBy(evolutionSelector)"
              :title="translate('MultiSites_MetricDocumentationEvolution')">
            <span
                v-if="sortColumn === evolutionSelector"
                :class="sortColumnClass"
            />
            {{ translate('MultiSites_Evolution') }}
          </th>

          <th class="sitesTableEvolutionSelector">
            <select
                class="browser-default"
                :value="evolutionSelector"
                @change="changeEvolutionSelector($event.target.value)"
            >
              <option value="hits_evolution">
                {{ translate('General_ColumnHits')}}
              </option>
              <option value="visits_evolution">
                {{ translate('General_ColumnNbVisits') }}
              </option>
              <option value="pageviews_evolution">
                {{ translate('General_ColumnPageviews') }}
              </option>
              <option
                  value="ai_chatbots_requests_evolution"
                  v-if="showAiChatbotsRequests && !isSegmented"
              >
                {{ translate('MultiSites_AiChatbotsRequests') }}
              </option>
              <option
                  value="revenue_evolution"
                  v-if="displayRevenue"
              >
                {{ translate('General_ColumnRevenue') }}
              </option>
            </select>
          </th>
        </tr>
      </thead>

      <tbody>
        <tr v-if="isLoading">
          <td class="sitesTableLoading" :colspan="loadingColspan">
            <MatomoLoader />
          </td>
        </tr>

        <SitesTableSite
            v-else
            v-for="site in sites"
            :display-revenue="displayRevenue"
            :evolution-metric="evolutionMetric"
            :key="`site-${site.idsite}`"
            :model-value="site"
            :display-sparkline="displaySparklines"
            :sparkline-metric="sparklineMetric"
            :show-ai-chatbots-requests="showAiChatbotsRequests && !isSegmented"
        />
      </tbody>
    </table>
  </div>

  <div v-if="!isLoading || paginationUpperBound > 0"
       class="sitesTablePagination">
    <span
        class="dataTablePrevious"
        @click="navigatePreviousPage()"
        v-show="paginationCurrentPage !== 0"
    >
      &#xAB; {{ translate('General_Previous') }}
    </span>

    <span class="dataTablePages">
      {{ translate(
        'General_Pagination',
        paginationLowerBound,
        paginationUpperBound,
        numberOfFilteredSites,
      ) }}
    </span>

    <span
        class="dataTableNext"
        @click="navigateNextPage()"
        v-show="paginationCurrentPage < paginationMaxPage"
    >
      {{ translate('General_Next') }} &#xBB;
    </span>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { Matomo, MatomoLoader, Tooltips } from 'CoreHome';

import DashboardStore from './AllWebsitesDashboard.store';
import SitesTableSite from './SitesTableSite.vue';
import { DashboardSiteData, DashboardSortOrder } from '../types';

interface SitesTableState {
  evolutionSelector: string;
}

export default defineComponent({
  directives: {
    Tooltips,
  },
  components: {
    MatomoLoader,
    SitesTableSite,
  },
  props: {
    displayRevenue: {
      type: Boolean,
      required: true,
    },
    displaySparklines: {
      type: Boolean,
      required: true,
    },
    showAiChatbotsRequests: {
      type: Boolean,
      required: true,
    },
    isSegmented: {
      type: Boolean,
      required: true,
    },
  },
  data(): SitesTableState {
    return {
      evolutionSelector: 'visits_evolution',
    };
  },
  watch: {
    isSegmented() {
      this.ensureEvolutionSelectorIsValid();
    },
  },
  computed: {
    errorLoading(): boolean {
      return DashboardStore.state.value.errorLoading;
    },
    errorShowProfessionalHelp() {
      return Matomo.config && Matomo.config.are_ads_enabled;
    },
    evolutionMetric(): string {
      return this.evolutionSelector;
    },
    isLoading(): boolean {
      return DashboardStore.state.value.isLoadingSites;
    },
    numberOfFilteredSites() {
      return DashboardStore.state.value.numSites;
    },
    paginationCurrentPage(): number {
      return DashboardStore.state.value.paginationCurrentPage;
    },
    paginationLowerBound() {
      return DashboardStore.paginationLowerBound.value;
    },
    paginationUpperBound() {
      return DashboardStore.paginationUpperBound.value;
    },
    paginationMaxPage(): number {
      return DashboardStore.numberOfPages.value;
    },
    sites(): DashboardSiteData[] {
      return DashboardStore.state.value.dashboardSites as DashboardSiteData[];
    },
    sortColumn(): string {
      return DashboardStore.state.value.sortColumn;
    },
    sortColumnClass(): Record<string, boolean> {
      return {
        sitesTableSort: true,
        sitesTableSortAsc: this.sortOrder === 'asc',
        sitesTableSortDesc: this.sortOrder === 'desc',
      };
    },
    sortOrder(): DashboardSortOrder {
      return DashboardStore.state.value.sortOrder;
    },
    sparklineMetric(): string {
      switch (this.evolutionMetric) {
        case 'hits_evolution':
          return 'hits';
        case 'pageviews_evolution':
          return 'nb_pageviews';
        case 'ai_chatbots_requests_evolution':
          return 'ai_chatbots_requests';
        case 'revenue_evolution':
          return 'revenue';
        case 'visits_evolution':
          return 'nb_visits';
        default:
          return '';
      }
    },
    loadingColspan(): number {
      let columns = 6;
      if (this.showAiChatbotsRequests && !this.isSegmented) {
        columns += 1;
      }
      if (this.displayRevenue) {
        columns += 1;
      }
      if (this.displaySparklines) {
        columns += 1;
      }
      return columns;
    },
  },
  methods: {
    changeEvolutionSelector(metric: string) {
      this.evolutionSelector = metric;

      this.sortBy(metric);
    },
    ensureEvolutionSelectorIsValid() {
      if (
        this.evolutionSelector === 'ai_chatbots_requests_evolution'
        && (this.isSegmented || !this.showAiChatbotsRequests)
      ) {
        this.evolutionSelector = 'visits_evolution';
        this.sortBy(this.evolutionSelector);
      }
    },
    navigateNextPage() {
      DashboardStore.navigateNextPage();
    },
    navigatePreviousPage() {
      DashboardStore.navigatePreviousPage();
    },
    sortBy(column: string) {
      DashboardStore.sortBy(column);
    },
  },
});
</script>