Commit 5139f590 authored by FORESTIER Fabien's avatar FORESTIER Fabien
Browse files

Add copy link button on articles, add custom event tracking

parent b4902c36
Pipeline #1808 passed with stages
in 5 minutes and 40 seconds
{
"name": "webapp",
"version": "2.3.1",
"version": "2.3.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -1418,6 +1418,7 @@
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"dev": true,
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
......@@ -2673,7 +2674,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
"dev": true,
"optional": true
},
"constants-browserify": {
"version": "1.0.0",
......@@ -3068,7 +3070,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"dev": true
"dev": true,
"optional": true
},
"depd": {
"version": "1.1.2",
......@@ -4127,7 +4130,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
......@@ -4148,12 +4152,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
......@@ -4168,17 +4174,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
......@@ -4295,7 +4304,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
......@@ -4307,6 +4317,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -4321,6 +4332,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
......@@ -4328,12 +4340,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
......@@ -4352,6 +4366,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
......@@ -4432,7 +4447,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
......@@ -4444,6 +4460,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
......@@ -4529,7 +4546,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
......@@ -4565,6 +4583,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......@@ -4584,6 +4603,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
......@@ -4627,12 +4647,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
......@@ -4641,6 +4663,7 @@
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
......@@ -4653,6 +4676,7 @@
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"dev": true,
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
......@@ -4669,6 +4693,7 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -4678,6 +4703,7 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......@@ -4717,7 +4743,8 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
"dev": true
"dev": true,
"optional": true
},
"get-stream": {
"version": "3.0.0",
......@@ -4965,7 +4992,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
"dev": true,
"optional": true
},
"has-value": {
"version": "1.0.0",
......@@ -6400,6 +6428,7 @@
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"parse-json": "^2.2.0",
......@@ -6412,7 +6441,8 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
"dev": true,
"optional": true
}
}
},
......@@ -6683,7 +6713,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"dev": true
"dev": true,
"optional": true
},
"map-visit": {
"version": "1.0.0",
......@@ -7385,6 +7416,7 @@
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"dev": true,
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
......@@ -8556,6 +8588,7 @@
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
"dev": true,
"optional": true,
"requires": {
"load-json-file": "^1.0.0",
"normalize-package-data": "^2.3.2",
......@@ -8567,6 +8600,7 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"pify": "^2.0.0",
......@@ -8577,7 +8611,8 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
"dev": true,
"optional": true
}
}
},
......@@ -8586,6 +8621,7 @@
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
"dev": true,
"optional": true,
"requires": {
"find-up": "^1.0.0",
"read-pkg": "^1.0.0"
......@@ -8596,6 +8632,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"dev": true,
"optional": true,
"requires": {
"path-exists": "^2.0.0",
"pinkie-promise": "^2.0.0"
......@@ -8606,6 +8643,7 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"dev": true,
"optional": true,
"requires": {
"pinkie-promise": "^2.0.0"
}
......@@ -11678,6 +11716,7 @@
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"dev": true,
"optional": true,
"requires": {
"string-width": "^1.0.2 || 2"
}
......
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { AppRoutes } from '../../../../routes';
import { DatasetResearchService } from '../../../../geosource/services';
import { Router, NavigationEnd } from '@angular/router';
import { UserService } from '../../../../user/services';
import { AppStateService } from '../../../services';
import { Angulartics2Piwik } from 'angulartics2/piwik';
@Component({
selector: 'app-header',
......@@ -23,6 +24,7 @@ export class HeaderComponent implements OnInit {
private _router: Router,
private _userService: UserService,
private _appStateService: AppStateService,
private _angulartics2Piwik: Angulartics2Piwik,
) { }
ngOnInit() {
......@@ -48,6 +50,7 @@ export class HeaderComponent implements OnInit {
toggleBurger() {
this.isBurgerActive = !this.isBurgerActive;
this._appStateService.changeMenuState(this.isBurgerActive);
this._angulartics2Piwik.eventTrack('BurgerMenu', { category: 'Navigation', label: 'BurgerManu', value: 1 });
}
toggleUserDropdown() {
......
......@@ -22,6 +22,7 @@ export class CMSPostDetailComponent implements OnInit {
safePostContent: SafeHtml;
pageHeaderInfo: IPageHeaderInfo = {
title: '',
hasCopyLinkBtn: true,
};
relations: {
datasetsMetadata: Metadata[];
......
......@@ -15,7 +15,7 @@
</div>
<div class="search column is-7-desktop is-8-tablet ">
<app-search-bar class="app-search-bar"></app-search-bar>
<a class="explore-link" [routerLink]="['/', AppRoutes.research.uri]">
<a class="explore-link" [routerLink]="['/', AppRoutes.research.uri]" (click)="trackExploreButtonEvent()">
<button class="button explore-button" i18n="@@home.explore">Explore</button>
</a>
</div>
......
......@@ -9,6 +9,7 @@ import { forkJoin } from 'rxjs/internal/observable/forkJoin';
import { NotificationService } from '../../../core/services';
import { Notification } from '../../../core/models';
import { notificationMessages } from '../../../../i18n/traductions';
import { Angulartics2Piwik } from 'angulartics2/piwik';
@Component({
selector: 'app-home',
......@@ -34,6 +35,7 @@ export class HomeComponent implements OnInit {
private _datasetResearchService: DatasetResearchService,
private _notificationService: NotificationService,
private _router: Router,
private _angulartics2Piwik: Angulartics2Piwik,
) { }
ngOnInit() {
......@@ -100,4 +102,7 @@ export class HomeComponent implements OnInit {
this._router.navigate(['/', AppRoutes.research.uri]);
}
trackExploreButtonEvent() {
this._angulartics2Piwik.eventTrack('ExploreButton', { category: 'HomePage', label: 'Explore', value: 1 });
}
}
......@@ -17,4 +17,13 @@
<span>{{ pageInfo.subtitle }}</span>
</div>
</div>
<button *ngIf="pageInfo.hasCopyLinkBtn" class="button copy-link-button has-tooltip-left tooltip" type="button"
(click)="copyToClipboard()" [attr.data-tooltip]="messageClipboard">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20">
<path fill="#818080" fill-rule="evenodd"
d="M1.852 7.777a2.619 2.619 0 0 1 0-3.703l2.222-2.222a2.619 2.619 0 0 1 3.704 0l2.963 2.963a2.619 2.619 0 0 1 0 3.703l-.37.37.74.741.37-.37a2.619 2.619 0 0 1 3.704 0l2.963 2.963a2.619 2.619 0 0 1 0 3.704l-2.222 2.222a2.619 2.619 0 0 1-3.704 0L9.26 15.185a2.619 2.619 0 0 1 0-3.704l.37-.37-.74-.741-.37.37a2.619 2.619 0 0 1-3.704 0L1.852 7.777zm7.037-.37l-.74-.74a1.048 1.048 0 0 0-1.482 1.48l.74.742-.37.37a.524.524 0 0 1-.74 0L3.332 6.296a.524.524 0 0 1 0-.74l2.223-2.223a.524.524 0 0 1 .74 0L9.26 6.296a.524.524 0 0 1 0 .74l-.37.371zm2.222 5.185l-.37.37a.524.524 0 0 0 0 .742l2.963 2.962a.524.524 0 0 0 .74 0l2.223-2.222a.524.524 0 0 0 0-.74l-2.963-2.963a.524.524 0 0 0-.741 0l-.37.37.74.74a1.047 1.047 0 1 1-1.481 1.482l-.74-.74z"
clip-rule="evenodd" />
</svg>
</button>
</div>
\ No newline at end of file
......@@ -96,3 +96,12 @@
line-height: 1.15;
color: $brand-color;
}
.copy-link-button {
position: absolute;
top: 10px;
right: 10px;
padding: 0;
height: 2.25rem;
width: 2.25rem;
}
\ No newline at end of file
......@@ -3,6 +3,9 @@ import { Router } from '@angular/router';
import { AppRoutes } from '../../../routes';
import { NavigationHistoryService } from '../../../core/services';
import { IPageHeaderInfo } from '../../models';
import { buttonCopyLinkToCliboardMessages } from '../../../../i18n/traductions';
import { Angulartics2Piwik } from 'angulartics2/piwik';
@Component({
selector: 'app-page-header',
......@@ -14,10 +17,12 @@ export class PageHeaderComponent implements OnInit {
constructor(
private _navigationHistoryService: NavigationHistoryService,
private _router: Router,
private _angulartics2Piwik: Angulartics2Piwik,
) { }
@Input() pageInfo: IPageHeaderInfo;
@Input() customGoToPreviousPage: any;
messageClipboard: string = buttonCopyLinkToCliboardMessages.hover;
ngOnInit() {
}
......@@ -36,4 +41,32 @@ export class PageHeaderComponent implements OnInit {
}
}
copyToClipboard() {
const el = document.createElement('input'); // Create a <input> element
el.value = window.location.href; // Set its value to the string that you want copied
el.setAttribute('readonly', ''); // Make it readonly to be tamper-proof
el.style.position = 'absolute';
el.style.left = '-9999px'; // Move outside the screen to make it invisible
document.body.appendChild(el); // Append the <input> element to the HTML document
const selected =
document.getSelection().rangeCount > 0 // Check if there is any content selected previously
? document.getSelection().getRangeAt(0) // Store selection if found
: false; // Mark as false to know no selection existed before
el.select(); // Select the <input> content
document.execCommand('copy'); // Copy - only works as a result of a user action (e.g. click events)
document.body.removeChild(el); // Remove the <input> element
if (selected) { // If a selection existed before copying
document.getSelection().removeAllRanges(); // Unselect everything on the HTML document
document.getSelection().addRange(selected); // Restore the original selection
}
this.messageClipboard = buttonCopyLinkToCliboardMessages.copied;
this._angulartics2Piwik.eventTrack('ShareArticle', { category: 'Edito', label: window.location.href, value: 1});
setTimeout(() => {
this.messageClipboard = buttonCopyLinkToCliboardMessages.hover;
// tslint:disable-next-line:align
}, 2000);
}
}
......@@ -4,6 +4,7 @@ export interface IPageHeaderInfo {
surtitle?: string;
subtitle?: string;
hasBetaStyle?: boolean;
hasCopyLinkBtn?: boolean
}
export interface ICMSPageLinks {
......
......@@ -308,3 +308,8 @@ export const reusesTypes = {
web: 'Site web',
article: 'Article',
};
export const buttonCopyLinkToCliboardMessages = {
hover: 'Copier le lien',
copied: 'Copié !'
};
......@@ -308,3 +308,8 @@ export const reusesTypes = {
web: 'Website',
article: 'Article',
};
export const buttonCopyLinkToCliboardMessages = {
hover: 'Copy the link',
copied: 'Copied!'
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment