diff options
Diffstat (limited to 'frontend')
9 files changed, 217 insertions, 60 deletions
diff --git a/frontend/src/app/Shared.ts b/frontend/src/app/Shared.ts index 59a2716d..d088fff9 100644 --- a/frontend/src/app/Shared.ts +++ b/frontend/src/app/Shared.ts @@ -1,4 +1,4 @@ -import { ElementRef } from "@angular/core"; +import { ElementRef, EventEmitter } from "@angular/core"; import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { AlertDialogComponent } from './_modals/alert-dialog/alert-dialog.component'; @@ -27,18 +27,24 @@ class Shared { }); } } - openYesNoDialog(title: string, message: string,yesFunction:Function): void { + openYesNoDialog(title: string, message: string, yesFunction: Function): void { if (this.dialog) { const dialogRef = this.dialog.open(YesNoDialogComponent, { width: '350px', - data: { title: title, message: message,yesFunction} + data: { title: title, message: message, yesFunction } }); dialogRef.afterClosed().subscribe(res => { //nesto }); } } + + bgScroll: EventEmitter<number> = new EventEmitter(); + + emitBGScrollEvent(value: number) { + this.bgScroll.emit(value); + } } export default new Shared(false);
\ No newline at end of file diff --git a/frontend/src/app/_elements/folder/folder.component.css b/frontend/src/app/_elements/folder/folder.component.css index a1c1124a..3e865576 100644 --- a/frontend/src/app/_elements/folder/folder.component.css +++ b/frontend/src/app/_elements/folder/folder.component.css @@ -1,7 +1,7 @@ #folder { - position: absolute; + /*position: absolute; left: 50%; - transform: translateX(-50%); + transform: translateX(-50%);*/ } #tabs { @@ -22,9 +22,10 @@ align-items: center; position: relative; overflow-x: hidden; - background-color: var(--ns-bg-dark-100); height: 2.5rem; + background-color: var(--ns-bg-dark-100); border-color: var(--ns-primary); + color: var(--ns-primary); border-style: solid; border-width: 1px 1px 0 1px; } @@ -37,6 +38,7 @@ .selected-tab { height: 3rem; background-color: var(--ns-primary); + color: var(--offwhite); } .hover-tab { @@ -91,7 +93,7 @@ background-color: var(--ns-bg-dark-50); width: 100%; height: 36rem; - backdrop-filter: blur(2px); + /*backdrop-filter: blur(2px);*/ border-color: var(--ns-primary); border-style: solid; border-width: 1px 1px 1px 1px; @@ -104,21 +106,18 @@ justify-content: center; } -.folder-bottom-button { +.bottom-button { font-size: large; position: relative; - background-color: var(--ns-bg-dark-50); + background-color: var(--ns-primary); width: 10rem; - height: 2.5rem; - display: flex; - flex-direction: row; - justify-content: space-around; - align-items: center; + height: 2.3rem; border-color: var(--ns-primary); border-style: solid; border-width: 0px 1px 1px 1px; } -.folder-bottom-button:hover { - background-color: var(--ns-primary); +.rounded-bottom { + border-top-right-radius: 0; + border-top-left-radius: 0; }
\ No newline at end of file diff --git a/frontend/src/app/_elements/folder/folder.component.html b/frontend/src/app/_elements/folder/folder.component.html index 895ac84e..c3da30fc 100644 --- a/frontend/src/app/_elements/folder/folder.component.html +++ b/frontend/src/app/_elements/folder/folder.component.html @@ -1,12 +1,12 @@ <div id="folder" style="width: 60rem;"> - <div id="tabs" class="text-offwhite"> + <div id="tabs"> <div id="new-file-tab" class="folder-tab p-1 rounded-top" [style]="'z-index:' + newFileZIndex() + ' ;'" [ngClass]="{'selected-tab' : newFileSelected, 'hover-tab' : hoveringOverFileIndex == -2}"> <mat-icon class="text-offwhite">add</mat-icon> <a class="stretched-link tab-link" (click)="selectNewFile()" (mouseenter)="hoverOverFile(-2)" (mouseleave)="hoverOverFile(-1)"> <p class="m-1" *ngIf="newFile != undefined">{{newFile.name}}</p> </a> </div> - <div class="folder-tab p-1 rounded-top" *ngFor="let file of files; let i = index" [style]="'z-index:' + calcZIndex(i) + ' ;'" [ngClass]="{'selected-tab' : selectedFileIndex == i, 'hover-tab' : hoveringOverFileIndex == i}"> + <div class="folder-tab p-1 rounded-top" *ngFor="let file of filteredFiles; let i = index" [style]="'z-index:' + calcZIndex(i) + ' ;'" [ngClass]="{'selected-tab' : selectedFileIndex == i, 'hover-tab' : hoveringOverFileIndex == i}"> <a class="m-1 stretched-link tab-link" (click)="selectFile(i)" (mouseenter)="hoverOverFile(i)" (mouseleave)="hoverOverFile(-1)">{{file.name}}</a> </div> </div> @@ -15,27 +15,22 @@ <div id="path" class="ps-2">{{folderName}} </div> <mat-icon>keyboard_arrow_right</mat-icon> - <div id="search"> + <div id="search" class="text-offwhite"> <mat-form-field> - <input matNativeControl> + <button matPrefix class="btn-clear input-icon"><mat-icon>search</mat-icon></button> + <input type="search" matInput name="search" [(ngModel)]="searchTerm" (input)="searchTermsChanged()"> + <button matSuffix class="btn-clear input-icon" (click)="clearSearchTerm()"><mat-icon>clear</mat-icon></button> </mat-form-field> </div> <div id="search-options"> <div id="collapseFilters" class="collapse collapse-horizontal"> - <mat-chip-list aria-label="filter selection"> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">timeline</mat-icon> - Regresioni - </mat-chip> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">looks_two</mat-icon> - Binarni klasifikacioni - </mat-chip> - <mat-chip class="text-offwhite ns-bg-dark-50"> - <mat-icon class="text-offwhite">auto_awesome_motion</mat-icon> - Multiklasifikacioni - </mat-chip> - </mat-chip-list> + + <mat-icon class="text-offwhite ">timeline</mat-icon> + Regresioni + <mat-icon class="text-offwhite ">looks_two</mat-icon> + Binarni klasifikacioni + <mat-icon class="text-offwhite ">auto_awesome_motion</mat-icon> + Multiklasifikacioni </div> <a class="tab-link p-1" data-bs-toggle="collapse" data-bs-target="#collapseFilters" aria-expanded="false" aria-controls="collapseFilters"> <mat-icon>filter_alt</mat-icon> @@ -50,19 +45,23 @@ </div> {{fileToDisplay ? fileToDisplay.name : 'No file selected.'}} {{selectedFileIndex}} {{hoveringOverFileIndex}} </div> - <div id="footer"> - <div class="folder-bottom-button text-offwhite rounded-bottom bubble" *ngIf="newFileSelected"> - <a class="tab-link stretched-link">Sačuvaj</a> - <div> - <mat-icon>check</mat-icon> + <div id="footer" [ngSwitch]="newFileSelected"> + <button mat-button (click)="saveNewFile()" class="bottom-button text-offwhite rounded-bottom" *ngSwitchCase="true"> + <div class="f-row"> + <div>Sačuvaj</div> + <div class="pt-1"> + <mat-icon>check</mat-icon> + </div> </div> - </div> - <div class="folder-bottom-button text-offwhite rounded-bottom bubble" *ngIf="!newFileSelected"> - <a class="tab-link stretched-link">Ok</a> - <div class="icon-double"> - <mat-icon>check</mat-icon> - <mat-icon>check</mat-icon> + </button> + <button mat-button (click)="ok()" class="bottom-button text-offwhite rounded-bottom" *ngSwitchCase="false"> + <div class="f-row"> + <div>Ok</div> + <div class="icon-double pt-1"> + <mat-icon>check</mat-icon> + <mat-icon>check</mat-icon> + </div> </div> - </div> + </button> </div> </div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/folder/folder.component.ts b/frontend/src/app/_elements/folder/folder.component.ts index 485a8dd7..91565f3c 100644 --- a/frontend/src/app/_elements/folder/folder.component.ts +++ b/frontend/src/app/_elements/folder/folder.component.ts @@ -20,11 +20,15 @@ export class FolderComponent implements OnInit { newFileSelected: boolean = true; selectedFileIndex: number = -1; + selectedFile?: (Dataset | Model); hoveringOverFileIndex: number = -1; fileToDisplay?: (Dataset | Model); @Output() selectedFileChanged: EventEmitter<(Dataset | Model)> = new EventEmitter(); + @Output() okPressed: EventEmitter<string> = new EventEmitter(); + + searchTerm: string = ''; constructor() { //PLACEHOLDER @@ -33,6 +37,9 @@ export class FolderComponent implements OnInit { new Dataset('Dijamanti'), new Dataset('Filmovi'), ] + + this.filteredFiles.length = 0; + this.filteredFiles.push(...this.files); } ngOnInit(): void { @@ -60,17 +67,19 @@ export class FolderComponent implements OnInit { if (!this.newFile) { this.createNewFile(); } - this.fileToDisplay = this.newFile; this.selectedFileIndex = -1; + this.fileToDisplay = this.newFile; + this.selectedFile = this.newFile; this.newFileSelected = true; this.selectedFileChanged.emit(this.newFile); } selectFile(index: number) { this.selectedFileIndex = index; - this.fileToDisplay = this.files[index]; + this.selectedFile = this.filteredFiles[index]; + this.fileToDisplay = this.filteredFiles[index]; this.newFileSelected = false; - this.selectedFileChanged.emit(this.files[index]); + this.selectedFileChanged.emit(this.selectedFile); } createNewFile() { @@ -81,6 +90,10 @@ export class FolderComponent implements OnInit { } } + ok() { + this.okPressed.emit(); + } + saveNewFile() { // TODO } @@ -97,6 +110,24 @@ export class FolderComponent implements OnInit { newFileZIndex() { return (this.files.length + 1); } + + clearSearchTerm() { + this.searchTerm = ''; + } + + filteredFiles: (Dataset | Model)[] = []; + + searchTermsChanged() { + this.filteredFiles.length = 0; + this.filteredFiles.push(...this.files.filter((file) => file.name.toLowerCase().includes(this.searchTerm.toLowerCase()))); + if (this.selectedFile) { + if (!this.filteredFiles.includes(this.selectedFile)) { + this.selectFile(-1); + } else { + this.selectedFileIndex = this.filteredFiles.indexOf(this.selectedFile); + } + } + } } export enum FolderType { diff --git a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts index 97387ac8..1a6157e3 100644 --- a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts +++ b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts @@ -1,5 +1,6 @@ import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { CookieService } from 'ngx-cookie-service'; +import Shared from 'src/app/Shared'; @Component({ selector: 'app-reactive-background', @@ -90,18 +91,32 @@ export class ReactiveBackgroundComponent implements AfterViewInit { this.drawBackground(); }, 1000 / 60); + + Shared.bgScroll.subscribe((amount) => { + this.scrollBackgroundFromSharedEvent(amount); + }) } private lastScrollY: number = 0; + scrollBackgroundFromSharedEvent(amount: number) { + const scrolledAmount = amount - this.lastScrollY; + this.scrollPoints(scrolledAmount); + this.lastScrollY = amount; + } + scrollBackground(e: Event) { const scrolledAmount = window.scrollY - this.lastScrollY; + this.scrollPoints(scrolledAmount); + this.lastScrollY = window.scrollY; + } + + scrollPoints(amount: number) { this.points.forEach((point, index) => { if (index > this.numPoints * this.fill) return; - point.y = point.y - (scrolledAmount / this.height) * this.scrollSpeed; + point.y = point.y - (amount / this.height) * this.scrollSpeed; this.keepPointWithinBounds(point); }) - this.lastScrollY = window.scrollY; } drawBackground() { diff --git a/frontend/src/app/_pages/experiment/experiment.component.css b/frontend/src/app/_pages/experiment/experiment.component.css index 5cb8c325..2fde8e7f 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.css +++ b/frontend/src/app/_pages/experiment/experiment.component.css @@ -29,4 +29,21 @@ mat-stepper { .label { color: white; +} + +.steps-container { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + overflow-y: auto; +} + +.step-content { + position: relative; + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; }
\ No newline at end of file diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html index 2c69ae9c..86b40cec 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.html +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -20,6 +20,7 @@ <div class="d-flex flex-colum align-items-center sidenav"> <mat-stepper orientation="vertical" (selectionChange)="changePage($event)"> <mat-step> + <!--editable="false"--> <ng-template matStepLabel><span class="label">Izvor podataka</span></ng-template> <ng-template matStepContent> <p>Izaberite vas izvor podataka</p> @@ -37,14 +38,14 @@ </mat-step> </mat-stepper> </div> - <div class="d-flex flex-colum w-100 position-relative"> - <div *ngIf="event==0"> - <app-folder></app-folder> + <div #stepsContainer class="steps-container"> + <div #steps id="step_1" class="step-content"> + <app-folder (okPressed)="goToPage(1)"></app-folder> </div> - <div *ngIf="event==1"> + <div #steps id="step_2" class="step-content"> <div class="text-offwhite" style="height: 100px;width: 100px;background-color: red;top:50%;left: 50%;position: absolute;">Insert odabir kolona</div> </div> - <div *ngIf="event==2"> + <div #steps id="step_3" class="step-content"> <div class="text-offwhite" style="height: 100px;width: 100px;background-color: blue;top:50%;left: 50%;position: absolute;">Insert treniranje</div> </div> </div> diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts index 2d623709..377866d1 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.ts +++ b/frontend/src/app/_pages/experiment/experiment.component.ts @@ -1,20 +1,86 @@ -import { Component, ViewEncapsulation } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, ViewChild, ViewChildren } from '@angular/core'; import { StepperSelectionEvent } from '@angular/cdk/stepper'; +import { MatStepper } from '@angular/material/stepper'; +import Shared from 'src/app/Shared'; + @Component({ selector: 'app-experiment', templateUrl: './experiment.component.html', styleUrls: ['./experiment.component.css'] }) -export class ExperimentComponent { +export class ExperimentComponent implements AfterViewInit { + + @ViewChild(MatStepper) stepper!: MatStepper; + @ViewChild('stepsContainer') stepsContainer!: ElementRef; + @ViewChildren('steps') steps!: ElementRef[]; event: number = 0; constructor() { } + stepHeight = this.calcStepHeight(); + + calcStepHeight() { + return window.innerHeight - 64; + } + + ngAfterViewInit(): void { + window.addEventListener('resize', () => { + this.updatePageHeight(); + }) + this.updatePageHeight(); + + setInterval(() => { + this.updatePageIfScrolled(); + }, 200); + + this.stepsContainer.nativeElement.addEventListener('scroll', (event: Event) => { + Shared.emitBGScrollEvent(this.stepsContainer.nativeElement.scrollTop); + }); + } + + updatePageIfScrolled() { + if (this.scrolling) return; + const currentPage = Math.round(this.stepsContainer.nativeElement.scrollTop / this.stepHeight) + this.stepper.selectedIndex = currentPage; + } + + updatePageHeight() { + this.stepHeight = this.calcStepHeight(); + const stepHeight = `${this.stepHeight}px`; + this.stepsContainer.nativeElement.style.minHeight = stepHeight; + this.steps.forEach(step => { + step.nativeElement.style.minHeight = stepHeight; + }) + } + changePage(event: StepperSelectionEvent) { - this.event = event.selectedIndex; - console.log(this.event); + this.updatePage(<number>event.selectedIndex) + } + + goToPage(pageNum: number) { + this.stepper.selectedIndex = pageNum; + this.updatePage(pageNum); + } + + updatePage(pageNum: number) { + this.event = pageNum; + let scrollAmount = 0; + this.steps.forEach((step, index) => { + if (index == pageNum) { + scrollAmount = step.nativeElement.offsetTop; + } + }) + this.scrolling = true; + setTimeout(() => { + this.scrolling = false; + }, 1000); + this.stepsContainer.nativeElement.scroll({ + top: scrollAmount, + behavior: 'smooth' //auto, smooth, initial, inherit + }); } + scrolling: boolean = false; } diff --git a/frontend/src/styles/helper.css b/frontend/src/styles/helper.css index 9c520ac3..875b94f1 100644 --- a/frontend/src/styles/helper.css +++ b/frontend/src/styles/helper.css @@ -51,4 +51,27 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; +} + +.btn-clear { + border: unset; + background-color: unset; + outline: unset; + position: relative; +} + +.input-icon { + color: var(--offwhite); + transform: translateY(25%); +} + +.input-icon:hover { + color: var(--ns-primary); +} + +.f-row { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; }
\ No newline at end of file |