Provide analytics on Front-end

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-12-16 16:48:50 +01:00
parent c1a59f5536
commit 709d26735b
19 changed files with 733 additions and 156 deletions

View File

@@ -0,0 +1,50 @@
import {
IAnalyticsConfig,
IConfig,
IKeyValueConfig,
} from "@/types/config.model";
export const statistics = async (config: IConfig, environement: any) => {
console.debug("Loading statistics", config.analytics);
const matomoConfig = checkProviderConfig(config, "matomo");
if (matomoConfig?.enabled === true) {
const { matomo } = (await import("./matomo")) as any;
matomo(environement, convertConfig(matomoConfig.configuration));
}
const sentryConfig = checkProviderConfig(config, "sentry");
if (sentryConfig?.enabled === true) {
const { sentry } = (await import("./sentry")) as any;
sentry(environement, convertConfig(sentryConfig.configuration));
}
};
export const checkProviderConfig = (
config: IConfig,
providerName: string
): IAnalyticsConfig | undefined => {
return config?.analytics?.find((provider) => provider.id === providerName);
};
export const convertConfig = (
configs: IKeyValueConfig[]
): Record<string, any> => {
return configs.reduce((acc, config) => {
acc[config.key] = toType(config.value, config.type);
return acc;
}, {} as Record<string, any>);
};
const toType = (value: string, type: string): string | number | boolean => {
switch (type) {
case "boolean":
return value === "true";
case "integer":
return parseInt(value, 10);
case "float":
return parseFloat(value);
case "string":
default:
return value;
}
};

View File

@@ -0,0 +1,14 @@
import Vue from "vue";
import VueMatomo from "vue-matomo";
export const matomo = (environment: any, matomoConfiguration: any) => {
console.debug("Loading Matomo statistics");
console.debug(
"Calling VueMatomo with the following configuration",
matomoConfiguration
);
Vue.use(VueMatomo, {
...matomoConfiguration,
router: environment.router,
});
};

View File

@@ -0,0 +1,11 @@
import VueRouter from "vue-router";
import Vue from "vue";
import { VuePlausible } from "vue-plausible";
export default (router: VueRouter, plausibleConfiguration: any) => {
console.debug("Loading Plausible statistics");
Vue.use(VuePlausible, {
// see configuration section
...plausibleConfiguration,
});
};

View File

@@ -0,0 +1,54 @@
import Vue from "vue";
import * as Sentry from "@sentry/vue";
import { Integrations } from "@sentry/tracing";
export const sentry = (environment: any, sentryConfiguration: any) => {
console.debug("Loading Sentry statistics");
console.debug(
"Calling Sentry with the following configuration",
sentryConfiguration
);
// Don't attach errors to previous events
window.sessionStorage.removeItem("lastEventId");
Sentry.init({
Vue,
dsn: sentryConfiguration.dsn,
integrations: [
new Integrations.BrowserTracing({
routingInstrumentation: Sentry.vueRouterInstrumentation(
environment.router
),
tracingOrigins: ["localhost", "mobilizon1.com", /^\//],
}),
],
beforeSend(event) {
// Check if it is an exception, and if so, save it in session storage
// so that it can be retreived from the error component
if (event.exception && event.event_id) {
window.sessionStorage.setItem("lastEventId", event.event_id);
}
return event;
},
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: sentryConfiguration.tracesSampleRate,
release: environment.version,
});
};
export const submitFeedback = async (
endpoint: string,
dsn: string,
params: Record<string, string>
): Promise<void> => {
await fetch(endpoint, {
method: "POST",
headers: {
"Content-type": "application/json",
Authorization: `DSN ${dsn}`,
},
body: JSON.stringify(params),
});
};