diff --git a/src/atlasViewerExports/export.module.ts b/src/atlasViewerExports/export.module.ts index 6d8ceecc8e0bc03ae52732c02bb1ef0b3f8f1028..1ebe2eabff0294e2b77e9aa6b5adfb9ca45122cc 100644 --- a/src/atlasViewerExports/export.module.ts +++ b/src/atlasViewerExports/export.module.ts @@ -5,9 +5,7 @@ import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { ComponentsModule } from "../components/components.module"; import { MarkdownDom } from '../components/markdown/markdown.component' -import { PanelComponent } from "../components/panel/panel.component"; import { ParseAttributeDirective } from "../components/parseAttribute.directive"; -import { ReadmoreComponent } from "../components/readmoore/readmore.component"; import { TreeComponent } from "../components/tree/tree.component"; import { SampleBoxUnit } from "./sampleBox/sampleBox.component"; @@ -27,10 +25,8 @@ import { SampleBoxUnit } from "./sampleBox/sampleBox.component"; entryComponents : [ SampleBoxUnit, - ReadmoreComponent, MarkdownDom, TreeComponent, - PanelComponent, ], }) @@ -39,15 +35,9 @@ export class ExportModule { const sampleBox = createCustomElement(SampleBoxUnit, {injector: this.injector}) customElements.define('sample-box', sampleBox) - const readMore = createCustomElement(ReadmoreComponent, { injector : this.injector }) - customElements.define('readmore-element', readMore) - const markDown = createCustomElement(MarkdownDom, {injector : this.injector }) customElements.define('markdown-element', markDown) - const panel = createCustomElement(PanelComponent, {injector : this.injector }) - customElements.define('panel-element', panel) - const tree = createCustomElement(TreeComponent, {injector : this.injector }) customElements.define('tree-element', tree) diff --git a/src/components/components.module.ts b/src/components/components.module.ts index a17a533ba36d52a2f640028746111b26487844c2..37db9c719f8a2f312b37826322cc87dfdd6da77a 100644 --- a/src/components/components.module.ts +++ b/src/components/components.module.ts @@ -19,20 +19,13 @@ import { FlattenTreePipe } from './flatTree/flattener.pipe'; import { FlatTreeComponent } from './flatTree/flatTree.component'; import { HighlightPipe } from './flatTree/highlight.pipe'; import { RenderPipe } from './flatTree/render.pipe'; -import { HoverableBlockDirective } from './hoverableBlock.directive'; -import { PaginationComponent } from './pagination/pagination.component'; -import { PanelComponent } from './panel/panel.component'; -import { PillComponent } from './pill/pill.component'; -import { ProgressBar } from './progress/progress.component'; -import { RadioList } from './radiolist/radiolist.component'; -import { ReadmoreComponent } from './readmoore/readmore.component'; -import { SleightOfHand } from './sleightOfHand/soh.component'; -import { TimerComponent } from './timer/timer.component'; import { TreeComponent } from './tree/tree.component'; import { TreeBaseDirective } from './tree/treeBase.directive'; import { IAVVerticalButton } from './vButton/vButton.component'; import { DynamicMaterialBtn } from './dynamicMaterialBtn/dynamicMaterialBtn.component'; import { SpinnerCmp } from './spinner/spinner.component'; +import { ReadmoreModule } from './readmore'; +import { HoverableModule } from './hoverable'; @NgModule({ imports : [ @@ -42,20 +35,14 @@ import { SpinnerCmp } from './spinner/spinner.component'; BrowserAnimationsModule, AngularMaterialModule, UtilModule, + ReadmoreModule, + HoverableModule, ], declarations : [ /* components */ MarkdownDom, - ReadmoreComponent, TreeComponent, - PanelComponent, - PaginationComponent, FlatTreeComponent, - TimerComponent, - PillComponent, - RadioList, - ProgressBar, - SleightOfHand, DialogComponent, ConfirmDialogComponent, IAVVerticalButton, @@ -63,7 +50,6 @@ import { SpinnerCmp } from './spinner/spinner.component'; SpinnerCmp, /* directive */ - HoverableBlockDirective, TreeBaseDirective, /* pipes */ @@ -78,18 +64,12 @@ import { SpinnerCmp } from './spinner/spinner.component'; ], exports : [ BrowserAnimationsModule, + ReadmoreModule, + HoverableModule, MarkdownDom, - ReadmoreComponent, TreeComponent, - PanelComponent, - PaginationComponent, FlatTreeComponent, - TimerComponent, - PillComponent, - RadioList, - ProgressBar, - SleightOfHand, DialogComponent, ConfirmDialogComponent, IAVVerticalButton, @@ -97,8 +77,6 @@ import { SpinnerCmp } from './spinner/spinner.component'; SpinnerCmp, TreeSearchPipe, - - HoverableBlockDirective, TreeBaseDirective, ], }) diff --git a/src/components/hoverableBlock.directive.ts b/src/components/hoverable/hoverableBlock.directive.ts similarity index 67% rename from src/components/hoverableBlock.directive.ts rename to src/components/hoverable/hoverableBlock.directive.ts index a57001b70aae41db1b4855265726ef7ba9da7175..8868d046199d7706197fe7d31513f893e7b64b36 100644 --- a/src/components/hoverableBlock.directive.ts +++ b/src/components/hoverable/hoverableBlock.directive.ts @@ -1,4 +1,4 @@ -import { Directive, HostBinding, HostListener, Input } from "@angular/core"; +import { Directive, HostBinding, HostListener, Input, SecurityContext } from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; @Directive({ @@ -39,29 +39,29 @@ export class HoverableBlockDirective { public opacity: number = 0.9 @HostBinding('style.transform') - public transform = this.sanitizer.bypassSecurityTrustStyle(`translateY(0px)`) + public transform = this.sanitizer.sanitize(SecurityContext.STYLE, `translateY(0px)`) @HostBinding('style.box-shadow') - public boxShadow = this.sanitizer.bypassSecurityTrustStyle('0 4px 6px 0 rgba(5,5,5,0.1)') + public boxShadow = this.sanitizer.sanitize(SecurityContext.STYLE, '0 4px 6px 0 rgba(5,5,5,0.1)') @HostListener('mouseenter') public onMouseenter() { if (this._disable) { return } this.opacity = 1.0 - this.boxShadow = this.sanitizer.bypassSecurityTrustStyle(`0 4px 6px 0 rgba(5,5,5,0.25)`) + this.boxShadow = this.sanitizer.sanitize(SecurityContext.STYLE, `0 4px 6px 0 rgba(5,5,5,0.25)`) /** * n.b. risk of XSS. But sincle translate Y is passed through Number, and corerced into a number, * and using 5 as a fallback, it should be safe */ - this.transform = this.sanitizer.bypassSecurityTrustStyle(`translateY(${this._translateY}px)`) + this.transform = this.sanitizer.sanitize(SecurityContext.STYLE, `translateY(${this._translateY}px)`) } @HostListener('mouseleave') public onmouseleave() { if (this._disable) { return } this.opacity = 0.9 - this.boxShadow = this.sanitizer.bypassSecurityTrustStyle(`0 4px 6px 0 rgba(5,5,5,0.1)`) - this.transform = this.sanitizer.bypassSecurityTrustStyle(`translateY(0px)`) + this.boxShadow = this.sanitizer.sanitize(SecurityContext.STYLE, `0 4px 6px 0 rgba(5,5,5,0.1)`) + this.transform = this.sanitizer.sanitize(SecurityContext.STYLE, `translateY(0px)`) } constructor(private sanitizer: DomSanitizer) { diff --git a/src/components/hoverable/index.ts b/src/components/hoverable/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0dc8b0c22be37dc381f8a507362cedc78f78370 --- /dev/null +++ b/src/components/hoverable/index.ts @@ -0,0 +1,2 @@ +export { HoverableModule } from './module' +export { HoverableBlockDirective } from './hoverableBlock.directive' \ No newline at end of file diff --git a/src/components/hoverable/module.ts b/src/components/hoverable/module.ts new file mode 100644 index 0000000000000000000000000000000000000000..0913063fdfbe173b6b7b18637364f56373329c91 --- /dev/null +++ b/src/components/hoverable/module.ts @@ -0,0 +1,17 @@ +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { HoverableBlockDirective } from "./hoverableBlock.directive"; + +@NgModule({ + imports: [ + CommonModule, + ], + declarations: [ + HoverableBlockDirective, + ], + exports: [ + HoverableBlockDirective + ] +}) + +export class HoverableModule{} \ No newline at end of file diff --git a/src/components/pagination/pagination.component.ts b/src/components/pagination/pagination.component.ts deleted file mode 100644 index 492fb57ca055f8bd65bf5387db49c254e062e3b6..0000000000000000000000000000000000000000 --- a/src/components/pagination/pagination.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core' - -@Component({ - selector : 'pagination-component', - templateUrl : './pagination.template.html', - styleUrls : [ - './pagination.style.css', - ], -}) - -export class PaginationComponent { - @Input() public total: number = 0 - @Input() public hitsPerPage: number = 15 - @Input() public currentPage: number = 0 - - @Output() public paginationChange: EventEmitter<number> = new EventEmitter() - @Output() public outOfBound: EventEmitter<number> = new EventEmitter() - - public goto(pgnum: number) { - const emitValue = pgnum < 0 ? - 0 : - pgnum >= Math.ceil(this.total / this.hitsPerPage) ? - Math.ceil(this.total / this.hitsPerPage) - 1 : - pgnum - - this.paginationChange.emit(emitValue) - } - - public gotoFirst() { - this.goto(0) - } - - public gotoLast() { - const num = Math.floor(this.total / this.hitsPerPage) + 1 - this.goto(num) - } - - get getPagination() { - return Array.from(Array(Math.ceil(this.total / this.hitsPerPage)).keys()).filter((this.hidePagination).bind(this)) - } - - get getPageLowerBound() { - return this.currentPage * this.hitsPerPage + 1 - } - - get getPageUpperBound() { - return Math.min( ( this.currentPage + 1 ) * this.hitsPerPage , this.total ) - } - - public hidePagination(idx: number) { - - const correctedPagination = this.currentPage < 2 ? - 2 : - this.currentPage > (Math.ceil(this.total / this.hitsPerPage) - 3) ? - Math.ceil(this.total / this.hitsPerPage) - 3 : - this.currentPage - return (Math.abs(idx - correctedPagination) < 3) - } -} diff --git a/src/components/pagination/pagination.style.css b/src/components/pagination/pagination.style.css deleted file mode 100644 index ca46999f972a2f39ccd8e170eb6701551ef7a7e5..0000000000000000000000000000000000000000 --- a/src/components/pagination/pagination.style.css +++ /dev/null @@ -1,72 +0,0 @@ -div.pagination-container -{ - padding:0.5em 0; - display:flex; - flex-direction: column; - align-items: center; -} - -:host-context([darktheme="true"]) div.pagination-container -{ - background-color:rgba(30,30,30,0.9); - color:rgba(240,240,240,0.9); -} - -div.btn -{ - border:none; - position : relative; - cursor:default; - transition : transform 0.1s ease; -} - -div.btn:hover -{ - transform: translateY(-2%); -} - -div.btn:before -{ - content : ' '; - position : absolute; - top:0; - left:0; - width : 100%; - height : 100%; - pointer-events: none; - background-color : rgba(128,128,128,1); - opacity: 0.0; - transition : opacity 0.1s ease; -} - -div.btn:hover:before -{ - opacity : 0.3; -} - -div.btn.btn-primary -{ - transform:translateY(3%); - position : relative; -} - -div.btn.btn-primary:before -{ - position : absolute; - content : ' '; - left:0; - top:0; - - width:100%; - height:100%; - - background-color : black; - opacity : 0.1; - - pointer-events: none; -} - -.pagination-control -{ - font-size:80%; -} \ No newline at end of file diff --git a/src/components/pagination/pagination.template.html b/src/components/pagination/pagination.template.html deleted file mode 100644 index 1d3f14ae11e85731797eb47941ced54ef63bfc62..0000000000000000000000000000000000000000 --- a/src/components/pagination/pagination.template.html +++ /dev/null @@ -1,48 +0,0 @@ -<div class = "pagination-container"> - <div class = "btn-group"> - - <div - class = "default-control btn btn-default btn-sm" - (click)="gotoFirst()" - > - - <i class = "fas fa-fast-backward"></i> - </div> - - <div - class = "btn btn-default btn-sm" - (click)="goto(currentPage - 1)" - > - <i class = "fas fa-step-backward"></i> - </div> - - <div - (click)="goto(pageNum)" - [ngClass]="{'btn-primary':currentPage == pageNum}" - *ngFor = "let pageNum of getPagination" - class = "pagination-control btn btn-default btn-sm" - > - {{ pageNum + 1 }} - </div> - - <div - class = "btn btn-default btn-sm" - (click)="goto(currentPage + 1)" - > - <i class = "fas fa-step-forward"></i> - </div> - <div - class = "btn btn-default btn-sm" - (click)="gotoLast()" - > - <i class = "fas fa-fast-forward"></i> - </div> - - </div> - <div *ngIf = "total > 0" class = "pagination-summary"> - showing {{ getPageLowerBound }} - {{ getPageUpperBound }} out of {{ total }} - </div> - <div *ngIf = "total == 0" class = "pagination-summary"> - no results - </div> -</div> \ No newline at end of file diff --git a/src/components/panel/panel.animation.ts b/src/components/panel/panel.animation.ts deleted file mode 100644 index 1b66a6ad48a989fb16332ef4a7678518decb637a..0000000000000000000000000000000000000000 --- a/src/components/panel/panel.animation.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { animate, state, style, transition, trigger } from "@angular/animations"; - -export const panelAnimations = trigger('collapseState', [ - state('collapsed', - style({ - 'margin-top' : '-{{ fullHeight }}px', - }), - { params : { fullHeight : 9999 } }, - ), - state('visible', - style({ - 'margin-top' : '0px', - }), - { params : { fullHeight : 0 } }, - ), - transition('collapsed => visible', [ - animate('250ms ease-out'), - ]), - transition('visible => collapsed', [ - animate('250ms ease-in'), - ]), -]) diff --git a/src/components/panel/panel.component.ts b/src/components/panel/panel.component.ts deleted file mode 100644 index a68b760124a05ded217f973a66e6d0edf7cbaf76..0000000000000000000000000000000000000000 --- a/src/components/panel/panel.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewChild } from "@angular/core"; -import { ParseAttributeDirective } from "../parseAttribute.directive"; - -@Component({ - selector : 'panel-component', - templateUrl : './panel.template.html', - styleUrls : [ - `./panel.style.css`, - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class PanelComponent extends ParseAttributeDirective { - - @Input() public showHeading: boolean = true - @Input() public showBody: boolean = true - @Input() public showFooter: boolean = false - - @Input() public collapseBody: boolean = false - @Input() public bodyCollapsable: boolean = false - - @ViewChild('panelBody', { read : ElementRef }) public efPanelBody: ElementRef - @ViewChild('panelFooter', { read : ElementRef }) public efPanelFooter: ElementRef - - constructor() { - super() - } - - public toggleCollapseBody(_event: Event) { - if (this.bodyCollapsable) { - this.collapseBody = !this.collapseBody - this.showBody = !this.showBody - this.showFooter = !this.showFooter - } - } -} diff --git a/src/components/panel/panel.style.css b/src/components/panel/panel.style.css deleted file mode 100644 index 6acdc28bdb60de794b7556a987360da98d1be662..0000000000000000000000000000000000000000 --- a/src/components/panel/panel.style.css +++ /dev/null @@ -1,60 +0,0 @@ -:host -{ - font-size:92%; - overflow:visible; - box-shadow: 0px 4px 16px -4px rgba(0,0,0,0.2); - border-radius : 0; - border:none; - margin:0; - background:none; -} - -[bodyFooterContainer] -{ - overflow:visible; -} - -:host > .panel-heading -{ - border-radius : 0; - padding: 0; - margin:0; - border:none; -} - -:host > [bodyFooterContainer] > .panel-body, -:host > [bodyFooterContainer] > .panel-footer -{ - margin-top:0px; - padding: 0px; - border:none; -} - -div.panel-body -{ - background-color:rgba(245,245,245,0.8); -} - -:host-context([darktheme="true"]).panel-default div.panel-heading -{ - background-color:rgba(45,45,45,0.9); - color:rgba(250,250,250,0.9); -} - -:host-context([darktheme="true"]).panel-success div.panel-heading -{ - background-color:rgba(60,118,61,0.9); - color:rgba(223,240,216 ,0.9); -} - -div.l-card-body -{ - color:rgba(0, 0, 0, 0.9); - background-color:rgba(230, 230, 230, 0.8); -} - -:host-context([darktheme="true"]) div.l-card-body -{ - color:rgba(255,255,255,0.9); - background-color:rgba(45,45,45,0.8); -} \ No newline at end of file diff --git a/src/components/panel/panel.template.html b/src/components/panel/panel.template.html deleted file mode 100644 index 84ca6a9f7a786cc51b3ba4a32e9ff8e1b3ff416d..0000000000000000000000000000000000000000 --- a/src/components/panel/panel.template.html +++ /dev/null @@ -1,25 +0,0 @@ -<div class="l-card"> - <div class="l-card-body"> - <div - *ngIf="showHeading" - class="l-card-title" - (click)="toggleCollapseBody($event)" - [hoverable]="{disable:!bodyCollapsable}"> - <ng-content select="[heading]"> - </ng-content> - </div> - <!-- While wrapping body and footer in a diffrent div adds a lot of overhead, it enables nice transition effects --> - <div - bodyFooterContainer> - <div - *ngIf="showBody" - class="l-card-text" - #panelBody> - - <ng-content select="[body]"> - </ng-content> - - </div> - </div> - </div> -</div> \ No newline at end of file diff --git a/src/components/pill/pill.component.ts b/src/components/pill/pill.component.ts deleted file mode 100644 index 02764af4b1de00e0ddeb27dcf55ada9b04e921f5..0000000000000000000000000000000000000000 --- a/src/components/pill/pill.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, EventEmitter, Input, Output } from "@angular/core"; - -@Component({ - selector: 'pill-component', - templateUrl: './pill.template.html', - styleUrls: [ - './pill.style.css', - ], -}) - -export class PillComponent { - @Input() public title: string = 'Untitled Pill' - @Input() public showClose: boolean = true - @Output() public pillClicked: EventEmitter<boolean> = new EventEmitter() - @Output() public closeClicked: EventEmitter<boolean> = new EventEmitter() - - @Input() public containerStyle: any = { - backgroundColor: 'grey', - } - @Input() public closeBtnStyle: any = { - backgroundColor: 'lightgrey', - } - - public close() { - this.closeClicked.emit(true) - } -} diff --git a/src/components/pill/pill.style.css b/src/components/pill/pill.style.css deleted file mode 100644 index e2aaf541a20bb78635edbb6ebf711fbf95a6756a..0000000000000000000000000000000000000000 --- a/src/components/pill/pill.style.css +++ /dev/null @@ -1,28 +0,0 @@ -.pill-container -{ - padding: 0.2em 1em; - margin-left: 0.2em; - border-radius: 1em; - display: flex; - align-items: center; -} - -.pill-title -{ - flex: 1 1 0; -} - -.pill-close -{ - flex: 0 0 auto; - box-sizing: border-box; - - line-height: 1; - margin-left: 0.4em; - margin-right: -0.6em; -} - -:host -{ - display: inline-block; -} \ No newline at end of file diff --git a/src/components/pill/pill.template.html b/src/components/pill/pill.template.html deleted file mode 100644 index 9ce7bf503564227d872a657f5677907aca7052c9..0000000000000000000000000000000000000000 --- a/src/components/pill/pill.template.html +++ /dev/null @@ -1,15 +0,0 @@ -<div - [ngStyle]="containerStyle" - class="pill-container"> - <span - class="text-truncate pill-title"> - {{ title }} - </span> - <div - [ngStyle]="closeBtnStyle" - class="pill-close rounded-circle" - (click)="close()" - *ngIf="showClose"> - <i class="fas fa-times-circle"></i> - </div> -</div> \ No newline at end of file diff --git a/src/components/progress/progress.component.ts b/src/components/progress/progress.component.ts deleted file mode 100644 index 7cad6aaebe2e0b891e23bc555129359efebd6ec4..0000000000000000000000000000000000000000 --- a/src/components/progress/progress.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from "@angular/core"; - -@Component({ - selector: 'progress-bar', - templateUrl: './progress.template.html', - styleUrls: [ - './progress.style.css', - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class ProgressBar { - @Input() public progressStyle: any - - private _progress: number = 0 - /** - * between 0 and 1 - */ - @Input() - set progress(val: number) { - if (isNaN(val)) { - this._progress = 0 - return - } - if (val < 0 || val === null) { - this._progress = 0 - return - } - if (val > 1) { - this._progress = 1 - return - } - this._progress = val - } - - get progress() { - return this._progress - } - - get progressPercent() { - return `${this.progress * 100}%` - } -} diff --git a/src/components/progress/progress.style.css b/src/components/progress/progress.style.css deleted file mode 100644 index 36858a282cdd6c793041f515aa8c4cd7e0cab97a..0000000000000000000000000000000000000000 --- a/src/components/progress/progress.style.css +++ /dev/null @@ -1,41 +0,0 @@ -.progress -{ - height: 100%; - width: 100%; - position:relative; - overflow:hidden; - background-color:rgba(255,255,255,0.5); -} - -:host-context([darktheme="true"]) .progress -{ - background-color:rgba(0,0,0,0.5); -} - -@keyframes moveRight -{ - from { - transform: translateX(-105%); - } - to { - transform: translateX(205%); - } -} - -.progress::after -{ - content: ''; - width: 100%; - height: 100%; - position:absolute; - border-left-width: 10em; - border-right-width:0; - border-style: solid; - border-image: linear-gradient( - to right, - rgba(128, 200, 128, 0.0), - rgba(128, 200, 128, 0.5), - rgba(128, 200, 128, 0.0) - ) 0 100%; - animation: moveRight 2000ms linear infinite; -} \ No newline at end of file diff --git a/src/components/progress/progress.template.html b/src/components/progress/progress.template.html deleted file mode 100644 index 7df81f0819667454c5aa5127a780a94a557d1ae6..0000000000000000000000000000000000000000 --- a/src/components/progress/progress.template.html +++ /dev/null @@ -1,3 +0,0 @@ -<div class="progress rounded-0"> - <div [style.width]="progressPercent" class="progress-bar bg-success rounded-0" role="progressbar"></div> -</div> \ No newline at end of file diff --git a/src/components/radiolist/radiolist.component.ts b/src/components/radiolist/radiolist.component.ts deleted file mode 100644 index b9b97ad6f64f2f325c47ef051bfa81d8306a1cef..0000000000000000000000000000000000000000 --- a/src/components/radiolist/radiolist.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core"; - -@Component({ - selector: 'radio-list', - templateUrl: './radiolist.template.html', - styleUrls: [ - './radiolist.style.css', - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class RadioList { - @Input() - public listDisplay: (item: any) => string = (obj) => obj.name - - @Output() - public itemSelected: EventEmitter<any> = new EventEmitter() - - @Input() - public selectedItem: any | null = null - - @Input() - public inputArray: IHasExtraButtons[] = [] - - @Input() - public ulClass: string = '' - - @Input() public checkSelected: (selectedItem: any, item: any) => boolean = (si, i) => si === i - - @Output() public extraBtnClicked = new EventEmitter<IExraBtnClickEvent>() - - public handleExtraBtnClick(extraBtn: IExtraButton, inputItem: any, event: MouseEvent) { - this.extraBtnClicked.emit({ - extraBtn, - inputItem, - event, - }) - } - - public overflowText(event) { - return (event.offsetWidth < event.scrollWidth) - } -} - -export interface IExtraButton { - name: string - faIcon: string - class?: string -} - -export interface IHasExtraButtons { - extraButtons?: IExtraButton[] -} - -export interface IExraBtnClickEvent { - extraBtn: IExtraButton - inputItem: any - event: MouseEvent -} diff --git a/src/components/radiolist/radiolist.style.css b/src/components/radiolist/radiolist.style.css deleted file mode 100644 index d293cda69f806438eef820f796f1f4b075d60699..0000000000000000000000000000000000000000 --- a/src/components/radiolist/radiolist.style.css +++ /dev/null @@ -1,73 +0,0 @@ -:host-context([darktheme="true"]) ul -{ - background-color:rgba(30,30,30); -} - -:host-context([darktheme="true"]) li[role="menuitem"] -{ - color:rgba(255,255,255,0.8); -} - -:host-context([darktheme="true"]) li[role="menuitem"]:hover -{ - cursor:default; - background-color:rgba(128,128,128,0.2); -} - - -:host-context([darktheme="false"]) ul -{ - background-color:rgba(255,255,255); -} -:host-context([darktheme="false"]) li[role="menuitem"]:hover -{ - cursor:default; - background-color:rgba(128,128,128,0.2); - opacity:0.85; -} -li[role="menuitem"] -{ - transition : opacity 0.3s ease,background-color 0.2s ease ; - opacity:0.75; -} - - - -li[role="menuitem"] -{ - padding:0.5em 0.8em; - border-radius:0px; - cursor:default; -} - -ul -{ - width:100%; - overflow-x:hidden; - display:inline-block; -} - -ul,span.dropdown-item-1 -{ - padding:0px; - border-radius:0px; - white-space: nowrap; - border:none; - overflow: hidden; - text-overflow: ellipsis -} - -:host-context([darktheme="true"]) .radioListMenu { - border-color: white; -} -:host-context([darktheme="false"]) .radioListMenu { - border-color: black; -} -:host-context([isMobile="true"]) .radioListMenu { - opacity: 1; - border-style: solid; - border-width: 0px 1px 1px 1px; -} -:host-context([isMobile="false"]) .radioListMenu { - opacity: 0.8; -} \ No newline at end of file diff --git a/src/components/radiolist/radiolist.template.html b/src/components/radiolist/radiolist.template.html deleted file mode 100644 index d60939d5579e10c99a9518a7cf12c8db16e26f38..0000000000000000000000000000000000000000 --- a/src/components/radiolist/radiolist.template.html +++ /dev/null @@ -1,28 +0,0 @@ -<ul - [ngClass]="ulClass" - class="radioListMenu" - role="menu"> - - <li - *ngFor="let input of inputArray; let i = index" - class="d-flex justify-content-between" - [ngClass]="checkSelected(selectedItem, input) ? 'selected' : 'notselected'" - role="menuitem" - (click)="itemSelected.emit({previous: selectedItem, current: input})" - [matTooltip]="input.tooltipText"> - - <span class="dropdown-item-1 textSpan" - #DropDownText - [innerHTML]="listDisplay(input)" - [ngClass]="checkSelected(selectedItem, input) ? 'font-weight-bold' : ''"> - </span> - - <ng-container *ngIf="input.extraButtons as extraButtons"> - <span *ngFor="let extraBtn of extraButtons" - [ngClass]="extraBtn.class" - (click)="handleExtraBtnClick(extraBtn, input, $event)"> - <i [ngClass]="extraBtn.faIcon"></i> - </span> - </ng-container> - </li> -</ul> \ No newline at end of file diff --git a/src/components/readmore/index.ts b/src/components/readmore/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..170dc3e0a6b5fd65ad708b23e9865cd3ed1c39d0 --- /dev/null +++ b/src/components/readmore/index.ts @@ -0,0 +1,2 @@ +export { ReadmoreModule } from './module' +export { ReadmoreComponent } from './readmoreCmp/readmore.component' \ No newline at end of file diff --git a/src/components/readmore/module.ts b/src/components/readmore/module.ts new file mode 100644 index 0000000000000000000000000000000000000000..255b721bcc67ce576a20103f7f8e13c87c387d39 --- /dev/null +++ b/src/components/readmore/module.ts @@ -0,0 +1,21 @@ +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { HoverableModule } from "../hoverable"; +import { ReadmoreComponent } from "./readmoreCmp/readmore.component"; + +@NgModule({ + imports: [ + CommonModule, + BrowserAnimationsModule, + HoverableModule, + ], + declarations: [ + ReadmoreComponent + ], + exports: [ + ReadmoreComponent + ] +}) + +export class ReadmoreModule{} \ No newline at end of file diff --git a/src/components/readmoore/readmore.animations.ts b/src/components/readmore/readmoreCmp/readmore.animations.ts similarity index 100% rename from src/components/readmoore/readmore.animations.ts rename to src/components/readmore/readmoreCmp/readmore.animations.ts diff --git a/src/components/readmoore/readmore.component.ts b/src/components/readmore/readmoreCmp/readmore.component.ts similarity index 100% rename from src/components/readmoore/readmore.component.ts rename to src/components/readmore/readmoreCmp/readmore.component.ts diff --git a/src/components/readmoore/readmore.style.css b/src/components/readmore/readmoreCmp/readmore.style.css similarity index 78% rename from src/components/readmoore/readmore.style.css rename to src/components/readmore/readmoreCmp/readmore.style.css index eb18ca91a602ea4ace77c30fa2ab2e43a4d2fe11..eda7922c5fa7532c99c4db4744aa95fd479c54af 100644 --- a/src/components/readmoore/readmore.style.css +++ b/src/components/readmore/readmoreCmp/readmore.style.css @@ -1,16 +1,12 @@ -div[content] +div.readmore-content { overflow:hidden; } -div[sliver] +div.readmore-sliver { width:100%; display:flex; flex-direction: column; align-items: center; -} - -div[sliver] -{ background-color: rgba(128,128,128,0.1); } diff --git a/src/components/readmoore/readmore.template.html b/src/components/readmore/readmoreCmp/readmore.template.html similarity index 88% rename from src/components/readmoore/readmore.template.html rename to src/components/readmore/readmoreCmp/readmore.template.html index 20fdb98aeca3cfb760d23090d3cde70888b5c63c..2fa6c9975b6b2aa49712109c30512925157eebef 100644 --- a/src/components/readmoore/readmore.template.html +++ b/src/components/readmore/readmoreCmp/readmore.template.html @@ -1,6 +1,6 @@ <div [@collapseState] = "{ value : show ? 'visible' : 'collapsed', params : { collapsedHeight: collapsedHeight, fullHeight: fullHeight, animationLength: animationLength } }" - content> + class="readmore-content"> <div #contentContainer> <ng-content> </ng-content> @@ -8,7 +8,7 @@ </div> <div (click)="toggle($event)" - sliver + class="readmore-sliver" [hoverable]="{translateY:-1}"> <i diff --git a/src/components/sleightOfHand/soh.component.ts b/src/components/sleightOfHand/soh.component.ts deleted file mode 100644 index 14f80e6888b5fad39f415e68af2d89295a31190d..0000000000000000000000000000000000000000 --- a/src/components/sleightOfHand/soh.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ChangeDetectionStrategy, Component, HostBinding, HostListener, Input } from "@angular/core"; - -@Component({ - selector: 'sleight-of-hand', - templateUrl: './soh.template.html', - styleUrls: [ - './soh.style.css', - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class SleightOfHand { - - @HostBinding('class.do-not-close') - get doNotCloseClass() { - return this.doNotClose || this.focusInStatus - } - - @HostListener('focusin') - public focusInHandler() { - this.focusInStatus = true - } - - @HostListener('focusout') - public focusOutHandler() { - this.focusInStatus = false - } - - private focusInStatus: boolean = false - - @Input() - public doNotClose: boolean = false -} diff --git a/src/components/sleightOfHand/soh.style.css b/src/components/sleightOfHand/soh.style.css deleted file mode 100644 index 701612d06f07969b4c9d76b2bc5dbd279b359a84..0000000000000000000000000000000000000000 --- a/src/components/sleightOfHand/soh.style.css +++ /dev/null @@ -1,28 +0,0 @@ -:host:not(.do-not-close):not(:hover) > .sleight-of-hand-back, -:host:not(.do-not-close):hover > .sleight-of-hand-front, -:host(.do-not-close) > .sleight-of-hand-front -{ - opacity: 0; - pointer-events: none; -} - -:host * -{ - transition: opacity 300ms ease-in-out; -} - -:host -{ - position: relative; -} - -:host > .sleight-of-hand-front -{ - position: relative; -} - -:host > .sleight-of-hand-back -{ - position: absolute; - z-index: 1; -} \ No newline at end of file diff --git a/src/components/sleightOfHand/soh.template.html b/src/components/sleightOfHand/soh.template.html deleted file mode 100644 index fca028aa043b8a5c77fdb98261a0e6d5a57dd19c..0000000000000000000000000000000000000000 --- a/src/components/sleightOfHand/soh.template.html +++ /dev/null @@ -1,9 +0,0 @@ -<div class="sleight-of-hand-back"> - <ng-content select="[sleight-of-hand-back]"> - </ng-content> -</div> - -<div class="sleight-of-hand-front"> - <ng-content select="[sleight-of-hand-front]"> - </ng-content> -</div> \ No newline at end of file diff --git a/src/components/timer/timer.component.ts b/src/components/timer/timer.component.ts deleted file mode 100644 index c5b495cdacbf263846f25cefc1c31efeb33f6437..0000000000000000000000000000000000000000 --- a/src/components/timer/timer.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; -import { timedValues } from "../../util/generator" - -@Component({ - selector: 'timer-component', - templateUrl: './timer.template.html', - styleUrls: [ - './timer.style.css', - ], -}) - -export class TimerComponent implements OnInit, OnDestroy { - @Input() private timeout: number = 500 - @Input() private pause: boolean = false - @Output() public timerEnd: EventEmitter<boolean> = new EventEmitter() - - private generator: IterableIterator<any> = null - public progress: number = 0 - private baseProgress: number = 0 - - private rafCbId: number - private rafCb = () => { - if (this.pause) { - this.generator = null - this.baseProgress = this.progress - } else { - if (this.generator === null) { - this.generator = timedValues(this.timeout * (1 - this.baseProgress), 'linear') - } else { - const next = this.generator.next() - this.progress = this.baseProgress + (1 - this.baseProgress) * next.value - if (next.done) { - this.timerEnd.emit(true) - return - } - } - } - this.rafCbId = requestAnimationFrame(this.rafCb) - } - - get transform() { - return `translateX(${this.progress * 100}%)` - } - - public ngOnInit() { - this.rafCbId = requestAnimationFrame(this.rafCb) - } - - public ngOnDestroy() { - if (this.rafCbId) { cancelAnimationFrame(this.rafCbId) } - } -} diff --git a/src/components/timer/timer.style.css b/src/components/timer/timer.style.css deleted file mode 100644 index ad5611e32d1c2256c7d887058c0227373c6cbeea..0000000000000000000000000000000000000000 --- a/src/components/timer/timer.style.css +++ /dev/null @@ -1,14 +0,0 @@ -:host -{ - display: block; - width: 100%; - height: 100%; - overflow: hidden; -} - -div -{ - background-color:rgba(128, 128, 128, 0.2); - height:100%; - width:100%; -} \ No newline at end of file diff --git a/src/components/timer/timer.template.html b/src/components/timer/timer.template.html deleted file mode 100644 index 6e13c9405bd33ffe268229f6cbaae57d6af45ece..0000000000000000000000000000000000000000 --- a/src/components/timer/timer.template.html +++ /dev/null @@ -1,2 +0,0 @@ -<div [style.transform] = "transform"> -</div> \ No newline at end of file diff --git a/src/components/vButton/vButton.component.ts b/src/components/vButton/vButton.component.ts index 63eda444bf09774fe0c3e3ffc25cd77fe5fbf4ac..f2720905b3ff3bb9ff75a5b01d9add65643b552e 100644 --- a/src/components/vButton/vButton.component.ts +++ b/src/components/vButton/vButton.component.ts @@ -1,4 +1,8 @@ import { Component, Input, ChangeDetectionStrategy } from "@angular/core"; +import { Subject } from "rxjs"; +import { map, startWith } from "rxjs/operators"; + +type TIVBColor = 'default' | 'primary' | 'accent' | 'warn' @Component({ selector: 'iav-v-button', @@ -11,8 +15,15 @@ import { Component, Input, ChangeDetectionStrategy } from "@angular/core"; }) export class IAVVerticalButton{ - @Input() color: 'default' | 'primary' | 'accent' | 'warng' = 'default' - get class(){ - return `d-flex flex-column align-items-center iv-custom-comp ${this.color} h-100` + + private color$ = new Subject<TIVBColor>() + public class$ = this.color$.pipe( + startWith('default'), + map(colorCls => `d-flex flex-column align-items-center iv-custom-comp ${colorCls} h-100`) + ) + + @Input() + set color(val: TIVBColor){ + this.color$.next(val) } } \ No newline at end of file diff --git a/src/components/vButton/vButton.template.html b/src/components/vButton/vButton.template.html index 539d1b897e89d6f0d972c7aff567853cc3268963..347e28236f83c3dddc879cadea20edb0a3502ea1 100644 --- a/src/components/vButton/vButton.template.html +++ b/src/components/vButton/vButton.template.html @@ -1,4 +1,4 @@ -<div [class]="class"> +<div [class]="class$ | async"> <div class="icon-container flex-grow-0 flex-shrink-0"> <ng-content select="[iav-v-button-icon]"> </ng-content> diff --git a/src/messaging/nmvSwc/index.spec.ts b/src/messaging/nmvSwc/index.spec.ts index 86862ed2a2a3eda0898f813ec8f083c94025421b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/messaging/nmvSwc/index.spec.ts +++ b/src/messaging/nmvSwc/index.spec.ts @@ -1,66 +0,0 @@ -import { IAV_IDS, IAV_VOXEL_SIZES_NM } from './index' - -const waxholmTemplates = require('!json-loader!src/res/ext/waxholmRatV2_0.json') -const allenTemplates = require('!json-loader!src/res/ext/allenMouse.json') -const colinTemplates = require('!json-loader!src/res/ext/colin.json') -const mniTemplates = require('!json-loader!src/res/ext/MNI152.json') -const bbTemplates = require('!json-loader!src/res/ext/bigbrain.json') - - -const ratNehubaConfig = require('!json-loader!src/res/ext/waxholmRatV2_0NehubaConfig.json') -const mouseNehubaConfig = require('!json-loader!src/res/ext/allenMouseNehubaConfig.json') -const colinNehubaConfig = require('!json-loader!src/res/ext/colinNehubaConfig.json') -const icbmNehubaConfig = require('!json-loader!src/res/ext/MNI152NehubaConfig.json') -const bbNehubaConfig = require('!json-loader!src/res/ext/bigbrainNehubaConfig.json') - -const tmplArr = [ - waxholmTemplates, - allenTemplates, - colinTemplates, - mniTemplates, - bbTemplates, -] - -const configArr = [ - ratNehubaConfig, - mouseNehubaConfig, - colinNehubaConfig, - icbmNehubaConfig, - bbNehubaConfig, -].map(cfg => { - - return { - layerNames: Object.keys( - cfg['dataset']['initialNgState']['layers'] - ), - voxelSize: cfg['dataset']['initialNgState']['navigation']['pose']['position']['voxelSize'] - } -}) - -describe('> messaging/nmvSwc', () => { - for (const tmplKey in IAV_IDS) { - describe(`> ${tmplKey}`, () => { - let tmpl, config - beforeAll(() => { - tmpl = tmplArr.find(t => t['@id'] === IAV_IDS[tmplKey]) - config = tmpl && configArr.find(cfg => - cfg.layerNames.includes(tmpl['ngId']) - ) - }) - - it('> should be able to find tmpl by id', () => { - expect(tmpl).toBeTruthy() - }) - - it('> should be able to find the config', () => { - expect(config).toBeTruthy() - }) - - it('> voxelSize should match the hardcoded value', () => { - expect( - config.voxelSize - ).toEqual(IAV_VOXEL_SIZES_NM[tmplKey]) - }) - }) - } -}) diff --git a/src/res/css/extra_styles.css b/src/res/css/extra_styles.css index 4db5bf3001a3386c61b72c36ba8190fd974e921e..9ff20c44eb1333fd05c64ce56c8db598aee09b25 100644 --- a/src/res/css/extra_styles.css +++ b/src/res/css/extra_styles.css @@ -755,11 +755,11 @@ kg-dataset-previewer > img { opacity: 0.5; transition: opacity 200ms ease-in-out; + cursor: move; } .hover-grab:hover { - cursor: grab; opacity: 1.0; } diff --git a/src/util/fn.spec.ts b/src/util/fn.spec.ts index bbdbff61026839a3ce6a020d75bc25a4a5cd1aca..61bb2fd8cb23665bc85aacb76b298f026d2f89aa 100644 --- a/src/util/fn.spec.ts +++ b/src/util/fn.spec.ts @@ -8,22 +8,44 @@ import { isSame, getGetRegionFromLabelIndexId, switchMapWaitFor, bufferUntil } f describe(`> util/fn.ts`, () => { describe('> #getGetRegionFromLabelIndexId', () => { - const colinsJson = require('!json-loader!../res/ext/colin.json') const COLIN_JULICHBRAIN_LAYER_NAME = `COLIN_V25_LEFT_NG_SPLIT_HEMISPHERE` - const COLIN_V25_ID = 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-26' - + const LABEL_INDEX = 12 + const dummyParc = { + regions: [ + { + name: 'foo-bar', + children: [ + { + name: 'foo-bar-region-ba', + ngId: `${COLIN_JULICHBRAIN_LAYER_NAME}-ba`, + labelIndex: LABEL_INDEX + }, + { + name: 'foo-bar-region+1', + ngId: COLIN_JULICHBRAIN_LAYER_NAME, + labelIndex: LABEL_INDEX + 1 + }, + { + name: 'foo-bar-region', + ngId: COLIN_JULICHBRAIN_LAYER_NAME, + labelIndex: LABEL_INDEX + } + ] + } + ] + } it('translateds hoc1 from labelIndex to region', () => { const getRegionFromlabelIndexId = getGetRegionFromLabelIndexId({ parcellation: { - ...colinsJson.parcellations.find(p => p['@id'] === COLIN_V25_ID), + ...dummyParc, updated: true, }, }) - const fetchedRegion = getRegionFromlabelIndexId({ labelIndexId: `${COLIN_JULICHBRAIN_LAYER_NAME}#116` }) + const fetchedRegion = getRegionFromlabelIndexId({ labelIndexId: `${COLIN_JULICHBRAIN_LAYER_NAME}#${LABEL_INDEX}` }) expect(fetchedRegion).toBeTruthy() - expect(fetchedRegion.fullId.kg.kgId).toEqual('c9753e82-80ca-4074-a704-9dd2c4c0d58b') + expect(fetchedRegion.name).toEqual('foo-bar-region') }) }) diff --git a/src/widget/widgetUnit/widgetUnit.style.css b/src/widget/widgetUnit/widgetUnit.style.css index 55c1afe8cc3695399cb4946b03df7532b416e3bd..9002aa7d4dcb155fb9e4fbd98ca065576625e20b 100644 --- a/src/widget/widgetUnit/widgetUnit.style.css +++ b/src/widget/widgetUnit/widgetUnit.style.css @@ -30,9 +30,8 @@ div[widgetUnitHeading] margin-left:0.5em; } -panel-component[widgetUnitPanel] +.widget-body { - display:block; min-width:280px; } @@ -41,16 +40,6 @@ panel-component[widgetUnitPanel] cursor : move; } -:host > panel-component -{ - max-width: 100%; - width: 300px; - border-width: 1px !important; - border: solid; - border-color: rgba(0, 0, 0, 0); - box-sizing: border-box; -} - @keyframes blinkDark { 0% { diff --git a/src/widget/widgetUnit/widgetUnit.template.html b/src/widget/widgetUnit/widgetUnit.template.html index d86af225904795724317d11ba8a068ef59107a7b..6af4e0338400bd94e1e36f6daad5708aa1a0c11c 100644 --- a/src/widget/widgetUnit/widgetUnit.template.html +++ b/src/widget/widgetUnit/widgetUnit.template.html @@ -1,47 +1,42 @@ -<panel-component - [attr.aria-label]="'Widget for ' + title" - widgetUnitPanel - [ngClass]="{'blinkOn': blinkOn}" - [bodyCollapsable] = "state === 'docked'" +<mat-card cdkDrag [cdkDragDisabled]="state === 'docked'" - cdkDrag> - <div - widgetUnitHeading - heading - cdkDragHandle> - <div title> - <div *ngIf="!titleHTML"> - {{ title }} - </div> - <div [innerHTML]="titleHTML" *ngIf="titleHTML"> + [ngClass]="{'blinkOn': blinkOn, 'bodyCollapsable': state === 'docked'}" + class="widget-body"> - </div> - </div> - <div icons> - <ng-container> - <i *ngIf="canBeDocked && state === 'floating'" - (click)="dock($event)" - class="fas fa-window-minimize" - [hoverable]="hoverableConfig"></i> - <i *ngIf="state === 'docked'" - (click)="undock($event)" - class="fas fa-window-restore" - [hoverable]="hoverableConfig"></i> - </ng-container> + <!-- body --> + <mat-card-content> + <!-- top bar, drag handle etc --> + <div class="d-flex align-items-center"> + <!-- drag handle --> + <span class="hover-grab p-2" + cdkDragHandle> + <i class="fas fa-grip-vertical"></i> + </span> + + <div class="flex-grow-1"></div> - <i *ngIf="exitable" - aria-label="close" - (click)="exit($event)" - class="fas fa-times" - [hoverable] ="hoverableConfig"></i> + <!-- close btn --> + <button mat-icon-button + (click)="exit($event)"> + <i class="fas fa-times"></i> + </button> </div> - <progress-bar [progress]="progressIndicator" *ngIf="showProgress" progressBar> - </progress-bar> - </div> - <div widgetUnitBody body> + <h4 class="mat-h4"> + <ng-template [ngTemplateOutlet]="titleTmpl"> + </ng-template> + </h4> <ng-template #container> - </ng-template> + </mat-card-content> +</mat-card> + + +<!-- title tmpl --> +<ng-template #titleTmpl> + <div *ngIf="!titleHTML"> + {{ title }} + </div> + <div [innerHTML]="titleHTML" *ngIf="titleHTML"> </div> -</panel-component> +</ng-template>