This is an automated email from the ASF dual-hosted git repository. zjffdu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new 6a122cc [ZEPPELIN-4552] Support scroll to the paragraph specified by the url param 6a122cc is described below commit 6a122cceeb7d7804e0fa2ea2ce5082cfcf9c215e Author: vthinkxie <yadong....@alibaba-inc.com> AuthorDate: Thu Jan 16 12:47:00 2020 +0800 [ZEPPELIN-4552] Support scroll to the paragraph specified by the url param ### What is this PR for? Support scroll to the paragraph specified by the url param ### What type of PR is it? [Feature] ### Todos * [ ] - Task ### What is the Jira issue? [ZEPPELIN-4552] ### How should this be tested? https://travis-ci.org/vthinkxie/zeppelin/builds/637914933 ### Screenshots (if appropriate) <img width="1486" alt="截屏2020-01-19下午4 01 47" src="https://user-images.githubusercontent.com/1506722/72677223-08e6a600-3ad5-11ea-887a-7acdfb054401.png"> ### Questions: * Does the licenses files need update? no * Is there breaking changes for older versions? no * Does this needs documentation? no Author: vthinkxie <yadong....@alibaba-inc.com> Closes #3601 from vthinkxie/ZEPPELIN-4552 and squashes the following commits: 4922e93a3 [vthinkxie] [ZEPPELIN-4552] Support scroll to the paragraph specified by the url param --- .../result-item/result-item.component.html | 2 +- .../result-item/result-item.component.ts | 23 +++++++++++----- .../workspace/notebook/notebook.component.html | 1 + .../pages/workspace/notebook/notebook.component.ts | 17 +++++++++++- .../notebook/paragraph/paragraph.component.ts | 31 +++++++++++++++------- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.html b/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.html index dcd78dc..14d6ee6 100644 --- a/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.html +++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.html @@ -12,7 +12,7 @@ <nz-card [nzTitle]="titleTemplateRef"> <ng-template #titleTemplateRef> - <a [routerLink]="routerLink">{{displayName}}</a> + <a [routerLink]="routerLink" [queryParams]="queryParams">{{displayName}}</a> </ng-template> <zeppelin-code-editor [style.height.px]="height" diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.ts index e911a66..67eabe6 100644 --- a/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.ts +++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-search/result-item/result-item.component.ts @@ -20,6 +20,7 @@ import { OnDestroy, SimpleChanges } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { NotebookSearchResultItem } from '@zeppelin/interfaces'; import { getKeywordPositions, KeywordPosition } from '@zeppelin/utility/get-keyword-positions'; import { editor, Range } from 'monaco-editor'; @@ -34,9 +35,9 @@ import IStandaloneCodeEditor = editor.IStandaloneCodeEditor; }) export class NotebookSearchResultItemComponent implements OnChanges, OnDestroy { @Input() result: NotebookSearchResultItem; - + queryParams = {}; displayName = ''; - routerLink = ''; + routerLink = []; mergedStr: string; keywords: string[] = []; highlightPositions: KeywordPosition[] = []; @@ -54,13 +55,23 @@ export class NotebookSearchResultItemComponent implements OnChanges, OnDestroy { contextmenu: false }; - constructor(private ngZone: NgZone, private cdr: ChangeDetectorRef) {} + constructor(private ngZone: NgZone, private cdr: ChangeDetectorRef, private router: ActivatedRoute) {} setDisplayNameAndRouterLink(): void { - const noteId = this.result.id.split('/', 2)[0]; + const term = this.router.snapshot.params.queryStr; + const listOfId = this.result.id.split('/'); + const [noteId, hasParagraph, paragraph] = listOfId; + if (!hasParagraph) { + this.routerLink = ['/', 'notebook', this.result.id]; + this.queryParams = {}; + } else { + this.routerLink = ['/', 'notebook', noteId]; + this.queryParams = { + paragraph, + term + }; + } this.displayName = this.result.name ? this.result.name : `Note ${noteId}`; - - this.routerLink = `/notebook/${noteId}`; } setHighlightKeyword(): void { diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.html b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.html index d9574db..b204c86 100644 --- a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.html +++ b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.html @@ -47,6 +47,7 @@ *ngFor="let p of note.paragraphs;let first = first; let last = last; index as i" [nzSpan]="p.config.colWidth * 2" [select]="p.id === selectId" + [scrolled]="p.id === scrolledId" [index]="i" [paragraph]="p" [note]="note" diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts index 0ca7546..9a0ecc9 100644 --- a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts +++ b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts @@ -22,7 +22,7 @@ import { import { ActivatedRoute, Router } from '@angular/router'; import { isNil } from 'lodash'; import { Subject } from 'rxjs'; -import { distinctUntilKeyChanged, takeUntil } from 'rxjs/operators'; +import { distinctUntilKeyChanged, map, startWith, takeUntil } from 'rxjs/operators'; import { MessageListener, MessageListenersManager } from '@zeppelin/core'; import { Permissions } from '@zeppelin/interfaces'; @@ -58,6 +58,7 @@ export class NotebookComponent extends MessageListenersManager implements OnInit note: Note['note']; permissions: Permissions; selectId: string | null = null; + scrolledId: string | null = null; isOwner = true; noteRevisions: RevisionListItem[] = []; currentRevision: string; @@ -248,6 +249,10 @@ export class NotebookComponent extends MessageListenersManager implements OnInit this.selectId = id; } + onParagraphScrolled(id: string) { + this.scrolledId = id; + } + onSelectAtIndex(index: number) { const scopeIndex = Math.min(this.note.paragraphs.length, Math.max(0, index)); if (this.note.paragraphs[scopeIndex]) { @@ -345,6 +350,16 @@ export class NotebookComponent extends MessageListenersManager implements OnInit } ngOnInit() { + this.activatedRoute.queryParamMap + .pipe( + startWith(this.activatedRoute.snapshot.queryParamMap), + takeUntil(this.destroy$), + map(data => data.get('paragraph')) + ) + .subscribe(id => { + this.onParagraphSelect(id); + this.onParagraphScrolled(id); + }); this.activatedRoute.params .pipe( takeUntil(this.destroy$), diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook/paragraph/paragraph.component.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook/paragraph/paragraph.component.ts index ad9691e..3afdea1 100644 --- a/zeppelin-web-angular/src/app/pages/workspace/notebook/paragraph/paragraph.component.ts +++ b/zeppelin-web-angular/src/app/pages/workspace/notebook/paragraph/paragraph.component.ts @@ -11,6 +11,7 @@ */ import { + AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -62,7 +63,7 @@ type Mode = 'edit' | 'command'; }, changeDetection: ChangeDetectionStrategy.OnPush }) -export class NotebookParagraphComponent extends ParagraphBase implements OnInit, OnChanges, OnDestroy { +export class NotebookParagraphComponent extends ParagraphBase implements OnInit, OnChanges, OnDestroy, AfterViewInit { @ViewChild(NotebookParagraphCodeEditorComponent, { static: false }) notebookParagraphCodeEditorComponent: NotebookParagraphCodeEditorComponent; @ViewChildren(NotebookParagraphResultComponent) notebookParagraphResultComponents: QueryList< @@ -73,6 +74,7 @@ export class NotebookParagraphComponent extends ParagraphBase implements OnInit, @Input() looknfeel: string; @Input() revisionView: boolean; @Input() select: boolean = false; + @Input() scrolled: boolean = false; @Input() index: number = -1; @Input() viewOnly: boolean; @Input() last: boolean; @@ -608,25 +610,36 @@ export class NotebookParagraphComponent extends ParagraphBase implements OnInit, }); } + scrollIfNeeded(): void { + if (this.scrolled && this.host.nativeElement) { + setTimeout(() => { + this.host.nativeElement.scrollIntoView(); + }); + } + } ngOnChanges(changes: SimpleChanges): void { - const { index, select } = changes; + const { index, select, scrolled } = changes; if ( (index && index.currentValue !== index.previousValue && this.select) || (select && select.currentValue === true && select.previousValue !== true) ) { - if (this.host.nativeElement) { - setTimeout(() => { - if (this.mode === 'command') { - (this.host.nativeElement as HTMLElement).focus(); - } - }); - } + setTimeout(() => { + if (this.mode === 'command' && this.host.nativeElement) { + (this.host.nativeElement as HTMLElement).focus(); + } + }); + } + if (scrolled) { + this.scrollIfNeeded(); } } getElement(): HTMLElement { return this.host && this.host.nativeElement; } + ngAfterViewInit(): void { + this.scrollIfNeeded(); + } ngOnDestroy(): void { super.ngOnDestroy();