diff options
author | Ben Burgess <88810029+bx80@users.noreply.github.com> | 2022-09-09 07:08:01 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-09 07:08:01 +0300 |
commit | 178c87bdba89ec714805e346d97fdda7af79498c (patch) | |
tree | 94522a17183c1f3517be02596fa12abfadce091c /plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue | |
parent | 437dfd2e2b21d3aa875d33d4a095ff784a26a310 (diff) |
Improved opt out (#19528)
* New opt out UI, self-contained code - WIP
* Updated translation
* built vue files
* Added OptOutJS functionality, code improvements, show custom guide link on UI
* Rebuild Vue
* built vue files
* Fix typo
* Default iframe out-out to show intro, minor code tidy, updated UI test screenshots
* built vue files
* Replaced let with var
* Improved warning when opt-out content div is missing, added info box to recommend testing
* built vue files
* Update UI test screenshots
* Show intro parameter show as zero if not set, hide opt out complete message if not showing intro, added additional opt out url exclusions, reverted incorrect regex adjustments
* built vue files
* Annotated new core home embed code methods as internal
* Simplify code
Co-authored-by: Stefan Giehl <stefan@matomo.org>
* Updated parameter name, added trailing url trimming
* Added language choice selection for self-contained opt-out code
* Increased test_TotalPiwikFilesSize_isWithinReasonnableSize size from 58MiB to 60MiB
* Adjust layout
* Update UI test screenshot
* Prevent session start for optOutJS controller method
* Fix conflicts
* Fix for vue error
* built vue files
* Added content type and cache control headers when serving the opt out javascript
* Added option to apply styling (disabled by default), improved reminder box visibility, updated developer log, added what's new, added title to opt-out developer guide section
* built vue files
* Fix typo
Co-authored-by: Justin Velluppillai <justin@innocraft.com>
* Update tests
* Update UI test screenshot
* Moved inline CSS style to less
* built vue files
* Update UI test screenshot
* Update test reminder section style
* built vue files
* Update UI test screenshot
* Accept cookie path and cookie domain as URL parameters, revert loading (incorrect) cookie settings from config
* Bump to retry random test fail
* Local vue build
* built vue files
* Added blog post link to the what's new notification
* Update UI test screenshot
* Update "What's New?" link url
Co-authored-by: bx80 <bx80@users.noreply.github.com>
Co-authored-by: Stefan Giehl <stefan@matomo.org>
Co-authored-by: Justin Velluppillai <justin@innocraft.com>
Diffstat (limited to 'plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue')
-rw-r--r-- | plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue | 241 |
1 files changed, 209 insertions, 32 deletions
diff --git a/plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue b/plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue index ca9435ae39..fc0d43a250 100644 --- a/plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue +++ b/plugins/PrivacyManager/vue/src/OptOutCustomizer/OptOutCustomizer.vue @@ -12,8 +12,25 @@ v-html="$sanitize(readThisToLearnMore)" /> </p> - <h3>{{ translate('PrivacyManager_OptOutCustomize') }}</h3> + <h3>{{ translate('PrivacyManager_OptOutAppearance') }}</h3> <div> + <span> + <label> + <input + id="applyStyling" + type="checkbox" + name="applyStyling" + v-model="applyStyling" + @keydown="updateCode()" + @change="updateCode()" + /> + <span> + {{ translate('PrivacyManager_ApplyStyling') }} + </span> + </label> + </span> + </div> + <div v-if="applyStyling" id="opt-out-styling"> <p> <span> {{ translate('PrivacyManager_FontColor') }}: @@ -40,6 +57,7 @@ type="number" min="1" max="100" + :value="fontSize" @keydown="onFontSizeChange($event)" @change="onFontSizeChange($event)" /> @@ -47,6 +65,7 @@ <span> <select class="browser-default" + :value="fontSizeUnit" @keydown="onFontSizeUnitChange($event)" @change="onFontSizeUnitChange($event)" > @@ -62,20 +81,30 @@ <input id="FontFamilyInput" type="text" + :value="fontFamily" @keydown="onFontFamilyChange($event)" @change="onFontFamilyChange($event)" /> </span> </p> </div> - <h3>{{ translate('PrivacyManager_OptOutHtmlCode') }}</h3> - <pre v-select-on-focus="{}" ref="pre"><iframe - style="border: 0; height: 200px; width: 600px;" - src="{{ iframeUrl }}" - ></iframe></pre> - <p - v-html="$sanitize(optOutExplanationIntro)"> - </p> + <div> + <span> + <label> + <input + id="showIntro" + type="checkbox" + name="showIntro" + v-model="showIntro" + @keydown="updateCode()" + @change="updateCode()" + /> + <span> + {{ translate('PrivacyManager_ShowIntro') }} + </span> + </label> + </span> + </div> <h3>{{ translate('PrivacyManager_OptOutPreview') }}</h3> <iframe id="previewIframe" @@ -84,6 +113,91 @@ :class="{ withBg }" /> </div> + <div> + <div class="form-group row"> + <div class="col s12 m6"> + <h3>{{ translate('PrivacyManager_OptOutHtmlCode') }}</h3> + <p> + <label for="codeType1"> + <input + type="radio" + id="codeType1" + name="codeType" + value="tracker" + v-model="codeType" + @keydown="updateCode()" + @change="updateCode()" + /> + <span>{{ translate('PrivacyManager_OptOutUseTracker') }}</span> + </label> + </p> + + <p> + <label for="codeType2"> + <input + type="radio" + id="codeType2" + name="codeType" + value="selfContained" + v-model="codeType" + @keydown="updateCode()" + @change="updateCode()" + /> + <span>{{ translate('PrivacyManager_OptOutUseStandalone') }}</span> + </label> + </p> + + <div v-if="codeType === 'selfContained'"> + <div> + <Field + uicontrol="select" + name="language" + v-model="language" + :title="translate('General_Language')" + :options="languageOptions" + @keydown="updateCode()" + @change="updateCode()" + /> + </div> + </div> + + </div> + <div class="col s12 m6"> + <div class="form-help" v-html="$sanitize(codeTypeHelp)"> + </div> + </div> + </div> + </div> + + <div> + <pre v-select-on-focus="{}" ref="pre"> +{{ codeBox }} + </pre> + <p + v-html="$sanitize(optOutExplanationIntro)"> + </p> + <div class="system notification notification-info optOutTestReminder"> + <p> + <strong>{{ translate('PrivacyManager_OptOutRememberToTest') }}</strong> + </p> + <p> + {{ translate('PrivacyManager_OptOutRememberToTestBody') }} + </p> + <p> + <ul> + <li>{{ translate('PrivacyManager_OptOutRememberToTestStep1') }}</li> + <li>{{ translate('PrivacyManager_OptOutRememberToTestStep2') }}</li> + <li>{{ translate('PrivacyManager_OptOutRememberToTestStep3') }}</li> + <li>{{ translate('PrivacyManager_OptOutRememberToTestStep4') }}</li> + </ul> + </p> + </div> + <h3>{{ translate('PrivacyManager_BuildYourOwn') }}</h3> + <p + v-html="$sanitize(optOutCustomOptOutLink)"> + </p> + + </div> </template> <script lang="ts"> @@ -94,9 +208,13 @@ import { defineComponent } from 'vue'; import { translate, SelectOnFocus, - MatomoUrl, debounce, + MatomoUrl, + AjaxHelper, } from 'CoreHome'; +import { + Field, +} from 'CorePluginsAdmin'; interface OptOutCustomizerState { fontSizeUnit: string; @@ -104,6 +222,11 @@ interface OptOutCustomizerState { fontColor: string; fontSize: string; fontFamily: string; + showIntro: null|boolean; + applyStyling: boolean; + codeType: string; + code: string; + language: string; } function nearlyWhite(hex: string) { @@ -118,11 +241,18 @@ const { $ } = window; export default defineComponent({ props: { - language: { + currentLanguageCode: { type: String, required: true, }, - piwikurl: String, + languageOptions: { + type: Object, + required: true, + }, + matomoUrl: String, + }, + components: { + Field, }, directives: { SelectOnFocus, @@ -130,10 +260,15 @@ export default defineComponent({ data(): OptOutCustomizerState { return { fontSizeUnit: 'px', - backgroundColor: '', - fontColor: '', - fontSize: '', - fontFamily: '', + backgroundColor: '#FFFFFF', + fontColor: '#000000', + fontSize: '12', + fontFamily: 'Arial', + showIntro: true, + applyStyling: false, + codeType: 'tracker', + code: '', + language: this.currentLanguageCode, }; }, created() { @@ -142,26 +277,54 @@ export default defineComponent({ this.onFontSizeChange = debounce(this.onFontSizeChange, 50); this.onFontSizeUnitChange = debounce(this.onFontSizeUnitChange, 50); this.onFontFamilyChange = debounce(this.onFontFamilyChange, 50); + + if (this.matomoUrl) { + this.updateCode(); + } }, methods: { onFontColorChange(event: Event) { this.fontColor = (event.target as HTMLInputElement).value; + this.updateCode(); }, onBgColorChange(event: Event) { this.backgroundColor = (event.target as HTMLInputElement).value; + this.updateCode(); }, onFontSizeChange(event: Event) { this.fontSize = (event.target as HTMLInputElement).value; + this.updateCode(); }, onFontSizeUnitChange(event: Event) { this.fontSizeUnit = (event.target as HTMLInputElement).value; + this.updateCode(); }, onFontFamilyChange(event: Event) { this.fontFamily = (event.target as HTMLInputElement).value; + this.updateCode(); + }, + updateCode() { + let methodName = 'CoreAdminHome.getOptOutJSEmbedCode'; + if (this.codeType === 'selfContained') { + methodName = 'CoreAdminHome.getOptOutSelfContainedEmbedCode'; + } + AjaxHelper.fetch({ + method: methodName, + backgroundColor: this.backgroundColor.substr(1), + fontColor: this.fontColor.substr(1), + fontSize: this.fontSizeWithUnit, + fontFamily: this.fontFamily, + showIntro: (this.showIntro === true ? 1 : 0), + applyStyling: (this.applyStyling === true ? 1 : 0), + matomoUrl: this.matomoUrl, + language: (this.codeType === 'selfContained' ? this.language : 'auto'), + }).then((data) => { + this.code = data.value || ''; + }); }, }, watch: { - iframeUrl() { + codeBox() { const pre = this.$refs.pre as HTMLElement; const isAnimationAlreadyRunning = $(pre).queue('fx').length > 0; if (!isAnimationAlreadyRunning) { @@ -178,28 +341,31 @@ export default defineComponent({ return ''; }, withBg(): boolean { - return !!this.piwikurl + return !!this.matomoUrl && this.backgroundColor === '' && this.fontColor !== '' && nearlyWhite(this.fontColor.slice(1)); }, - iframeUrl(): string { - if (this.piwikurl) { - const query = MatomoUrl.stringify({ - module: 'CoreAdminHome', - action: 'optOut', - language: this.language, - backgroundColor: this.backgroundColor.slice(1), - fontColor: this.fontColor.slice(1), - fontSize: this.fontSizeWithUnit, - fontFamily: this.fontFamily, - }); - - return `${this.piwikurl}index.php?${query}`; + codeBox(): string { + if (this.matomoUrl) { + return this.code; } - return ''; }, + iframeUrl(): string { + const query = MatomoUrl.stringify({ + module: 'CoreAdminHome', + action: 'optOut', + language: this.language, + backgroundColor: this.backgroundColor.substr(1), + fontColor: this.fontColor.substr(1), + fontSize: this.fontSizeWithUnit, + fontFamily: this.fontFamily, + applyStyling: (this.applyStyling === true ? 1 : 0), + showIntro: (this.showIntro === true ? 1 : 0), + }); + return `${this.matomoUrl}index.php?${query}`; + }, readThisToLearnMore() { const link = 'https://matomo.org/faq/how-to/faq_25918/'; return translate( @@ -215,6 +381,17 @@ export default defineComponent({ '</a>', ); }, + optOutCustomOptOutLink() { + const link = 'https://developer.matomo.org/guides/tracking-javascript-guide#optional-creating-a-custom-opt-out-form'; + return translate( + 'CoreAdminHome_OptOutCustomOptOutLink', + `<a href="${link}" rel="noreferrer noopener" target="_blank">`, + '</a>', + ); + }, + codeTypeHelp() { + return translate('PrivacyManager_OptOutCodeTypeExplanation'); + }, }, }); </script> |