From a6d1a40791278121adbb46a4547e4259ee93ba28 Mon Sep 17 00:00:00 2001 From: chuanlin2018 Date: Wed, 10 Apr 2024 10:53:11 -0400 Subject: [PATCH 1/4] Rewrote the floating menu --- .../app/landing/landingpage.component.html | 33 +-- .../app/landing/landingpage.component.scss | 10 + .../src/app/landing/landingpage.component.ts | 17 +- .../app/landing/tools/menu/menu.component.css | 30 +++ .../landing/tools/menu/menu.component.html | 39 ++++ .../landing/tools/menu/menu.component.spec.ts | 25 +++ .../app/landing/tools/menu/menu.component.ts | 199 ++++++++++++++++++ .../app/landing/tools/toolmenu.component.css | 6 + .../app/landing/tools/toolmenu.component.ts | 11 +- angular/src/app/landing/tools/tools.module.ts | 7 +- 10 files changed, 358 insertions(+), 19 deletions(-) create mode 100644 angular/src/app/landing/tools/menu/menu.component.css create mode 100644 angular/src/app/landing/tools/menu/menu.component.html create mode 100644 angular/src/app/landing/tools/menu/menu.component.spec.ts create mode 100644 angular/src/app/landing/tools/menu/menu.component.ts diff --git a/angular/src/app/landing/landingpage.component.html b/angular/src/app/landing/landingpage.component.html index e1b482314..633ee5478 100644 --- a/angular/src/app/landing/landingpage.component.html +++ b/angular/src/app/landing/landingpage.component.html @@ -28,20 +28,25 @@ (click)="menu3.togglePopup($event)"> --> + + + + - - + +
@@ -54,9 +59,13 @@
- - + --> + + + diff --git a/angular/src/app/landing/landingpage.component.scss b/angular/src/app/landing/landingpage.component.scss index 04132ff5f..38768c295 100644 --- a/angular/src/app/landing/landingpage.component.scss +++ b/angular/src/app/landing/landingpage.component.scss @@ -52,6 +52,16 @@ z-index: 10; } +.sticky-menu01 { + float: right; + position: sticky; + margin-top: 4em; + right: 2em; + width: 10em; + height: 2.3em; + z-index: 10; +} + .sticky-menu { float: right; position: sticky; diff --git a/angular/src/app/landing/landingpage.component.ts b/angular/src/app/landing/landingpage.component.ts index 488dd4990..bd1d98eed 100644 --- a/angular/src/app/landing/landingpage.component.ts +++ b/angular/src/app/landing/landingpage.component.ts @@ -103,6 +103,15 @@ export class LandingPageComponent implements OnInit, AfterViewInit { buttonTop: number = 20; + showStickMenu: boolean = false; + + + @HostListener('document:click', ['$event']) + documentClick(event: MouseEvent) { + event.stopPropagation(); + this.showStickMenu = false; + } + @ViewChild(LandingBodyComponent) landingBodyComponent: LandingBodyComponent; @@ -578,10 +587,9 @@ export class LandingPageComponent implements OnInit, AfterViewInit { * sections. */ goToSection(sectionId: string) { - // If sectionID is "Metadata", scroll to About This Dataset and display JSON viewer this.showJsonViewer = (sectionId == "Metadata"); if(sectionId == "Metadata") sectionId = "about"; - + setTimeout(() => { this.landingBodyComponent.goToSection(sectionId); }, 50); @@ -637,4 +645,9 @@ export class LandingPageComponent implements OnInit, AfterViewInit { "col-10 md:col-10 lg:col-10 sm:flex-nowrap"; } } + + toggleMenu(event){ + event.stopPropagation(); + this.showStickMenu = !this.showStickMenu + } } diff --git a/angular/src/app/landing/tools/menu/menu.component.css b/angular/src/app/landing/tools/menu/menu.component.css new file mode 100644 index 000000000..d3d8186d6 --- /dev/null +++ b/angular/src/app/landing/tools/menu/menu.component.css @@ -0,0 +1,30 @@ +.menuicon { + margin-right: .5em; +} + +.menu-header { + background-color: var(--background-default); + color: white; + font-family: sans-serif; + font-size: 16px; + font-weight: bold; + line-height: 2em; + min-height: 2em; +} + +.menu-item { + background-color: var(--background-default); + word-wrap: break-word; + font-family: 'Sans-Serif'; + font-size: 14px; + cursor: pointer; +} + +.menu-item:hover { + background-color: var(--background-hover); +} + +.menu-body { + padding-left: 5px; + padding-right: 5px; +} \ No newline at end of file diff --git a/angular/src/app/landing/tools/menu/menu.component.html b/angular/src/app/landing/tools/menu/menu.component.html new file mode 100644 index 000000000..48b058a33 --- /dev/null +++ b/angular/src/app/landing/tools/menu/menu.component.html @@ -0,0 +1,39 @@ + + + + + + +
+ + {{menuitem.title}} +
+ + + + + + +
+ + {{menuitem.title}} +
+ + + + + + +
+ + {{menuitem.title}} +
\ No newline at end of file diff --git a/angular/src/app/landing/tools/menu/menu.component.spec.ts b/angular/src/app/landing/tools/menu/menu.component.spec.ts new file mode 100644 index 000000000..b6ba4e5ac --- /dev/null +++ b/angular/src/app/landing/tools/menu/menu.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MenuComponent } from './menu.component'; + +describe('MenuComponent', () => { + let component: MenuComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MenuComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular/src/app/landing/tools/menu/menu.component.ts b/angular/src/app/landing/tools/menu/menu.component.ts new file mode 100644 index 000000000..86e6b5f76 --- /dev/null +++ b/angular/src/app/landing/tools/menu/menu.component.ts @@ -0,0 +1,199 @@ +import { Component, EventEmitter, Input, OnInit, Output, HostListener } from '@angular/core'; +import { CollectionService } from '../../../shared/collection-service/collection.service'; +import { Themes, ThemesPrefs, Collections, Collection, ColorScheme, CollectionThemes } from '../../../shared/globals/globals'; +import { NerdmRes, NERDResource } from '../../../nerdm/nerdm'; +import { CartConstants } from '../../../datacart/cartconstants'; +import { AppConfig } from '../../../config/config'; +import * as _ from 'lodash-es'; + +export class menuItem { + title: string; + backgroundColor: string; + isHeader: boolean; + sectionName: string; + icon: string; + url: string; + + constructor( + title: string, + sectionName: string = "", + url: string, + backgroundColor: string = "white", + isHeader: boolean = false, + icon: string = ""){ + this.title = title; + this.sectionName = sectionName; + this.url = url; + this.backgroundColor = backgroundColor; + this.isHeader = isHeader; + this.icon = icon; + } +} + +@Component({ + selector: 'app-menu', + templateUrl: './menu.component.html', + styleUrls: ['./menu.component.css'] +}) +export class MenuComponent implements OnInit { + defaultColor: string; + lighterColor: string; + hoverColor: string; + allCollections: any = {}; + resourceType: string; + gotoMenu: menuItem[] = [] as menuItem[]; + useMenu: menuItem[] = [] as menuItem[]; + findMenu: menuItem[] = [] as menuItem[]; + public CART_CONSTANTS: any = CartConstants.cartConst; + globalCartUrl: string = "/datacart/" + this.CART_CONSTANTS.GLOBAL_CART_NAME; + recordType: string = ""; + + + // the resource record metadata that the tool menu data is drawn from + @Input() record : NerdmRes|null = null; + @Input() collection: string = Collections.DEFAULT; + @Input() theme: string = "nist"; + @Output() scroll = new EventEmitter(); + + // signal for triggering display of the citation information + @Output() toggle_citation = new EventEmitter(); + + constructor( + public collectionService: CollectionService, + private cfg : AppConfig) { } + + ngOnInit(): void { + this.allCollections = this.collectionService.loadCollections(this.collection.toLowerCase()); + + this.setColor(); + + this.resourceType = ThemesPrefs.getResourceLabel(this.theme); + + this.buildMenu(); + } + + buildMenu() { + this.gotoMenu.push(new menuItem("Go To...", "", "", this.defaultColor, true)); + this.gotoMenu.push(new menuItem("Top", "top", "", this.lighterColor, false, "faa faa-arrow-circle-right menuicon")); + this.gotoMenu.push(new menuItem("Description", "description", "", this.lighterColor, false, "faa faa-arrow-circle-right menuicon")); + this.gotoMenu.push(new menuItem("Data Access", "dataAccess", "", this.lighterColor, false, "faa faa-arrow-circle-right menuicon")); + this.gotoMenu.push(new menuItem("About This "+this.resourceType, "about","", this.lighterColor, false, "faa faa-arrow-circle-right menuicon")); + + this.useMenu.push(new menuItem("Use", "", "", this.defaultColor, true)); + this.useMenu.push(new menuItem("Citation", "citation", "", this.lighterColor, false, "faa faa-angle-double-right")); + this.useMenu.push(new menuItem("Repository Metadata", "Metadata", "", this.lighterColor, false, "faa faa-angle-double-right")); + this.useMenu.push(new menuItem("Fair Use Statement","", this.record['license'], this.lighterColor, false, "faa faa-external-link")); + this.useMenu.push(new menuItem("Data Cart", "", this.globalCartUrl, this.lighterColor, false, "faa faa-cart-plus")); + + let searchbase = this.cfg.get("locations.pdrSearch","/sdp/") + if (searchbase.slice(-1) != '/') searchbase += "/" + let authlist = ""; + if (this.record['authors']) { + for (let i = 0; i < this.record['authors'].length; i++) { + if(i > 0) authlist += ','; + let fn = this.record['authors'][i]['fn']; + + if (fn != null && fn != undefined && fn.trim().indexOf(" ") > 0) + authlist += '"'+ fn.trim() + '"'; + else + authlist += fn.trim(); + } + } + + let contactPoint = ""; + if (this.record['contactPoint'] && this.record['contactPoint'].fn) { + contactPoint = this.record['contactPoint'].fn.trim(); + if(contactPoint.indexOf(" ") > 0){ + contactPoint = '"' + contactPoint + '"'; + } + } + + // If authlist is empty, use contact point instead + let authorSearchString: string = ""; + if(_.isEmpty(authlist)){ + authorSearchString = "/#/search?q=contactPoint.fn%3D" + contactPoint; + }else{ + authorSearchString = "/#/search?q=authors.fn%3D" + authlist + "%20OR%20contactPoint.fn%3D" + contactPoint; + } + + if (!authlist) { + if (this.record['contactPoint'] && this.record['contactPoint'].fn) { + let splittedName = this.record['contactPoint'].fn.split(' '); + authlist = splittedName[splittedName.length - 1]; + } + } + + let keywords: string[] = this.record['keyword']; + let keywordString: string = ""; + for(let i = 0; i < keywords.length; i++){ + if(i > 0) keywordString += ','; + + if(keywords[i].trim().indexOf(" ") > 0) + keywordString += '"' + keywords[i].trim() + '"'; + else + keywordString += keywords[i].trim(); + } + + let resourceLabel: string = "Similar Resources"; + if(this.recordType == Themes.SCIENCE_THEME){ + resourceLabel = "Resources in this Collection"; + } + + this.findMenu.push(new menuItem("Find", "", "", this.defaultColor, true)); + + this.findMenu.push(new menuItem(resourceLabel, "", searchbase + "#/search?q=keyword%3D" + keywordString, this.lighterColor, false, "faa faa-external-link" )) + this.findMenu.push(new menuItem('Resources by Authors', "", this.cfg.get("locations.pdrSearch", "/sdp/") + authorSearchString, this.lighterColor, false, "faa faa-external-link" )) + + + } + + /** + * switch the display of the Citation information: if it is currently showing, + * it should be hidden; if it is not visible, it should be shown. This method + * is trigger by clicking on the "Citation" link in the menu; clicking + * alternatively both shows and hides the display. + * + * The LandingPageComponent handles the actual display of the information + * (currently implemented as a pop-up). + */ + toggleCitation() { + this.toggle_citation.emit(true); + } + + /** + * Set color variables + */ + setColor() { + this.defaultColor = this.allCollections[this.collection.toLowerCase()].color.default; + this.lighterColor = this.allCollections[this.collection.toLowerCase()].color.lighter; + this.hoverColor = this.allCollections[this.collection.toLowerCase()].color.hover; + } + + /** + * scroll to the specified section of the landing page + */ + goToSection(sectname : string, url: string = "") { + if (sectname) { + console.info("scrolling to #"+sectname+"..."); + }else{ + console.info("scrolling to top of document"); + } + + switch(sectname) { + case "citation": { + this.toggleCitation(); + break; + } + case "": { + if(url) + window.open(url,'_blank'); + break; + } + default: { + this.scroll.emit(sectname); + break; + } + } + + } +} diff --git a/angular/src/app/landing/tools/toolmenu.component.css b/angular/src/app/landing/tools/toolmenu.component.css index 4f2510db8..b04849eee 100644 --- a/angular/src/app/landing/tools/toolmenu.component.css +++ b/angular/src/app/landing/tools/toolmenu.component.css @@ -51,6 +51,12 @@ } +:host ::ng-deep .rightMenuStylePop>.p-menu .p-tieredmenu .p-submenu-list { + position: absolute; + top: 1000px !important; + left: unset; +} + :host ::ng-deep .rightMenuStylePop>.p-menu .p-menuitem-link { padding: 0.5em 0.2em 0.5em 0.5em; font-size: 14px; diff --git a/angular/src/app/landing/tools/toolmenu.component.ts b/angular/src/app/landing/tools/toolmenu.component.ts index 3ceebaf95..1bc5f90e0 100644 --- a/angular/src/app/landing/tools/toolmenu.component.ts +++ b/angular/src/app/landing/tools/toolmenu.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, Output, OnChanges, ViewChild, EventEmitter, SimpleChanges } from '@angular/core'; +import { Component, Input, Output, OnChanges, ViewChild, EventEmitter, SimpleChanges, ElementRef } from '@angular/core'; import { MenuItem } from 'primeng/api'; import { Menu } from 'primeng/menu'; @@ -30,7 +30,9 @@ import { CollectionService } from '../../shared/collection-service/collection.se [style.--background-default]="defaultColor" [style.--background-lighter]="lighterColor" [style.--background-hover]="hoverColor" - [popup]="isPopup" [model]="items" [appendTo]="appendTo"> + [popup]="isPopup" [model]="items" + [appendTo]="appendTo" + > `, styleUrls: ['./toolmenu.component.css'] }) @@ -41,13 +43,14 @@ export class ToolMenuComponent implements OnChanges { hoverColor: string; // Object that hold all themes: Forensics, NIST, ... allCollections: any = {}; + buttonTop = 0; // the resource record metadata that the tool menu data is drawn from @Input() record : NerdmRes|null = null; // true if this menu should appear as a popup @Input() isPopup : boolean = false; - @Input() appendTo : boolean = false; + @Input() appendTo; @Input() theme: string = "nist" @Input() collection: string = Collections.DEFAULT; @@ -66,6 +69,7 @@ export class ToolMenuComponent implements OnChanges { public CART_CONSTANTS: any = CartConstants.cartConst; globalCartUrl: string = "/datacart/" + this.CART_CONSTANTS.GLOBAL_CART_NAME; editEnabled: any; + parentContext: ElementRef; /** * create the component. @@ -80,6 +84,7 @@ export class ToolMenuComponent implements OnChanges { } ngOnInit(): void { + console.log("appendTo", this.appendTo); this.allCollections = this.collectionService.loadCollections(this.collection.toLowerCase()); this.setColor(); diff --git a/angular/src/app/landing/tools/tools.module.ts b/angular/src/app/landing/tools/tools.module.ts index 351d8cba4..9965998d8 100644 --- a/angular/src/app/landing/tools/tools.module.ts +++ b/angular/src/app/landing/tools/tools.module.ts @@ -4,6 +4,7 @@ import { CommonModule } from '@angular/common'; import { MenuModule } from 'primeng/menu'; import { ToolMenuComponent } from './toolmenu.component'; +import { MenuComponent } from './menu/menu.component'; /** * A module providing tools for interacting with the landing page's record metadata. @@ -17,10 +18,12 @@ import { ToolMenuComponent } from './toolmenu.component'; MenuModule ], declarations: [ - ToolMenuComponent + ToolMenuComponent, + MenuComponent ], exports: [ - ToolMenuComponent + ToolMenuComponent, + MenuComponent ] }) export class ToolsModule { } From 881076ea6fed724ad8106d14d6bcfd593aa66c68 Mon Sep 17 00:00:00 2001 From: chuanlin2018 Date: Thu, 11 Apr 2024 10:30:51 -0400 Subject: [PATCH 2/4] Some clean up --- .../app/landing/landingpage.component.html | 28 +------------------ .../app/landing/landingpage.component.scss | 2 +- .../app/landing/tools/menu/menu.component.css | 5 ++-- .../landing/tools/menu/menu.component.spec.ts | 17 +++++++++-- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/angular/src/app/landing/landingpage.component.html b/angular/src/app/landing/landingpage.component.html index 633ee5478..531c76487 100644 --- a/angular/src/app/landing/landingpage.component.html +++ b/angular/src/app/landing/landingpage.component.html @@ -23,46 +23,21 @@
- - - - - - -
- - - - diff --git a/angular/src/app/landing/landingpage.component.scss b/angular/src/app/landing/landingpage.component.scss index 38768c295..d231fd5fe 100644 --- a/angular/src/app/landing/landingpage.component.scss +++ b/angular/src/app/landing/landingpage.component.scss @@ -52,7 +52,7 @@ z-index: 10; } -.sticky-menu01 { +.sticky-menu-popup { float: right; position: sticky; margin-top: 4em; diff --git a/angular/src/app/landing/tools/menu/menu.component.css b/angular/src/app/landing/tools/menu/menu.component.css index d3d8186d6..1440ca4fa 100644 --- a/angular/src/app/landing/tools/menu/menu.component.css +++ b/angular/src/app/landing/tools/menu/menu.component.css @@ -10,6 +10,7 @@ font-weight: bold; line-height: 2em; min-height: 2em; + border-radius: 3px; } .menu-item { @@ -25,6 +26,6 @@ } .menu-body { - padding-left: 5px; - padding-right: 5px; + padding-left: 10px; + padding-right: 10px; } \ No newline at end of file diff --git a/angular/src/app/landing/tools/menu/menu.component.spec.ts b/angular/src/app/landing/tools/menu/menu.component.spec.ts index b6ba4e5ac..799fcedac 100644 --- a/angular/src/app/landing/tools/menu/menu.component.spec.ts +++ b/angular/src/app/landing/tools/menu/menu.component.spec.ts @@ -1,14 +1,26 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { AppConfig } from '../../../config/config' import { MenuComponent } from './menu.component'; +import { TransferState } from '@angular/platform-browser'; +import { AngularEnvironmentConfigService } from '../../../config/config.service'; +import { testdata } from '../../../../environments/environment'; describe('MenuComponent', () => { let component: MenuComponent; let fixture: ComponentFixture; + let cfg : AppConfig; + let plid : Object = "browser"; + let ts : TransferState = new TransferState(); + let md = testdata['test1']; + beforeEach(async () => { + cfg = (new AngularEnvironmentConfigService(plid, ts)).getConfig() as AppConfig; await TestBed.configureTestingModule({ - declarations: [ MenuComponent ] + declarations: [ MenuComponent ], + providers: [ + { provide: AppConfig, useValue: cfg } + ] }) .compileComponents(); }); @@ -16,6 +28,7 @@ describe('MenuComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(MenuComponent); component = fixture.componentInstance; + component.record = md; fixture.detectChanges(); }); From 1f300086663e0fe02552cbf816a6bfdacc4e1543 Mon Sep 17 00:00:00 2001 From: chuanlin2018 Date: Thu, 11 Apr 2024 12:21:43 -0400 Subject: [PATCH 3/4] Added metrics info to floating menu --- .../app/landing/landingpage.component.html | 8 ++++---- angular/src/app/landing/landingpage.module.ts | 4 ++-- .../landing/metricsinfo/metricsinfo.module.ts | 13 +++++++++++++ .../landing/tools/menu/menu.component.html | 7 ++++++- .../app/landing/tools/menu/menu.component.ts | 19 ++++++++++++++++--- angular/src/app/landing/tools/tools.module.ts | 6 +++--- 6 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 angular/src/app/landing/metricsinfo/metricsinfo.module.ts diff --git a/angular/src/app/landing/landingpage.component.html b/angular/src/app/landing/landingpage.component.html index 531c76487..80405fc92 100644 --- a/angular/src/app/landing/landingpage.component.html +++ b/angular/src/app/landing/landingpage.component.html @@ -30,7 +30,7 @@ + [theme]="theme" [inBrowser]="inBrowser" [metricsData]="metricsData" [showMetrics]="showMetrics" (scroll)="goToSection($event)" (toggle_citation)="toggleCitation('large')">
@@ -38,13 +38,13 @@