%PDF- %PDF-
| Direktori : /data/www_bck/varak.net_bck/stats.varak.net/plugins/SitesManager/vue/src/SiteFields/ |
| Current File : //data/www_bck/varak.net_bck/stats.varak.net/plugins/SitesManager/vue/src/SiteFields/SiteFields.vue |
<!--
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
class="site card hoverable"
:idsite="theSite.idsite"
:type="theSite.type"
:class="{ 'editingSite': !!editMode }"
ref="root"
>
<div class="card-content">
<div class="row" v-if="!editMode">
<div class="col m3">
<h4>{{ theSite.name }}</h4>
<ul>
<li><span class="title">{{ translate('General_Id') }}:</span> {{ theSite.idsite }}</li>
<li v-show="availableTypes.length > 1">
<span class="title">{{ translate('SitesManager_Type') }}:</span>
{{ currentType.name }}
</li>
<li v-show="theSite.idsite && howToSetupUrl">
<a
:target="isInternalSetupUrl ? '_self' : '_blank'"
:title="translate('SitesManager_ShowTrackingTag')"
:href="setupUrl"
>
{{ translate('SitesManager_ShowTrackingTag') }}
</a>
</li>
</ul>
</div>
<div class="col m4">
<ul>
<li>
<span class="title">{{ translate('SitesManager_Timezone') }}:</span>
{{ theSite.timezone_name }}
</li>
<li>
<span class="title">{{ translate('SitesManager_Currency') }}:</span>
{{ theSite.currency_name }}
</li>
<li v-show="theSite.ecommerce === 1 || theSite.ecommerce === '1'">
<span class="title">{{ translate('Goals_Ecommerce') }}:</span>
{{ translate('General_Yes') }}
</li>
<li v-show="theSite.sitesearch === 1 || theSite.sitesearch === '1'">
<span class="title">{{ translate('Actions_SubmenuSitesearch') }}:</span>
{{ translate('General_Yes') }}
</li>
</ul>
</div>
<div class="col m4">
<ul>
<li>
<span class="title">{{ translate('SitesManager_Urls') }}</span>:
<span v-for="(url, index) in theSite.alias_urls" :key="url">
<a target=_blank rel="noreferrer noopener" :href="url">
{{ url }}{{ index === theSite.alias_urls.length - 1 ? '' : ', ' }}
</a>
</span>
</li>
<li v-if="theSite.excluded_ips?.length">
<span class="title">{{ translate('SitesManager_ExcludedIps') }}:</span>
{{ theSite.excluded_ips.split(/\s*,\s*/g).join(', ') }}
</li>
<li v-if="theSite.excluded_parameters?.length">
<span class="title">{{ translate('SitesManager_ExcludedParameters') }}:</span>
{{ theSite.excluded_parameters.split(/\s*,\s*/g).join(', ') }}
</li>
<li v-if="theSite.excluded_user_agents?.length">
<span class="title">{{ translate('SitesManager_ExcludedUserAgents') }}:</span>
{{ theSite.excluded_user_agents.split(/\s*,\s*/g).join(', ') }}
</li>
</ul>
</div>
<div class="col m1 text-right">
<ul>
<li>
<button
class="table-action"
@click="editSite()"
:title="translate('General_Edit')"
>
<span class="icon-edit"></span>
</button>
</li>
<li>
<button
class="table-action"
v-show="theSite.idsite"
@click="this.showRemoveDialog = true"
:title="translate('General_Delete')"
>
<span class="icon-delete"></span>
</button>
</li>
</ul>
</div>
</div>
<div v-if="editMode">
<div class="form-group row">
<div class="col s12 m6 input-field">
<input
type="text"
v-model="theSite.name"
maxlength="90"
:placeholder="translate('General_Name')"
/>
<label>{{ translate('General_Name') }}</label>
</div>
<div class="col s12 m6"></div>
</div>
<ActivityIndicator :loading="isLoading"/>
<div v-for="settingsPerPlugin in measurableSettings" :key="settingsPerPlugin.pluginName">
<GroupedSettings
:group-name="settingsPerPlugin.pluginName"
:settings="settingsPerPlugin.settings"
:all-setting-values="settingValues"
@change="settingValues[`${settingsPerPlugin.pluginName}.${$event.name}`] = $event.value"
/>
</div>
<Field
uicontrol="select"
name="currency"
v-model="theSite.currency"
:title="translate('SitesManager_Currency')"
:inline-help="translate('SitesManager_CurrencySymbolWillBeUsedForGoals')"
:options="currencies"
/>
<Field
uicontrol="select"
name="timezone"
v-model="theSite.timezone"
:title="translate('SitesManager_Timezone')"
:inline-help="'#timezoneHelpText'"
:options="timezones"
/>
<div id="timezoneHelpText" class="inline-help-node">
<div>
<span v-if="!timezoneSupportEnabled">
{{ translate('SitesManager_AdvancedTimezoneSupportNotFound') }}
<br/>
</span>
{{ utcTimeIs }}
<br/>
{{ translate('SitesManager_ChangingYourTimezoneWillOnlyAffectDataForward') }}
</div>
</div>
<div class="editingSiteFooter">
<input
v-show="!isLoading"
type="submit"
class="btn"
:value="translate('General_Save')"
@click="saveSite()"
/>
<button
class="btn btn-link"
@click="cancelEditSite(site)"
>
{{ translate('General_Cancel', '', '') }}
</button>
</div>
</div>
</div>
<PasswordConfirmation
v-model="showRemoveDialog"
@confirmed="deleteSite"
>
<h2>{{ removeDialogTitle }}</h2>
<p>{{ translate('SitesManager_DeleteSiteExplanation') }}</p>
<p>{{ translate('UsersManager_ConfirmWithPassword') }}</p>
</PasswordConfirmation>
</div>
</template>
<script lang="ts">
import { computed, DeepReadonly, defineComponent } from 'vue';
import {
Site,
MatomoUrl,
ActivityIndicator,
format,
translate,
AjaxHelper,
NotificationsStore,
} from 'CoreHome';
import {
Field,
GroupedSettings,
SettingsForSinglePlugin,
Setting,
PasswordConfirmation,
} from 'CorePluginsAdmin';
import TimezoneStore from '../TimezoneStore/TimezoneStore';
import CurrencyStore from '../CurrencyStore/CurrencyStore';
import SiteTypesStore from '../SiteTypesStore/SiteTypesStore';
import SiteType from '../SiteTypesStore/SiteType';
interface SiteFieldsState {
isLoading: boolean;
editMode: boolean;
theSite: Site;
measurableSettings: DeepReadonly<SettingsForSinglePlugin[]>;
settingValues: Record<string, unknown>;
showRemoveDialog: boolean;
}
interface CreateEditSiteResponse {
value: string|number;
}
const timezoneOptions = computed(
() => TimezoneStore.timezones.value.map(({ group, label, code }) => ({
group,
key: label,
value: code,
})),
);
function isSiteNew(site: Site) {
return typeof site.idsite === 'undefined';
}
export default defineComponent({
props: {
site: {
type: Object,
required: true,
},
timezoneSupportEnabled: {
type: Boolean,
},
utcTime: {
type: Date,
required: true,
},
globalSettings: {
type: Object,
required: true,
},
},
data(): SiteFieldsState {
return {
isLoading: false,
editMode: false,
theSite: { ...(this.site as Site) },
measurableSettings: [],
settingValues: {},
showRemoveDialog: false,
};
},
components: {
PasswordConfirmation,
Field,
GroupedSettings,
ActivityIndicator,
},
emits: ['delete', 'editSite', 'cancelEditSite', 'save'],
created() {
CurrencyStore.init();
TimezoneStore.init();
SiteTypesStore.init();
this.onSiteChanged();
},
watch: {
site() {
this.onSiteChanged();
},
measurableSettings(settings: SettingsForSinglePlugin[]) {
if (!settings.length) {
return;
}
const settingValues: Record<string, unknown> = {};
settings.forEach((settingsForPlugin) => {
settingsForPlugin.settings.forEach((setting) => {
settingValues[`${settingsForPlugin.pluginName}.${setting.name}`] = setting.value;
});
});
this.settingValues = settingValues;
},
},
methods: {
onSiteChanged() {
const site = this.site as Site;
this.theSite = { ...site };
const isNew = isSiteNew(site);
if (isNew) {
const globalSettings = this.globalSettings as Record<string, string>;
this.theSite.timezone = globalSettings.defaultTimezone;
this.theSite.currency = globalSettings.defaultCurrency;
}
const forcedEditSiteId = SiteTypesStore.getEditSiteIdParameter();
if (isNew
|| (forcedEditSiteId && `${site.idsite}` === forcedEditSiteId)
) {
this.editSite();
}
},
editSite() {
this.editMode = true;
this.$emit('editSite', { idSite: this.theSite.idsite });
this.measurableSettings = [];
if (isSiteNew(this.theSite)) {
if (!this.currentType) {
return;
}
this.measurableSettings = this.currentType.settings || [];
return;
}
this.isLoading = true;
AjaxHelper.fetch<SettingsForSinglePlugin[]>({
method: 'SitesManager.getSiteSettings',
idSite: this.theSite.idsite,
}).then((settings) => {
this.measurableSettings = settings;
}).finally(() => {
this.isLoading = false;
});
},
saveSite() {
const values: Record<string, unknown> = {
siteName: this.theSite.name,
timezone: this.theSite.timezone,
currency: this.theSite.currency,
type: this.theSite.type,
settingValues: {} as Record<string, Setting[]>,
};
const isNew = isSiteNew(this.theSite);
let apiMethod = 'SitesManager.addSite';
if (!isNew) {
apiMethod = 'SitesManager.updateSite';
values.idSite = this.theSite.idsite;
}
// process measurable settings
Object.entries(this.settingValues).forEach(([fullName, fieldValue]) => {
const [pluginName, name] = fullName.split('.');
const settingValues = values.settingValues as Record<string, Setting[]>;
if (!settingValues[pluginName]) {
settingValues[pluginName] = [];
}
let value = fieldValue;
if (fieldValue === false) {
value = '0';
} else if (fieldValue === true) {
value = '1';
} else if (Array.isArray(fieldValue)) {
value = fieldValue.filter((x) => !!x);
}
settingValues[pluginName].push({
name,
value,
});
});
AjaxHelper.post<CreateEditSiteResponse>(
{
method: apiMethod,
},
values,
).then((response) => {
this.editMode = false;
if (!this.theSite.idsite && response && response.value) {
this.theSite.idsite = `${response.value}`;
}
const timezoneInfo = TimezoneStore.timezones.value.find(
(t) => t.code === this.theSite.timezone,
);
this.theSite.timezone_name = timezoneInfo?.label || this.theSite.timezone;
if (this.theSite.currency) {
this.theSite.currency_name = CurrencyStore.currencies.value[this.theSite.currency];
}
const notificationId = NotificationsStore.show({
message: isNew
? translate('SitesManager_WebsiteCreated')
: translate('SitesManager_WebsiteUpdated'),
context: 'success',
id: 'websitecreated',
type: 'transient',
});
NotificationsStore.scrollToNotification(notificationId);
SiteTypesStore.removeEditSiteIdParameterFromHash();
this.$emit('save', { site: this.theSite, settingValues: values.settingValues, isNew });
});
},
cancelEditSite(site: Site) {
this.editMode = false;
SiteTypesStore.removeEditSiteIdParameterFromHash();
this.$emit('cancelEditSite', { site, element: this.$refs.root as HTMLElement });
},
deleteSite(password: string) {
AjaxHelper.post({
idSite: this.theSite.idsite,
module: 'API',
format: 'json',
method: 'SitesManager.deleteSite',
}, {
passwordConfirmation: password,
}).then(() => {
this.$emit('delete', this.theSite);
});
},
},
computed: {
availableTypes() {
return SiteTypesStore.types.value;
},
setupUrl() {
const site = this.theSite as Site;
let suffix = '';
let connector = '';
if (this.isInternalSetupUrl) {
suffix = MatomoUrl.stringify({
idSite: site.idsite,
period: MatomoUrl.parsed.value.period,
date: MatomoUrl.parsed.value.date,
updated: 'false',
});
connector = this.howToSetupUrl!.indexOf('?') === -1 ? '?' : '&';
}
return `${this.howToSetupUrl}${connector}${suffix}`;
},
utcTimeIs() {
const utcTime = this.utcTime as Date;
const formatTimePart = (n: number) => n.toString().padStart(2, '0');
const hours = formatTimePart(utcTime.getHours());
const minutes = formatTimePart(utcTime.getMinutes());
const seconds = formatTimePart(utcTime.getSeconds());
const date = `${format(this.utcTime)} ${hours}:${minutes}:${seconds}`;
return translate('SitesManager_UTCTimeIs', date);
},
timezones() {
return timezoneOptions.value;
},
currencies() {
return CurrencyStore.currencies.value;
},
currentType(): DeepReadonly<SiteType> {
const site = this.site as Site;
const type = SiteTypesStore.typesById.value[site.type];
if (!type) {
return { name: site.type } as SiteType;
}
return type;
},
howToSetupUrl() {
const type = this.currentType;
if (!type) {
return undefined;
}
return type.howToSetupUrl;
},
isInternalSetupUrl() {
const { howToSetupUrl } = this;
if (!howToSetupUrl) {
return false;
}
return (`${howToSetupUrl}`).substring(0, 1) === '?';
},
removeDialogTitle() {
return translate(
'SitesManager_DeleteConfirm',
`"${this.theSite.name}" (idSite = ${this.theSite.idsite})`,
);
},
},
});
</script>