From a8c450571b88156e4e3e12fe51f2e8d6057f8753 Mon Sep 17 00:00:00 2001
From: Eugen Neuber <eugen.neuber@tugraz.at>
Date: Mon, 14 Sep 2020 11:50:40 +0200
Subject: [PATCH] Working version (ugly) - WIP

See issue #29
---
 packages/matomo/README.md              | 34 +++++++----
 packages/matomo/package.json           |  6 +-
 packages/matomo/rollup.config.js       | 82 +++++++++++++++-----------
 packages/matomo/src/dbp-matomo-demo.js | 34 +++++------
 packages/matomo/src/dbp-matomo.js      |  4 +-
 packages/matomo/src/index.js           |  3 +
 packages/matomo/src/matomo.js          | 75 +++++++++++------------
 7 files changed, 132 insertions(+), 106 deletions(-)
 create mode 100644 packages/matomo/src/index.js

diff --git a/packages/matomo/README.md b/packages/matomo/README.md
index 9593f14e..7ecd7492 100644
--- a/packages/matomo/README.md
+++ b/packages/matomo/README.md
@@ -1,6 +1,6 @@
 # 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
 
@@ -10,27 +10,35 @@
 
 ## Attributes
 
-- `lang` (optional, default: `de`): set to `de` or `en` for German or English
-    - example `<dbp-notification lang="de" client-id="my-client-id"></dbp-notification>`
+- `endpoint` (required): set to your *Matomo* server
+    - 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
-import { send } from './notification';
-
-send({
-    "summary": "Item deleted",
-    "body": "Item foo was deleted!",
-    "type": "info",
-    "timeout": 5,
-});
+class Demo {
+
+    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()');
+    }
+
+}
 ``` 
 
 ## Local development
 
 ```bash
 # 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
 git submodule update --init
 
diff --git a/packages/matomo/package.json b/packages/matomo/package.json
index d884e765..5bb652ef 100644
--- a/packages/matomo/package.json
+++ b/packages/matomo/package.json
@@ -7,7 +7,7 @@
   "devDependencies": {
     "@rollup/plugin-commonjs": "^14.0.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",
     "chai": "^4.2.0",
     "i18next-scanner": "^2.10.2",
@@ -39,9 +39,9 @@
     "build-demo": "rollup -c --environment BUILD:demo",
     "build-test": "rollup -c --environment BUILD:test",
     "i18next": "i18next-scanner",
-    "watch": "yarn run watch-local",
+    "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "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"
   }
 }
