diff options
Diffstat (limited to 'plugins/MobileMessaging/vue/src')
6 files changed, 221 insertions, 9 deletions
diff --git a/plugins/MobileMessaging/vue/src/ManageSmsProvider/ManageSmsProvider.vue b/plugins/MobileMessaging/vue/src/ManageSmsProvider/ManageSmsProvider.vue index d2c415575f..cdf62c5469 100644 --- a/plugins/MobileMessaging/vue/src/ManageSmsProvider/ManageSmsProvider.vue +++ b/plugins/MobileMessaging/vue/src/ManageSmsProvider/ManageSmsProvider.vue @@ -76,7 +76,7 @@ interface ManageSmsProviderState { isDeletingAccount: boolean; isUpdatingAccount: boolean; showAccountForm: boolean; - credentials: Record<string, unknown>; + credentials: Record<string, unknown>|null; smsProvider?: string; } @@ -109,7 +109,7 @@ export default defineComponent({ isDeletingAccount: false, isUpdatingAccount: false, showAccountForm: false, - credentials: {}, + credentials: null, smsProvider: this.provider, }; }, @@ -187,7 +187,7 @@ export default defineComponent({ isUpdateAccountPossible() { // possible if smsProvider is set and all credential field values are set to something return !!this.smsProvider - && Object.keys(this.credentials).length > 0 + && this.credentials !== null && Object.values(this.credentials as Record<string, string>).every((v) => !!v); }, updateOrDeleteAccountText() { diff --git a/plugins/MobileMessaging/vue/src/ReportParameters/ReportParameters.vue b/plugins/MobileMessaging/vue/src/ReportParameters/ReportParameters.vue new file mode 100644 index 0000000000..d0c067265d --- /dev/null +++ b/plugins/MobileMessaging/vue/src/ReportParameters/ReportParameters.vue @@ -0,0 +1,79 @@ +<!-- + 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="report && report.type === 'mobile'"> + <SelectPhoneNumbers + :phone-numbers="phoneNumbers" + :with-introduction="true" + :model-value="report.phoneNumbers" + @update:model-value="$emit('change', 'phoneNumbers', $event)" + /> + </div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import { Report } from 'ScheduledReports'; +import SelectPhoneNumbers from '../SelectPhoneNumbers/SelectPhoneNumbers.vue'; + +const REPORT_TYPE = 'mobile'; + +export default defineComponent({ + props: { + report: { + type: Object, + required: true, + }, + phoneNumbers: { + type: [Array, Object], + required: true, + }, + }, + components: { + SelectPhoneNumbers, + }, + emits: ['change'], + created() { + const { + resetReportParametersFunctions, + updateReportParametersFunctions, + getReportParametersFunctions, + } = window; + + if (!resetReportParametersFunctions[REPORT_TYPE]) { + resetReportParametersFunctions[REPORT_TYPE] = (report: Report) => { + report.phoneNumbers = []; + report.formatmobile = 'sms'; + }; + } + + if (!updateReportParametersFunctions[REPORT_TYPE]) { + updateReportParametersFunctions[REPORT_TYPE] = (report: Report) => { + if (!report?.parameters) { + return; + } + + if (report.parameters && report.parameters.phoneNumbers) { + report.phoneNumbers = report.parameters.phoneNumbers; + } + report.formatmobile = 'sms'; + }; + } + + if (!getReportParametersFunctions[REPORT_TYPE]) { + getReportParametersFunctions[REPORT_TYPE] = (report: Report) => { + // returning [''] when no phone numbers are selected avoids the "please provide a value + // for 'parameters'" error message + const phoneNumbers: string[]|undefined = report.phoneNumbers as string[]|undefined; + return { + phoneNumbers: phoneNumbers || [''], + }; + }; + } + }, +}); +</script> diff --git a/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.adapter.ts b/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.adapter.ts new file mode 100644 index 0000000000..c1b79d5c56 --- /dev/null +++ b/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.adapter.ts @@ -0,0 +1,60 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +import { INgModelController, ITimeoutService } from 'angular'; +import { nextTick } from 'vue'; +import { createAngularJsAdapter, removeAngularJsSpecificProperties } from 'CoreHome'; +import SelectPhoneNumbers from './SelectPhoneNumbers.vue'; + +export default createAngularJsAdapter<[ITimeoutService]>({ + component: SelectPhoneNumbers, + require: '?ngModel', + scope: { + phoneNumbers: { + angularJsBind: '<', + }, + withIntroduction: { + angularJsBind: '<', + }, + value: { + angularJsBind: '<', + vue: 'modelValue', + }, + }, + $inject: ['$timeout'], + directiveName: 'matomoSelectPhoneNumbers', + events: { + 'update:modelValue': (newValue, vm, scope, element, attrs, ngModel, $timeout) => { + if (!ngModel) { + return; + } + + if (newValue !== (ngModel as INgModelController).$viewValue) { + $timeout(() => { + (ngModel as INgModelController).$setViewValue(newValue); + (ngModel as INgModelController).$render(); // not detected by the watch for some reason + }); + } + }, + }, + postCreate(vm, scope, element, attrs, controller) { + const ngModel = controller as INgModelController; + + // ngModel being used + ngModel.$render = () => { + nextTick(() => { + vm.modelValue = removeAngularJsSpecificProperties(ngModel.$viewValue); + }); + }; + + if (typeof scope.value !== 'undefined') { + (ngModel as INgModelController).$setViewValue(scope.value); + } else { + ngModel.$setViewValue(vm.modelValue); + } + }, +}); diff --git a/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.vue b/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.vue new file mode 100644 index 0000000000..15a34dcd7e --- /dev/null +++ b/plugins/MobileMessaging/vue/src/SelectPhoneNumbers/SelectPhoneNumbers.vue @@ -0,0 +1,66 @@ +<!-- + 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='mobile'> + <Field + uicontrol="checkbox" + var-type="array" + name="phoneNumbers" + :model-value="modelValue" + @update:model-value="$emit('update:modelValue', $event)" + :introduction="withIntroduction ? translate('ScheduledReports_SendReportTo') : undefined" + :title="translate('MobileMessaging_PhoneNumbers')" + :disabled="phoneNumbers.length === 0" + :options="phoneNumbers" + > + <template v-slot:inline-help> + <div id="mobilePhoneNumbersHelp" class="inline-help-node"> + <span class="icon-info" style="margin-right:3.5px"></span> + + <span v-if="phoneNumbers.length === 0" style="margin-right:3.5px"> + {{ translate('MobileMessaging_MobileReport_NoPhoneNumbers') }} + </span> + <span v-else style="margin-right:3.5px"> + {{ translate('MobileMessaging_MobileReport_AdditionalPhoneNumbers') }} + </span> + <a :href="linkTo({ module: 'MobileMessaging', action: 'index', updated: null })"> + {{ translate('MobileMessaging_MobileReport_MobileMessagingSettingsLink') }} + </a> + </div> + </template> + </Field> + </div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import { MatomoUrl } from 'CoreHome'; +import { Field } from 'CorePluginsAdmin'; + +export default defineComponent({ + props: { + modelValue: Array, + phoneNumbers: { + type: [Array, Object], + required: true, + }, + withIntroduction: Boolean, + }, + emits: ['update:modelValue'], + components: { + Field, + }, + methods: { + linkTo(params: QueryParameters) { + return `?${MatomoUrl.stringify({ + ...MatomoUrl.urlParsed.value, + ...params, + })}`; + }, + }, +}); +</script> diff --git a/plugins/MobileMessaging/vue/src/SmsProviderCredentials/SmsProviderCredentials.vue b/plugins/MobileMessaging/vue/src/SmsProviderCredentials/SmsProviderCredentials.vue index 34a6d8b8ff..7762eaecd2 100644 --- a/plugins/MobileMessaging/vue/src/SmsProviderCredentials/SmsProviderCredentials.vue +++ b/plugins/MobileMessaging/vue/src/SmsProviderCredentials/SmsProviderCredentials.vue @@ -37,10 +37,7 @@ export default defineComponent({ type: String, required: true, }, - modelValue: { - type: Object, - required: true, - }, + modelValue: Object, }, emits: ['update:modelValue'], components: { @@ -49,7 +46,7 @@ export default defineComponent({ watch: { provider() { // unset credentials when new provider is chosen - this.$emit('update:modelValue', {}); + this.$emit('update:modelValue', null); // fetch fields for provider this.getCredentialFields(); @@ -61,14 +58,21 @@ export default defineComponent({ methods: { getCredentialFields() { if (allFieldsByProvider[this.provider]) { + this.$emit( + 'update:modelValue', + Object.fromEntries( + (allFieldsByProvider[this.provider] as FieldInfo[]).map((f) => [f.name, null]), + ), + ); return; } - AjaxHelper.fetch({ + AjaxHelper.fetch<FieldInfo[]>({ module: 'MobileMessaging', action: 'getCredentialFields', provider: this.provider, }).then((fields) => { + this.$emit('update:modelValue', Object.fromEntries(fields.map((f) => [f.name, null]))); allFieldsByProvider[this.provider] = fields; }); }, diff --git a/plugins/MobileMessaging/vue/src/index.ts b/plugins/MobileMessaging/vue/src/index.ts index a26a2b9526..335b7ee0fc 100644 --- a/plugins/MobileMessaging/vue/src/index.ts +++ b/plugins/MobileMessaging/vue/src/index.ts @@ -6,8 +6,11 @@ */ import './SmsProviderCredentials/SmsProviderCredentials.adapter'; +import './SelectPhoneNumbers/SelectPhoneNumbers.adapter'; +export { default as ReportParameters } from './ReportParameters/ReportParameters.vue'; export { default as ManageSmsProvider } from './ManageSmsProvider/ManageSmsProvider.vue'; export { default as SmsProviderCredentials } from './SmsProviderCredentials/SmsProviderCredentials.vue'; export { default as DelegateMobileMessagingSettings } from './DelegateMobileMessagingSettings/DelegateMobileMessagingSettings.vue'; export { default as ManageMobilePhoneNumbers } from './ManageMobilePhoneNumbers/ManageMobilePhoneNumbers.vue'; +export { default as SelectPhoneNumbers } from './SelectPhoneNumbers/SelectPhoneNumbers.vue'; |