From 8bc37838473962db3024d16ca6b76add1ff61b56 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Tue, 29 Dec 2020 18:37:58 +0200 Subject: [PATCH 1/4] Minor fixes to the user guide htmls --- user-guide/UserGuide_de.html | 4 ++-- user-guide/UserGuide_en.html | 4 ++-- user-guide/UserGuide_es.html | 4 ++-- user-guide/UserGuide_gr.html | 4 ++-- user-guide/UserGuide_sk.html | 4 ++-- user-guide/UserGuide_tr.html | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/user-guide/UserGuide_de.html b/user-guide/UserGuide_de.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_de.html +++ b/user-guide/UserGuide_de.html @@ -2047,7 +2047,7 @@

 

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      diff --git a/user-guide/UserGuide_en.html b/user-guide/UserGuide_en.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_en.html +++ b/user-guide/UserGuide_en.html @@ -2047,7 +2047,7 @@

       

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      diff --git a/user-guide/UserGuide_es.html b/user-guide/UserGuide_es.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_es.html +++ b/user-guide/UserGuide_es.html @@ -2047,7 +2047,7 @@

       

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      diff --git a/user-guide/UserGuide_gr.html b/user-guide/UserGuide_gr.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_gr.html +++ b/user-guide/UserGuide_gr.html @@ -2047,7 +2047,7 @@

       

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      diff --git a/user-guide/UserGuide_sk.html b/user-guide/UserGuide_sk.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_sk.html +++ b/user-guide/UserGuide_sk.html @@ -2047,7 +2047,7 @@

       

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      diff --git a/user-guide/UserGuide_tr.html b/user-guide/UserGuide_tr.html index 952c19e94..b64d4663e 100644 --- a/user-guide/UserGuide_tr.html +++ b/user-guide/UserGuide_tr.html @@ -2047,7 +2047,7 @@

       

  • -

    Navigation

    +

    Navigation

    1. @@ -2138,7 +2138,7 @@

      Main menu - logged in

       

      -

      +

       

      Home  - gets you back to the homepage / dashboard

       

      From cf478980074ce75f744a8c2b49b0899d2bc8ea07 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Wed, 30 Dec 2020 18:08:10 +0200 Subject: [PATCH 2/4] Improve support of the User guide Editor for the new User Guide htmls --- .../user-guide-editor.component.html | 11 ++++++++--- .../user-guide-editor/user-guide-editor.component.ts | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.html b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.html index 10e98c8db..9e1d78d76 100644 --- a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.html +++ b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.html @@ -11,13 +11,18 @@ menubar: true, plugins: [ 'advlist autolink lists link image charmap print preview anchor', - 'searchreplace visualblocks code fullscreen fullpage', - 'insertdatetime media table paste code help wordcount importcss' + 'searchreplace visualblocks fullscreen fullpage', + 'insertdatetime media table paste code help wordcount importcss ', + 'codesample toc visualchars' ], + extended_valid_elements: '*[*]', + forced_root_block: '', + valid_children: '+body[script],ol[li|div|p|a|ol|table],h2[span],h3[span]', + save_enablewhendirty: false, toolbar: 'undo redo | formatselect | bold italic backcolor | \ alignleft aligncenter alignright alignjustify | \ - bullist numlist outdent indent | code | preview | removeformat | help' + bullist numlist outdent indent | code codesample | searchreplace | preview | removeformat | help' }" formControlName="html"> diff --git a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts index 8222989ee..29936386e 100644 --- a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts +++ b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts @@ -67,7 +67,7 @@ export class UserGuideEditorComponent extends BaseComponent implements OnInit { reader.addEventListener('load', () => { let result = this.parseText(reader.result as string); result = result.replace(/class="href" path="/g, 'href="#'); - this.formGroup.get('html').patchValue(result); + this.formGroup.get('html').patchValue(result); }, false); reader.readAsText(data); } From 0367aa0431c37d6a794e62ff1eb9aa2d172bec6b Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 31 Dec 2020 16:30:35 +0200 Subject: [PATCH 3/4] Minor improvements --- dmp-frontend/src/app/ui/navbar/navbar.component.scss | 1 + .../app/ui/user-guide-editor/user-guide-editor.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.scss b/dmp-frontend/src/app/ui/navbar/navbar.component.scss index 0d3206b6a..c4515f9e4 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.scss +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.scss @@ -43,6 +43,7 @@ $mat-card-header-size: 40px !default; color: #000000; opacity: 1; cursor: pointer; + text-decoration: none !important; } .faq-title:hover, diff --git a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts index 29936386e..67a53a805 100644 --- a/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts +++ b/dmp-frontend/src/app/ui/user-guide-editor/user-guide-editor.component.ts @@ -66,7 +66,7 @@ export class UserGuideEditorComponent extends BaseComponent implements OnInit { const reader = new FileReader(); reader.addEventListener('load', () => { let result = this.parseText(reader.result as string); - result = result.replace(/class="href" path="/g, 'href="#'); + //result = result.replace(/class="href" path="/g, 'href="#'); this.formGroup.get('html').patchValue(result); }, false); reader.readAsText(data); @@ -74,7 +74,7 @@ export class UserGuideEditorComponent extends BaseComponent implements OnInit { submit() { let result = this.parseText(this.formGroup.get('html').value); - result = result.replace(/href="#/g, 'class="href" path="'); + //result = result.replace(/href="#/g, 'class="href" path="'); this.formGroup.get('html').patchValue(result); this.userGuideService.updateUserGuide(this.formGroup.value).pipe(takeUntil(this._destroyed)) .subscribe( From c56b7c59edcc0a50616811c94531a77334f97486 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 31 Dec 2020 16:34:36 +0200 Subject: [PATCH 4/4] Fix issue with images not loading on user-guide for local development builds (plus an optional innerHTML alternative (disabled by default)) --- .../user-guide-content.component.html | 9 +- .../user-guide-content.component.scss | 4 + .../user-guide-content.component.ts | 116 +++++++++++++++--- 3 files changed, 104 insertions(+), 25 deletions(-) diff --git a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.html b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.html index 325bbfb73..e795bc016 100644 --- a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.html +++ b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.html @@ -1,11 +1,6 @@ - -
      - + +
      diff --git a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.scss b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.scss index 847345f67..e14027d67 100644 --- a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.scss +++ b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.scss @@ -25,3 +25,7 @@ margin: 0px; border: none; } + +:host :hover ::ng-deep .tocElement { + cursor: pointer !important; +} diff --git a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts index ae21bbd20..b2f0ee14b 100644 --- a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts +++ b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts @@ -1,72 +1,152 @@ -import { Component, OnInit, AfterViewChecked } from '@angular/core'; +import { Component, OnInit, AfterViewChecked, ViewEncapsulation, ViewChild, AfterContentInit, AfterViewInit } from '@angular/core'; import { UserGuideService } from '@app/core/services/user-guide/user-guide.service'; import { BaseComponent } from '@common/base/base.component'; import { takeUntil } from 'rxjs/internal/operators/takeUntil'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { LanguageService } from '@app/core/services/language/language.service'; -import { SecurityContext } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { ElementRef } from '@angular/core'; +import { interval, Subject } from 'rxjs'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; @Component({ selector: 'app-user-guide-content', templateUrl: './user-guide-content.component.html', styleUrls: ['./user-guide-content.component.scss'] }) -export class UserGuideContentComponent extends BaseComponent implements OnInit, AfterViewChecked { - +export class UserGuideContentComponent extends BaseComponent implements OnInit { + readonly useInnerHTML: boolean = false; //GK: Change for TESTING PURPOSES ONLY guideHTML: any; guideHTMLUrl: SafeResourceUrl; sanitizedGuideUrl: any; private scrollEvent: EventListener; + private tocScrollEvent: EventListener; + private _transformed: Subject = new Subject(); + private _parsed: Subject = new Subject(); + + @ViewChild('guide', {static: false}) guide: ElementRef; constructor( private userGuideService: UserGuideService, private sanitizer: DomSanitizer, private languageService: LanguageService, private httpClient: HttpClient, - private matomoService: MatomoService + private matomoService: MatomoService, + private configurationService: ConfigurationService ) { super(); } ngOnInit() { this.matomoService.trackPageView('User Guide Content'); this.scrollEvent = ((ev) => this.scroll(ev)); + this.tocScrollEvent = ((ev) => { + this.activeToc(ev); + this.scroll(ev); + }); this.userGuideService.getUserGuide(this.languageService.getCurrentLanguage()) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' }); - this.readBlob(blob); - this.guideHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); + if (this.useInnerHTML) { + this.readBlob(blob); + } else { + this.guideHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); + //GK: In case the app is in localhost (dev/debug build) apply the following transformation + //in order to show the user guide's images + if (this.guideHTMLUrl && this.configurationService.app.includes('localhost')) { + interval(1000).pipe(takeUntil(this._transformed)).subscribe(() => this.transform()); + } + } + + // this.guideHTML = this.sanitizer.sanitize(SecurityContext.HTML, blob); // this.sanitizedGuideUrl = this.sanitizer.sanitize(SecurityContext.URL, this.guideHTMLUrl); // console.log(this.guideHTMLUrl); }); } - ngAfterViewChecked(): void { - this.parse(); - } - readBlob(blob: Blob) { const fr = new FileReader(); fr.onload = ev => { - this.guideHTML = this.sanitizer.bypassSecurityTrustHtml(fr.result as string); - this.parse(); + const HTMLstring = fr.result as string; + this.guideHTML = this.sanitizer.bypassSecurityTrustHtml(HTMLstring); + this.addScripts(HTMLstring); + if (this.guideHTML) { + interval(1000).pipe(takeUntil(this._transformed)).subscribe(() => this.transform()); + interval(1000).pipe(takeUntil(this._parsed)).subscribe(() => this.parse()); + } }; fr.readAsText(blob); } + activeToc(ev: Event) { + const current = document.getElementsByClassName('active'); + if (current.length > 0) { + current[0].classList.remove('active'); + } + (ev.currentTarget as Element).classList.add('active'); + } + scroll(ev: Event) { - document.getElementById((ev.srcElement as any).getAttribute('path')).scrollIntoView({ behavior: 'smooth', block: 'start' }); + document.getElementById((ev.currentTarget as Element).getAttribute('path')).scrollIntoView({ behavior: 'smooth', block: 'start' }); } private parse() { - const specialElements: HTMLCollection = document.getElementsByClassName('href'); + const specialElements: HTMLCollection = document.getElementsByTagName('a'); for (let i = 0; i < specialElements.length; i++) { - const element = specialElements.item(i); - element.removeEventListener('click', this.scrollEvent); - element.addEventListener('click', this.scrollEvent); + const element = specialElements.item(i) as HTMLAnchorElement; + if(element.href.includes('#')) { + this.hrefToPath(element); + element.removeEventListener('click', this.scrollEvent); + element.addEventListener('click', this.scrollEvent); + } + if (!this._parsed.isStopped) { + this._parsed.next(true); + this._parsed.complete(); + } + } + + } + + private addScripts(HTMLString: string) { + const fragment = document.createRange().createContextualFragment(HTMLString); + this.guide.nativeElement.appendChild(fragment); + } + + transform() { + if (this.useInnerHTML) { + const tocElements = document.getElementsByClassName('nav-link'); + for (let i = 0; i < tocElements.length; i++) { + const href = (tocElements[i] as HTMLAnchorElement).href; + if (href.includes('#')) { + this.hrefToPath(tocElements[i] as HTMLAnchorElement); + tocElements[i].addEventListener('click', this.tocScrollEvent); + tocElements[i].classList.add('tocElement'); + if (!this._transformed.isStopped) { + this._transformed.next(true); + this._transformed.complete(); + } + } + } + } else { + const userguide = document.getElementById('userguide') as HTMLIFrameElement; + const images = userguide.contentWindow.document.getElementsByTagName('img'); + for (let i = 0; i < images.length; i++) { + const image = images[i]; + image.src = `${this.configurationService.app}${image.src}`; + if (!this._transformed.isStopped) { + this._transformed.next(true); + this._transformed.complete(); + } + } } } + private hrefToPath(element: HTMLAnchorElement) { + const href = element.href; + const hashtagIndex = href.lastIndexOf('#'); + element.removeAttribute('href'); + element.setAttribute('path', href.slice(hashtagIndex + 1)); + } + }