diff --git a/packages/matomo/rollup.config.js b/packages/matomo/rollup.config.js
index d12edb2c..71369f40 100644
--- a/packages/matomo/rollup.config.js
+++ b/packages/matomo/rollup.config.js
@@ -8,41 +8,55 @@ import serve from 'rollup-plugin-serve';
 import url from "@rollup/plugin-url";
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-export default {
-    input: (build != 'test') ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        url({
-            limit: 0,
-            emitFiles: true,
-            fileName: 'shared/[name].[hash][extname]'
-        }),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'assets/favicon.ico', dest: 'dist'},
-            ]
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+                return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            url({
+                limit: 0,
+                include: [
+                    await getPackagePath('select2', '**/*.css'),
+                ],
+                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
diff --git a/packages/matomo/src/dbp-matomo-demo.js b/packages/matomo/src/dbp-matomo-demo.js
index bf383ff0..71af83e0 100644
--- a/packages/matomo/src/dbp-matomo-demo.js
+++ b/packages/matomo/src/dbp-matomo-demo.js
@@ -4,37 +4,46 @@ import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import {AuthKeycloak, LoginButton} from 'dbp-auth';
 import * as commonUtils from 'dbp-common/utils';
 import * as commonStyles from 'dbp-common/styles';
+import {MatomoElement} from './matomo';
 
 
-class MatomoDemo extends LitElement {
+class MatomoDemo extends ScopedElementsMixin(LitElement) {
 
     constructor() {
         super();
         this.lang = 'de';
-        this.noAuth = false;
     }
 
     static get scopedElements() {
         return {
             'dbp-auth-keycloak': AuthKeycloak,
             'dbp-login-button': LoginButton,
-            // 'dbp-person-select': PersonSelect,
+            'dbp-matomo': MatomoElement,
         };
     }
 
     static get properties() {
         return {
             lang: { type: String },
-            noAuth: { type: Boolean, attribute: 'no-auth' },
         };
     }
 
     connectedCallback() {
         super.connectedCallback();
         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() {
@@ -44,20 +53,11 @@ class MatomoDemo extends LitElement {
             commonStyles.getGeneralCSS(),
             css`
             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() {
         return html`
             <section class="section">
@@ -71,7 +71,7 @@ class MatomoDemo extends LitElement {
                 </div>
                 <div class="container">
                     <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>
             </section>
         `;
diff --git a/packages/matomo/src/dbp-matomo.js b/packages/matomo/src/dbp-matomo.js
index e2930723..34ca672c 100644
--- a/packages/matomo/src/dbp-matomo.js
+++ b/packages/matomo/src/dbp-matomo.js
@@ -1,4 +1,4 @@
 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);
diff --git a/packages/matomo/src/index.js b/packages/matomo/src/index.js
new file mode 100644
index 00000000..fca22596
--- /dev/null
+++ b/packages/matomo/src/index.js
@@ -0,0 +1,3 @@
+import {Matomo} from './matomo.js';
+
+export {Matomo};
\ No newline at end of file
diff --git a/packages/matomo/src/matomo.js b/packages/matomo/src/matomo.js
index bc917333..030f0a54 100644
--- a/packages/matomo/src/matomo.js
+++ b/packages/matomo/src/matomo.js
@@ -1,31 +1,21 @@
 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 DBPLitElement from 'dbp-common/dbp-lit-element';
 import {EventBus} from 'dbp-common';
-// import {LoginStatus} from './util.js';
 
-export class Matomo extends ScopedElementsMixin(LitElement) {
+
+export class MatomoElement extends DBPLitElement {
 
     constructor() {
         super();
-        this.lang = 'de';
-        // this._loginData = {};
         this.endpoint = '';
         this.siteId = -1;
+        this.isRunning = false;
     }
 
-    static get scopedElements() {
-        return {
-        };
-    }
 
     static get properties() {
         return {
-            lang: { type: String },
-            // _loginData: { type: Object, attribute: false },
             endpoint: { type: String },
             siteId: { type: Number, attribute: 'site-id' },
         };
@@ -36,8 +26,7 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
 
         this._bus = new EventBus();
         this._bus.subscribe('auth-update', (data) => {
-            // this._loginData = data;
-            this.setupMatomo(data.status === LoginStatus.LOGGED_IN);
+            this.setupMatomo(data.status === 'logged-in');
         });
     }
 
@@ -46,36 +35,36 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
         super.disconnectedCallback();
     }
 
-
-    update(changedProperties) {
-        changedProperties.forEach((oldValue, propName) => {
-            if (propName === "lang") {
-                i18n.changeLanguage(this.lang);
-            }
-        });
-
-        super.update(changedProperties);
+    render() {
+        return ``;
     }
 
+    setupMatomo(loggedIn) {
+        console.log('setupMatomo: loggedIn = ' + loggedIn);
+        console.log('setupMatomo: running = ' + this.isRunning);
 
-    render() {}
+        if (loggedIn && ! this.isRunning) {
+            console.log('add matomo...');
 
-    setupMatomo(loggedIn) {
-        if (loggedIn) {
-            var _paq = window._paq || [];
+            window._paq = window._paq || [];
             _paq.push(['setCustomVariable', 1, "GitCommit", "<%= buildInfo.info %>", "visit"]);
             _paq.push(['enableHeartBeatTimer']);
             _paq.push(['disableCookies']);
             _paq.push(['trackPageView']);
             _paq.push(['enableLinkTracking']);
 
-            (function() {
-                var u = this.endpoint;
-                _paq.push(['setTrackerUrl', u+'matomo.php']);
-                _paq.push(['setSiteId', this.siteId]);
-                var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
-                g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
-            })();
+            (function (endpoint, siteId) {
+                _paq.push(['setTrackerUrl', endpoint+'matomo.php']);
+                _paq.push(['setSiteId', siteId]);
+
+                var g = document.createElement('script');
+                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
             window.addEventListener('locationchanged', function(e) {
@@ -96,8 +85,20 @@ export class Matomo extends ScopedElementsMixin(LitElement) {
                 _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
+            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]);
         }
     }
 }
-- 
GitLab