Skip to content
Snippets Groups Projects
Commit a8c45057 authored by Neuber, Eugen Ramon's avatar Neuber, Eugen Ramon :speech_balloon:
Browse files

Working version (ugly) - WIP

See issue #29
parent 630c35d4
No related branches found
No related tags found
1 merge request!2Matomo web component
Pipeline #12974 failed
# Matomo Web Component # Matomo Web Component
[GitLab Repository](https://gitlab.tugraz.at/dbp/web-components/Matomo) [GitLab Repository](git@gitlab.tugraz.at:dbp/web-components/toolkit.git)
## Usage ## Usage
...@@ -10,27 +10,35 @@ ...@@ -10,27 +10,35 @@
## Attributes ## Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English - `endpoint` (required): set to your *Matomo* server
- example `<dbp-notification lang="de" client-id="my-client-id"></dbp-notification>` - example `<dbp-matomo endpoint="https://my-matomo.tld"></dbp-matomo>`
- `site-id` (required): set to your site id
- example `<dbp-matomo site-id="456789"></dbp-matomo>`
## Sending notifications ## Tracking actions
```javascript ```javascript
import { send } from './notification'; class Demo {
send({ track(action, message) {
"summary": "Item deleted", const matomo = this.shadowRoot.querySelector(this.constructor.getScopedTagName('dbp-matomo'));
"body": "Item foo was deleted!", if (matomo !== null) {
"type": "info", matomo.track(action, message);
"timeout": 5, }
}); }
clickMe() {
this.track('button clicked', 'alert()');
}
}
``` ```
## Local development ## Local development
```bash ```bash
# get the source # get the source
git clone git@gitlab.tugraz.at:dbp/ git clone git@gitlab.tugraz.at:dbp/web-components/toolkit.git
cd toolkit/packages/matomo cd toolkit/packages/matomo
git submodule update --init git submodule update --init
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^14.0.0", "@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-node-resolve": "^8.1.0",
"@rollup/plugin-url": "^5.0.1", "@rollup/plugin-url": "^5.0.1",
"chai": "^4.2.0", "chai": "^4.2.0",
"i18next-scanner": "^2.10.2", "i18next-scanner": "^2.10.2",
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
"build-demo": "rollup -c --environment BUILD:demo", "build-demo": "rollup -c --environment BUILD:demo",
"build-test": "rollup -c --environment BUILD:test", "build-test": "rollup -c --environment BUILD:test",
"i18next": "i18next-scanner", "i18next": "i18next-scanner",
"watch": "yarn run watch-local", "watch": "npm run watch-local",
"watch-local": "rollup -c --watch", "watch-local": "rollup -c --watch",
"watch-dev": "rollup -c --watch --environment BUILD:development", "watch-dev": "rollup -c --watch --environment BUILD:development",
"test": "rollup -c --environment BUILD:test && karma start --singleRun" "test": "npm run build-test && karma start --singleRun"
} }
} }
...@@ -8,41 +8,55 @@ import serve from 'rollup-plugin-serve'; ...@@ -8,41 +8,55 @@ import serve from 'rollup-plugin-serve';
import url from "@rollup/plugin-url"; import url from "@rollup/plugin-url";
import consts from 'rollup-plugin-consts'; import consts from 'rollup-plugin-consts';
import del from 'rollup-plugin-delete'; import del from 'rollup-plugin-delete';
import {getPackagePath} from '../../rollup.utils.js';
const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
console.log("build: " + build); console.log("build: " + build);
export default { export default (async () => {
input: (build != 'test') ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] : glob.sync('test/**/*.js'), return {
output: { input: (build != 'test') ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] : glob.sync('test/**/*.js'),
dir: 'dist', output: {
entryFileNames: '[name].js', dir: 'dist',
chunkFileNames: 'shared/[name].[hash].[format].js', entryFileNames: '[name].js',
format: 'esm', chunkFileNames: 'shared/[name].[hash].[format].js',
sourcemap: true format: 'esm',
}, sourcemap: true
plugins: [ },
del({ onwarn: function (warning, warn) {
targets: 'dist/*' // keycloak bundled code uses eval
}), if (warning.code === 'EVAL') {
consts({ return;
environment: build, }
}), warn(warning);
resolve(), },
commonjs(), plugins: [
json(), del({
url({ targets: 'dist/*'
limit: 0, }),
emitFiles: true, consts({
fileName: 'shared/[name].[hash][extname]' environment: build,
}), }),
(build !== 'local' && build !== 'test') ? terser() : false, resolve(),
copy({ commonjs(),
targets: [ url({
{src: 'assets/index.html', dest: 'dist'}, limit: 0,
{src: 'assets/favicon.ico', dest: 'dist'}, include: [
] await getPackagePath('select2', '**/*.css'),
}), ],
(process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false emitFiles: true,
] fileName: 'shared/[name].[hash][extname]'
}; }),
json(),
(build !== 'local' && build !== 'test') ? terser() : false,
copy({
targets: [
{src: 'assets/index.html', dest: 'dist'},
{src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
{src: 'assets/favicon.ico', dest:'dist'},
],
}),
(process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
]
};
})();
\ No newline at end of file
...@@ -4,37 +4,46 @@ import {ScopedElementsMixin} from '@open-wc/scoped-elements'; ...@@ -4,37 +4,46 @@ import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import {AuthKeycloak, LoginButton} from 'dbp-auth'; import {AuthKeycloak, LoginButton} from 'dbp-auth';
import * as commonUtils from 'dbp-common/utils'; import * as commonUtils from 'dbp-common/utils';
import * as commonStyles from 'dbp-common/styles'; import * as commonStyles from 'dbp-common/styles';
import {MatomoElement} from './matomo';
class MatomoDemo extends LitElement { class MatomoDemo extends ScopedElementsMixin(LitElement) {
constructor() { constructor() {
super(); super();
this.lang = 'de'; this.lang = 'de';
this.noAuth = false;
} }
static get scopedElements() { static get scopedElements() {
return { return {
'dbp-auth-keycloak': AuthKeycloak, 'dbp-auth-keycloak': AuthKeycloak,
'dbp-login-button': LoginButton, 'dbp-login-button': LoginButton,
// 'dbp-person-select': PersonSelect, 'dbp-matomo': MatomoElement,
}; };
} }
static get properties() { static get properties() {
return { return {
lang: { type: String }, lang: { type: String },
noAuth: { type: Boolean, attribute: 'no-auth' },
}; };
} }
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
i18n.changeLanguage(this.lang); i18n.changeLanguage(this.lang);
}
track(action, message) {
const matomo = this.shadowRoot.querySelector(this.constructor.getScopedTagName('dbp-matomo'));
if (matomo !== null) {
matomo.track(action, message);
}
}
clickMe() {
this.track('button clicked', 'alert()');
this.updateComplete.then(()=>{ alert('button clicked!');
});
} }
static get styles() { static get styles() {
...@@ -44,20 +53,11 @@ class MatomoDemo extends LitElement { ...@@ -44,20 +53,11 @@ class MatomoDemo extends LitElement {
commonStyles.getGeneralCSS(), commonStyles.getGeneralCSS(),
css` css`
h1.title {margin-bottom: 1em;} h1.title {margin-bottom: 1em;}
div.container {margin-bottom: 1.5em;} div.container {margin-bottom: 1.5em; padding-left:20px;}
` `
]; ];
} }
getAuthComponentHtml() {
return this.noAuth ? html`` : html`
<div class="container">
<dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
</div>
`;
}
render() { render() {
return html` return html`
<section class="section"> <section class="section">
...@@ -71,7 +71,7 @@ class MatomoDemo extends LitElement { ...@@ -71,7 +71,7 @@ class MatomoDemo extends LitElement {
</div> </div>
<div class="container"> <div class="container">
<p>Click this button (and watch the network traffic) ...</p> <p>Click this button (and watch the network traffic) ...</p>
<p><input type="button" value="Fetch userinfo (see console)" @click="${this._onUserInfoClick}"></p> <p><input type="button" value="click me" @click="${this.clickMe}"></p>
</div> </div>
</section> </section>
`; `;
......
import * as commonUtils from 'dbp-common/utils'; import * as commonUtils from 'dbp-common/utils';
import {Matomo} from './matomo.js'; import {MatomoElement} from './matomo.js';
commonUtils.defineCustomElement('dbp-matomo', Matomo); commonUtils.defineCustomElement('dbp-matomo', MatomoElement);
import {Matomo} from './matomo.js';
export {Matomo};
\ No newline at end of file
import {i18n} from './i18n.js'; import {i18n} from './i18n.js';
import {html, css} from 'lit-element';
import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import * as commonStyles from 'dbp-common/styles';
import {LitElement} from "lit-element"; import {LitElement} from "lit-element";
import DBPLitElement from 'dbp-common/dbp-lit-element';
import {EventBus} from 'dbp-common'; import {EventBus} from 'dbp-common';
// import {LoginStatus} from './util.js';
export class Matomo extends ScopedElementsMixin(LitElement) {
export class MatomoElement extends DBPLitElement {
constructor() { constructor() {
super(); super();
this.lang = 'de';
// this._loginData = {};
this.endpoint = ''; this.endpoint = '';
this.siteId = -1; this.siteId = -1;
this.isRunning = false;
} }
static get scopedElements() {
return {
};
}
static get properties() { static get properties() {
return { return {
lang: { type: String },
// _loginData: { type: Object, attribute: false },
endpoint: { type: String }, endpoint: { type: String },
siteId: { type: Number, attribute: 'site-id' }, siteId: { type: Number, attribute: 'site-id' },
}; };
...@@ -36,8 +26,7 @@ export class Matomo extends ScopedElementsMixin(LitElement) { ...@@ -36,8 +26,7 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
this._bus = new EventBus(); this._bus = new EventBus();
this._bus.subscribe('auth-update', (data) => { this._bus.subscribe('auth-update', (data) => {
// this._loginData = data; this.setupMatomo(data.status === 'logged-in');
this.setupMatomo(data.status === LoginStatus.LOGGED_IN);
}); });
} }
...@@ -46,36 +35,36 @@ export class Matomo extends ScopedElementsMixin(LitElement) { ...@@ -46,36 +35,36 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
super.disconnectedCallback(); super.disconnectedCallback();
} }
render() {
update(changedProperties) { return ``;
changedProperties.forEach((oldValue, propName) => {
if (propName === "lang") {
i18n.changeLanguage(this.lang);
}
});
super.update(changedProperties);
} }
setupMatomo(loggedIn) {
console.log('setupMatomo: loggedIn = ' + loggedIn);
console.log('setupMatomo: running = ' + this.isRunning);
render() {} if (loggedIn && ! this.isRunning) {
console.log('add matomo...');
setupMatomo(loggedIn) { window._paq = window._paq || [];
if (loggedIn) {
var _paq = window._paq || [];
_paq.push(['setCustomVariable', 1, "GitCommit", "<%= buildInfo.info %>", "visit"]); _paq.push(['setCustomVariable', 1, "GitCommit", "<%= buildInfo.info %>", "visit"]);
_paq.push(['enableHeartBeatTimer']); _paq.push(['enableHeartBeatTimer']);
_paq.push(['disableCookies']); _paq.push(['disableCookies']);
_paq.push(['trackPageView']); _paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']); _paq.push(['enableLinkTracking']);
(function() { (function (endpoint, siteId) {
var u = this.endpoint; _paq.push(['setTrackerUrl', endpoint+'matomo.php']);
_paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', siteId]);
_paq.push(['setSiteId', this.siteId]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; var g = document.createElement('script');
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); var s = document.getElementsByTagName('script')[0];
})(); g.type = 'text/javascript';
g.async = true;
g.defer = true;
g.src = endpoint + 'matomo.js';
s.parentNode.insertBefore(g, s);
})(this.endpoint, this.siteId);
// track changed locations // track changed locations
window.addEventListener('locationchanged', function(e) { window.addEventListener('locationchanged', function(e) {
...@@ -96,8 +85,20 @@ export class Matomo extends ScopedElementsMixin(LitElement) { ...@@ -96,8 +85,20 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
_paq.push(['trackEvent', 'Error', e.error.message + '\n' + e.error.stack]); _paq.push(['trackEvent', 'Error', e.error.message + '\n' + e.error.stack]);
}); });
} else { this.isRunning = true;
return;
}
if (! loggedIn && this.isRunning) {
// TODO: reomve those event listeners // TODO: reomve those event listeners
console.log('remove matomo...');
this.isRunning = false;
}
}
track (action, message) {
console.log('MatomoElement (' +this.isRunning+'): ' + action + ', ' + message);
if (this.isRunning) {
_paq.push(['trackEvent', action, message]);
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment