Ubuntu
/*!
* 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,
computed,
readonly,
DeepReadonly,
} from 'vue';
import { AjaxHelper } from 'CoreHome';
import { Trigger, TriggerCategory } from '../types';
interface TriggersStoreState {
triggers: Trigger[];
isLoadingTriggers: boolean;
isLoadingSingle: boolean;
isUpdating: boolean;
}
type AvailableTriggerPromises = Record>>;
class TriggersStore {
private privateState = reactive({
triggers: [],
isLoadingTriggers: false,
isLoadingSingle: false,
isUpdating: false,
});
private state = computed(() => readonly(this.privateState));
readonly isUpdating = computed(() => this.state.value.isUpdating);
readonly isLoading = computed(() => {
const state = this.state.value;
return state.isLoadingTriggers || state.isLoadingSingle;
});
readonly triggers = computed(() => this.state.value.triggers);
private fetchPromise: Promise|null = null;
private availableTriggersPromises: AvailableTriggerPromises = {};
fetchTriggers(
idContainer: string,
idContainerVersion: number,
): Promise> {
this.privateState.triggers = [];
this.privateState.isLoadingTriggers = true;
if (!this.fetchPromise) {
this.fetchPromise = AjaxHelper.fetch({
method: 'TagManager.getContainerTriggers',
idContainer,
idContainerVersion,
filter_limit: '-1',
});
}
return Promise.resolve(this.fetchPromise).then((triggers) => {
this.privateState.triggers = triggers;
return this.triggers.value;
}).finally(() => {
this.privateState.isLoadingTriggers = false;
});
}
fetchTriggersIfNotLoaded(idContainer: string, idContainerVersion: number) {
if (!this.fetchPromise) {
// needed for suggestNameForType() to make sure it is aware of all names
this.fetchTriggers(idContainer, idContainerVersion);
}
}
fetchAvailableTriggers(idContext: string) {
if (!this.availableTriggersPromises[idContext]) {
this.availableTriggersPromises[idContext] = AjaxHelper.fetch({
method: 'TagManager.getAvailableTriggerTypesInContext',
idContext,
filter_limit: '-1',
});
}
return Promise.resolve(this.availableTriggersPromises[idContext]);
}
findTrigger(
idContainer: string,
idContainerVersion: number,
idTrigger: number,
): Promise> {
// before going through an API request we first try to find it in loaded variables
const found = this.triggers.value.find((v) => v.idtrigger === idTrigger);
if (found) {
return Promise.resolve(found);
}
// otherwise we fetch it via API
this.privateState.isLoadingSingle = true;
return AjaxHelper.fetch({
idTrigger,
idContainer,
idContainerVersion,
method: 'TagManager.getContainerTrigger',
filter_limit: '-1',
}).then((record) => {
this.privateState.triggers = [...this.privateState.triggers, record];
return readonly(record);
}).finally(() => {
this.privateState.isLoadingSingle = false;
});
}
suggestNameForType(templateId: string): string|undefined {
for (let counter = 0; counter < 100; counter += 1) {
let name = templateId;
if (counter) {
name = `${name} (${counter})`;
}
const isFree = !this.triggers.value.some((v) => v.name === name);
if (isFree) {
return name;
}
}
return undefined;
}
createOrUpdateTrigger(
trigger: DeepReadonly|Trigger,
method: string,
idContainer: string,
idContainerVersion: number,
parameterValues: Record,
): Promise<{ value: number }> {
const mappedEntries = Object.entries(parameterValues).map(([key, value]) => {
let newValue = value;
if (typeof value === 'boolean') {
newValue = (+value).toString();
}
return [key, newValue];
});
const parameters = Object.fromEntries(mappedEntries);
const conditions = trigger.conditions.filter(
(c) => c && c.actual && c.comparison && c.expected,
);
this.privateState.isUpdating = true;
return AjaxHelper.post<{ value: number }>(
{
idTrigger: trigger.idtrigger,
method,
idContainer,
idContainerVersion,
type: trigger.type,
name: trigger.name,
description: trigger.description,
},
{
parameters,
conditions,
},
{ withTokenInUrl: true },
).finally(() => {
this.privateState.isUpdating = false;
});
}
reload(
idContainer: string,
idContainerVersion: number,
): ReturnType {
this.privateState.triggers = [];
this.fetchPromise = null;
this.availableTriggersPromises = {};
return this.fetchTriggers(idContainer, idContainerVersion);
}
deleteTrigger(
idContainer: string,
idContainerVersion: number,
idTrigger: number,
): Promise {
this.privateState.isUpdating = true;
this.privateState.triggers = [];
return AjaxHelper.fetch(
{
idTrigger,
idContainerVersion,
idContainer,
method: 'TagManager.deleteContainerTrigger',
},
{ withTokenInUrl: true },
).finally(() => {
this.privateState.isUpdating = false;
});
}
}
export default new TriggersStore();