aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/app')
-rw-r--r--frontend/src/app/Shared.ts12
-rw-r--r--frontend/src/app/_elements/folder/folder.component.css25
-rw-r--r--frontend/src/app/_elements/folder/folder.component.html59
-rw-r--r--frontend/src/app/_elements/folder/folder.component.ts37
-rw-r--r--frontend/src/app/_elements/reactive-background/reactive-background.component.ts19
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.css17
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.html11
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.ts74
8 files changed, 194 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;
}