From 87b1858bfb9d53f9932767d48e1b21bdc7d536fb Mon Sep 17 00:00:00 2001 From: Danijel Anđelković Date: Sun, 17 Apr 2022 21:56:08 +0200 Subject: Promenio komponentu za iscrtavanje reaktivne pozadine tako da je transparentna, dodao komponentu za iscrtavanje gradijentne pozadine. Ispravio razne BUG-ove vezane za reaktivnu pozadinu, i promenio stil. --- .../gradient-background.component.css | 0 .../gradient-background.component.html | 1 + .../gradient-background.component.spec.ts | 25 ++++++ .../gradient-background.component.ts | 47 ++++++++++++ .../reactive-background.component.html | 2 +- .../reactive-background.component.ts | 88 +++++++++++++++------- .../app/_pages/playground/playground.component.css | 0 .../_pages/playground/playground.component.html | 1 + .../_pages/playground/playground.component.spec.ts | 25 ++++++ .../app/_pages/playground/playground.component.ts | 15 ++++ frontend/src/app/app-routing.module.ts | 2 + frontend/src/app/app.component.html | 8 +- frontend/src/app/app.module.ts | 6 +- 13 files changed, 189 insertions(+), 31 deletions(-) create mode 100644 frontend/src/app/_elements/gradient-background/gradient-background.component.css create mode 100644 frontend/src/app/_elements/gradient-background/gradient-background.component.html create mode 100644 frontend/src/app/_elements/gradient-background/gradient-background.component.spec.ts create mode 100644 frontend/src/app/_elements/gradient-background/gradient-background.component.ts create mode 100644 frontend/src/app/_pages/playground/playground.component.css create mode 100644 frontend/src/app/_pages/playground/playground.component.html create mode 100644 frontend/src/app/_pages/playground/playground.component.spec.ts create mode 100644 frontend/src/app/_pages/playground/playground.component.ts diff --git a/frontend/src/app/_elements/gradient-background/gradient-background.component.css b/frontend/src/app/_elements/gradient-background/gradient-background.component.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/_elements/gradient-background/gradient-background.component.html b/frontend/src/app/_elements/gradient-background/gradient-background.component.html new file mode 100644 index 00000000..3f30c35e --- /dev/null +++ b/frontend/src/app/_elements/gradient-background/gradient-background.component.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/frontend/src/app/_elements/gradient-background/gradient-background.component.spec.ts b/frontend/src/app/_elements/gradient-background/gradient-background.component.spec.ts new file mode 100644 index 00000000..969c73b7 --- /dev/null +++ b/frontend/src/app/_elements/gradient-background/gradient-background.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GradientBackgroundComponent } from './gradient-background.component'; + +describe('GradientBackgroundComponent', () => { + let component: GradientBackgroundComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ GradientBackgroundComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(GradientBackgroundComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/gradient-background/gradient-background.component.ts b/frontend/src/app/_elements/gradient-background/gradient-background.component.ts new file mode 100644 index 00000000..1414bc60 --- /dev/null +++ b/frontend/src/app/_elements/gradient-background/gradient-background.component.ts @@ -0,0 +1,47 @@ +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; + +@Component({ + selector: 'app-gradient-background', + templateUrl: './gradient-background.component.html', + styleUrls: ['./gradient-background.component.css'] +}) +export class GradientBackgroundComponent implements AfterViewInit { + + @ViewChild('holder') holderRef!: ElementRef; + private holder!: HTMLDivElement; + + + @Input() colorHorizontal1 = 'rgba(0, 8, 45, 0.5)'; + @Input() colorHorizontal2 = 'rgba(0, 52, 89, 0.5)'; + + @Input() colorVertical1 = 'rgba(0, 52, 89, 0.5)'; + @Input() colorVertical2 = 'rgba(0, 152, 189, 0.5)'; + + constructor() { } + + color: string = this.gradientHorizontal(); + + private width = 0; + private height = 0; + + gradientHorizontal(): string { + return `linear-gradient(90deg, ${this.colorHorizontal1} 0%, ${this.colorHorizontal2} 50%, ${this.colorHorizontal1} 100%), linear-gradient(0deg, ${this.colorVertical1} 0%, ${this.colorVertical2} 100%)`; + } + + resize() { + this.width = window.innerWidth; + this.height = window.innerHeight; + + this.holder.style.width = this.width + 'px'; + this.holder.style.height = this.height + 'px'; + } + + ngAfterViewInit(): void { + this.holder = this.holderRef.nativeElement; + + window.addEventListener('resize', () => this.resize()); + this.resize(); + + } + +} diff --git a/frontend/src/app/_elements/reactive-background/reactive-background.component.html b/frontend/src/app/_elements/reactive-background/reactive-background.component.html index 756952fb..c63dd6ac 100644 --- a/frontend/src/app/_elements/reactive-background/reactive-background.component.html +++ b/frontend/src/app/_elements/reactive-background/reactive-background.component.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file 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 980e3e6f..9d7f5522 100644 --- a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts +++ b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts @@ -1,14 +1,17 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; @Component({ selector: 'app-reactive-background', templateUrl: './reactive-background.component.html', styleUrls: ['./reactive-background.component.css'] }) -export class ReactiveBackgroundComponent implements OnInit { +export class ReactiveBackgroundComponent implements AfterViewInit { + + @ViewChild('bgCanvas') canvasRef!: ElementRef; @Input() numPoints: number = 450; @Input() speed: number = 0.001; // 0-1 + @Input() scrollSpeed: number = 1; @Input() maxSize: number = 6; @Input() minDistance: number = 0.07; //0-1 @@ -25,8 +28,8 @@ export class ReactiveBackgroundComponent implements OnInit { private height = 200; private ratio = 1; - private canvas?: HTMLCanvasElement; - private ctx?: CanvasRenderingContext2D; + private canvas!: HTMLCanvasElement; + private ctx!: CanvasRenderingContext2D; private time: number = 0; @@ -35,14 +38,22 @@ export class ReactiveBackgroundComponent implements OnInit { private mouseX = 0; private mouseY = 0; - ngOnInit(): void { - + ngAfterViewInit(): void { document.addEventListener('mousemove', (e) => { this.mouseX = e.clientX / this.width; this.mouseY = e.clientY / this.height; }) - this.canvas = (document.getElementById('bgCanvas')); + document.addEventListener('mouseleave', _ => { + this.mouseX = -1; + this.mouseY = -1; + }) + + document.addEventListener('scroll', (e) => { + this.scrollBackground(e); + }) + + this.canvas = (this.canvasRef.nativeElement); const ctx = this.canvas.getContext('2d'); if (ctx) { this.ctx = ctx; @@ -68,17 +79,28 @@ export class ReactiveBackgroundComponent implements OnInit { }, 1000 / 60); } + private lastScrollY: number = 0; + + scrollBackground(e: Event) { + const scrolledAmount = window.scrollY - this.lastScrollY; + this.points.forEach((point) => { + point.y = point.y - (scrolledAmount / this.height) * this.scrollSpeed; + this.keepPointWithinBounds(point); + }) + this.lastScrollY = window.scrollY; + } + drawBackground() { if (!this.ctx || !this.canvas) return; this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - this.ctx.fillStyle = this.bgColor; - this.ctx.fillRect(0, 0, this.width, this.height); + //this.ctx.fillStyle = this.bgColor; + //this.ctx.fillRect(0, 0, this.width, this.height); this.points.forEach((point, index) => { + this.updatePoint(point); this.drawLines(point, index); this.drawPoint(point); - this.updatePoint(point); }); //this.drawPoint(new Point(this.mouseX, this.mouseY, 12, 0)); @@ -94,11 +116,12 @@ export class ReactiveBackgroundComponent implements OnInit { const dist = this.distance(p.x, p.y, otherPoint.x, otherPoint.y); if (dist < this.minDistance) { const h = HEX[Math.round((1 - dist / this.minDistance) * 16)] - this.ctx!.strokeStyle = this.lineColor + h + h; - this.ctx!.beginPath(); - this.ctx!.moveTo(p.x * this.width, p.y * this.height); - this.ctx!.lineTo(otherPoint.x * this.width, otherPoint.y * this.height); - this.ctx!.stroke(); + this.ctx.strokeStyle = this.lineColor + h; + this.ctx.lineWidth = this.maxSize / 2; + this.ctx.beginPath(); + this.ctx.moveTo(p.x * this.width, p.y * this.height); + this.ctx.lineTo(otherPoint.x * this.width, otherPoint.y * this.height); + this.ctx.stroke(); } i++; @@ -108,7 +131,7 @@ export class ReactiveBackgroundComponent implements OnInit { drawPoint(p: Point) { this.ctx!.fillStyle = this.pointColor; this.ctx!.beginPath(); - this.ctx!.arc(p.x * this.width, p.y * this.height, p.size, 0, 2 * Math.PI); + this.ctx!.arc(p.x * this.width, p.y * this.height, p.size * this.screenDepth(p.x), 0, 2 * Math.PI); this.ctx!.fill(); } @@ -140,22 +163,33 @@ export class ReactiveBackgroundComponent implements OnInit { p.x -= ((mx - p.x) / distToCursor) / 500; p.y -= ((my - p.y) / distToCursor) / 500; - const grd = this.ctx!.createLinearGradient(p.x * this.width, p.y * this.height, mx * this.width, my * this.height); - grd.addColorStop(0, this.cursorLineColor + 'ff'); + const grd = this.ctx.createLinearGradient(p.x * this.width, p.y * this.height, mx * this.width, my * this.height); + const alpha = HEX[Math.round(p.size / this.maxSize * (HEX.length - 1))]; + grd.addColorStop(0, this.cursorLineColor + alpha); grd.addColorStop(1, this.cursorLineColor + '00'); - this.ctx!.strokeStyle = grd; - this.ctx!.beginPath(); - this.ctx!.moveTo(p.x * this.width, p.y * this.height); - this.ctx!.lineTo(mx * this.width, my * this.height); - this.ctx!.stroke(); + this.ctx.strokeStyle = grd; + this.ctx.beginPath(); + this.ctx.moveTo(p.x * this.width, p.y * this.height); + this.ctx.lineTo(mx * this.width, my * this.height); + this.ctx.stroke(); } - p.x %= 1; - p.y %= 1; + this.keepPointWithinBounds(p); + } + + keepPointWithinBounds(p: Point) { + p.x = p.x % 1.0; + p.y = p.y % 1.0; + p.x = ((1 - Math.sign(p.x)) / 2) + p.x; + p.y = ((1 - Math.sign(p.y)) / 2) + p.y; } distance(x1: number, y1: number, x2: number, y2: number): number { - return Math.sqrt(((x2 - x1) ** 2) + ((y2 / this.ratio - y1 / this.ratio) ** 2)); + return Math.sqrt(((x2 - x1) ** 2) + ((y2 / this.ratio - y1 / this.ratio) ** 2) / this.screenDepth(x1)) * this.ratio; + } + + screenDepth(x: number): number { + return (1.5 - Math.sin(x * Math.PI)); } } @@ -168,4 +202,4 @@ class Point { ) { } } -const HEX = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; \ No newline at end of file +const HEX = ['00', '11', '22', '33', '44', '55', '66', '77', '88', '99', 'aa', 'bb', 'cc', 'dd', 'ee', 'ff']; \ No newline at end of file diff --git a/frontend/src/app/_pages/playground/playground.component.css b/frontend/src/app/_pages/playground/playground.component.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/_pages/playground/playground.component.html b/frontend/src/app/_pages/playground/playground.component.html new file mode 100644 index 00000000..5622cd83 --- /dev/null +++ b/frontend/src/app/_pages/playground/playground.component.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/frontend/src/app/_pages/playground/playground.component.spec.ts b/frontend/src/app/_pages/playground/playground.component.spec.ts new file mode 100644 index 00000000..bf66b27e --- /dev/null +++ b/frontend/src/app/_pages/playground/playground.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PlaygroundComponent } from './playground.component'; + +describe('PlaygroundComponent', () => { + let component: PlaygroundComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PlaygroundComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PlaygroundComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_pages/playground/playground.component.ts b/frontend/src/app/_pages/playground/playground.component.ts new file mode 100644 index 00000000..007a455e --- /dev/null +++ b/frontend/src/app/_pages/playground/playground.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-playground', + templateUrl: './playground.component.html', + styleUrls: ['./playground.component.css'] +}) +export class PlaygroundComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index e22f7a88..8aadb8bf 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -14,6 +14,7 @@ import { PredictComponent } from './_pages/predict/predict.component'; import { FilterDatasetsComponent } from './_pages/filter-datasets/filter-datasets.component'; import { ExperimentComponent } from './experiment/experiment.component'; import { TrainingComponent } from './training/training.component'; +import { PlaygroundComponent } from './_pages/playground/playground.component'; const routes: Routes = [ { path: '', component: HomeComponent, data: { title: 'Početna strana' } }, @@ -28,6 +29,7 @@ const routes: Routes = [ { path: 'browse-datasets', component: FilterDatasetsComponent, data: { title: 'Javni izvori podataka' } }, { path: 'browse-predictors', component: BrowsePredictorsComponent, data: { title: 'Javni trenirani modeli' } }, { path: 'predict/:id', component: PredictComponent, data: { title: 'Predvidi vrednosti' } }, + { path: 'playground', component: PlaygroundComponent, data: { title: 'Zabava' } } ]; @NgModule({ diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index daf93cc1..1bd207e1 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -1,5 +1,9 @@ - + + + + + +
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index c4f89ad8..26417373 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -48,6 +48,8 @@ import { TrainingComponent } from './training/training.component'; import { ItemExperimentComponent } from './_elements/item-experiment/item-experiment.component'; import { YesNoDialogComponent } from './_modals/yes-no-dialog/yes-no-dialog.component'; import { Configuration } from './configuration.service'; +import { PlaygroundComponent } from './_pages/playground/playground.component'; +import { GradientBackgroundComponent } from './_elements/gradient-background/gradient-background.component'; export function initializeApp(appConfig: Configuration) { return () => appConfig.load(); @@ -87,7 +89,9 @@ export function initializeApp(appConfig: Configuration) { GraphComponent, TrainingComponent, ItemExperimentComponent, - YesNoDialogComponent + YesNoDialogComponent, + PlaygroundComponent, + GradientBackgroundComponent ], imports: [ BrowserModule, -- cgit v1.2.3 From 56fbc59007fe5064168af33c9770a0d378343b85 Mon Sep 17 00:00:00 2001 From: Danijel Anđelković Date: Sun, 17 Apr 2022 23:20:18 +0200 Subject: Promenio stil home strane. --- .../reactive-background.component.ts | 6 ++- frontend/src/app/_pages/home/home.component.html | 62 +++++++++++++--------- frontend/src/app/app.component.html | 8 +-- frontend/src/styles.css | 16 ++++++ 4 files changed, 60 insertions(+), 32 deletions(-) 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 9d7f5522..73cdb326 100644 --- a/frontend/src/app/_elements/reactive-background/reactive-background.component.ts +++ b/frontend/src/app/_elements/reactive-background/reactive-background.component.ts @@ -22,6 +22,8 @@ export class ReactiveBackgroundComponent implements AfterViewInit { @Input() pointColor: string = '#ffffff'; @Input() cursorLineColor: string = '#ff0000'; + private fleeSpeed = 0.005; + private points: Point[] = []; private width = 200; @@ -160,8 +162,8 @@ export class ReactiveBackgroundComponent implements AfterViewInit { const distToCursor = this.distance(p.x, p.y, mx, my); if (distToCursor < this.cursorDistance) { - p.x -= ((mx - p.x) / distToCursor) / 500; - p.y -= ((my - p.y) / distToCursor) / 500; + p.x -= ((mx - p.x) / distToCursor) * this.fleeSpeed; + p.y -= ((my - p.y) / distToCursor) * this.fleeSpeed; const grd = this.ctx.createLinearGradient(p.x * this.width, p.y * this.height, mx * this.width, my * this.height); const alpha = HEX[Math.round(p.size / this.maxSize * (HEX.length - 1))]; diff --git a/frontend/src/app/_pages/home/home.component.html b/frontend/src/app/_pages/home/home.component.html index 08f95a69..8294a73b 100644 --- a/frontend/src/app/_pages/home/home.component.html +++ b/frontend/src/app/_pages/home/home.component.html @@ -1,56 +1,66 @@ -
+
-

Započnite sa treniranjem!

-
-
+ + + +
+
- storage + storage

Moji izvori podataka

- Preuredite vaše izvore - podataka, ili - dodajte novi. + Preuredite vaše izvore podataka, ili dodajte novi.

-
+
- model_training + model_training

Moji modeli

- Pregledajte vaše modele, menjajte ih, - napravite nove modele, ili - ih obrišite. + Pregledajte vaše modele, menjajte ih, napravite nove modele, ili ih obrišite.

-
+
- batch_prediction + batch_prediction

Rezultati treniranja

- Pregledajte sve vaše trenirane - modele, - koristite ih da predvidite vrednosti za red ili skup podataka, ili ih obrišite. + Pregledajte sve vaše trenirane modele, koristite ih da predvidite vrednosti za red ili skup podataka, ili ih obrišite.

-

Pogledajte javne izvore podataka!

- +
+

Pogledajte javne izvore podataka!

+
+ -

Pogledaj sve javne izvore podataka...

-

Iskoristite već trenirane modele!

+ + + +
+

Iskoristite već trenirane modele!

+
-

Pogledaj sve javne trenirane modele...

+ +
\ No newline at end of file diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index 1bd207e1..ba7743b5 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -1,9 +1,9 @@ - - + + - + - +
diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 802b8bd0..b6555f43 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -2,4 +2,20 @@ body { /*background-image: url('/assets/images/add_model_background.jpg');*/ background-color: #003459; +} + +.shadowed { + box-shadow: rgba(240, 46, 170, 0.4) 0px 5px, rgba(240, 46, 170, 0.3) 0px 10px, rgba(240, 46, 170, 0.2) 0px 15px, rgba(240, 46, 170, 0.1) 0px 20px, rgba(240, 46, 170, 0.05) 0px 25px; +} + +.shadowed:last-child { + box-shadow: rgba(240, 46, 170, 0.4) -5px 5px, rgba(240, 46, 170, 0.3) -10px 10px, rgba(240, 46, 170, 0.2) -15px 15px, rgba(240, 46, 170, 0.1) -20px 20px, rgba(240, 46, 170, 0.05) -25px 25px; +} + +.shadowed:first-child { + box-shadow: rgba(240, 46, 170, 0.4) 5px 5px, rgba(240, 46, 170, 0.3) 10px 10px, rgba(240, 46, 170, 0.2) 15px 15px, rgba(240, 46, 170, 0.1) 20px 20px, rgba(240, 46, 170, 0.05) 25px 25px; +} + +.shadow-accent { + box-shadow: rgba(240, 46, 170, 0.4) 0px 5px, rgba(240, 46, 170, 0.3) 0px 10px, rgba(240, 46, 170, 0.2) 0px 15px, rgba(240, 46, 170, 0.1) 0px 20px, rgba(240, 46, 170, 0.05) 0px 25px; } \ No newline at end of file -- cgit v1.2.3 From bcd4852ea7964e15f4ad7d0061522da42d866d37 Mon Sep 17 00:00:00 2001 From: Danijel Anđelković Date: Tue, 19 Apr 2022 02:28:18 +0200 Subject: Dodao komponentu za prikaz dataseta sa tabelama. Promenio scrollbar i home stranicu. Zapoceo trening stranicu. --- frontend/angular.json | 7 +- .../carousel-vertical.component.css | 3 + .../carousel-vertical.component.html | 12 +++ .../carousel-vertical.component.spec.ts | 25 ++++++ .../carousel-vertical.component.ts | 65 ++++++++++++++ .../src/app/_elements/graph/graph.component.html | 2 +- .../src/app/_elements/navbar/navbar.component.html | 30 +++---- .../notifications/notifications.component.ts | 1 + .../app/_elements/playlist/playlist.component.css | 57 +++++++++++++ .../app/_elements/playlist/playlist.component.html | 19 +++++ .../_elements/playlist/playlist.component.spec.ts | 25 ++++++ .../app/_elements/playlist/playlist.component.ts | 49 +++++++++++ .../select-item-list.component.css | 0 .../select-item-list.component.html | 1 + .../select-item-list.component.spec.ts | 25 ++++++ .../select-item-list/select-item-list.component.ts | 15 ++++ frontend/src/app/_pages/home/home.component.html | 46 +++++----- frontend/src/app/app.module.ts | 8 +- frontend/src/app/training/training.component.html | 17 ++-- .../src/assets/images/add_model_background.jpg | Bin 56906 -> 0 bytes .../assets/images/logo_igrannonica_temp - Copy.png | Bin 0 -> 16336 bytes .../src/assets/images/logo_igrannonica_temp.png | Bin 0 -> 29448 bytes frontend/src/styles.css | 94 +++++++++++++++++++-- 23 files changed, 441 insertions(+), 60 deletions(-) create mode 100644 frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.css create mode 100644 frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.html create mode 100644 frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.spec.ts create mode 100644 frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.ts create mode 100644 frontend/src/app/_elements/playlist/playlist.component.css create mode 100644 frontend/src/app/_elements/playlist/playlist.component.html create mode 100644 frontend/src/app/_elements/playlist/playlist.component.spec.ts create mode 100644 frontend/src/app/_elements/playlist/playlist.component.ts create mode 100644 frontend/src/app/_elements/select-item-list/select-item-list.component.css create mode 100644 frontend/src/app/_elements/select-item-list/select-item-list.component.html create mode 100644 frontend/src/app/_elements/select-item-list/select-item-list.component.spec.ts create mode 100644 frontend/src/app/_elements/select-item-list/select-item-list.component.ts delete mode 100644 frontend/src/assets/images/add_model_background.jpg create mode 100644 frontend/src/assets/images/logo_igrannonica_temp - Copy.png create mode 100644 frontend/src/assets/images/logo_igrannonica_temp.png diff --git a/frontend/angular.json b/frontend/angular.json index 6653e4b1..d1983d31 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -108,5 +108,10 @@ } } }, - "defaultProject": "frontend" + "defaultProject": "frontend", + "cli": { + "warnings": { + "versionMismatch": false + } + } } \ No newline at end of file diff --git a/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.css b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.css new file mode 100644 index 00000000..3d4a2432 --- /dev/null +++ b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.css @@ -0,0 +1,3 @@ +.carousel { + overscroll-behavior: contain; +} \ No newline at end of file diff --git a/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.html b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.html new file mode 100644 index 00000000..f52aee12 --- /dev/null +++ b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.html @@ -0,0 +1,12 @@ +

+ {{scroll}} +

+ \ No newline at end of file diff --git a/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.spec.ts b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.spec.ts new file mode 100644 index 00000000..0c736e90 --- /dev/null +++ b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CarouselVerticalComponent } from './carousel-vertical.component'; + +describe('CarouselVerticalComponent', () => { + let component: CarouselVerticalComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CarouselVerticalComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CarouselVerticalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.ts b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.ts new file mode 100644 index 00000000..d8849ea6 --- /dev/null +++ b/frontend/src/app/_elements/carousel-vertical/carousel-vertical.component.ts @@ -0,0 +1,65 @@ +import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; + +@Component({ + selector: 'app-carousel-vertical', + templateUrl: './carousel-vertical.component.html', + styleUrls: ['./carousel-vertical.component.css'] +}) +export class CarouselVerticalComponent implements OnInit, AfterViewInit { + + @ViewChild('wrapper') wrapper!: ElementRef; + + @Input() items!: any[]; + + itemsToShow: any[] = []; + + @Input() type: string = "Object"; + + scroll = 0; + height = 9; //rem + + currentIndex = 0; + + @Input() shownElements: number = 5; + + constructor() { + } + + ngOnInit(): void { + this.itemsToShow = [...this.items.slice(0, this.shownElements)]; + console.log('0', this.itemsToShow); + } + + ngAfterViewInit(): void { + const container = this.wrapper.nativeElement + + container.addEventListener('scroll', (event: Event) => { + this.scroll = (container.scrollTop / (container.scrollHeight - container.clientHeight)); + if (this.scroll == 1.0) { + //console.log('removed', this.itemsToShow.splice(0, 1)[0].name); + const itemToAdd = this.items[(this.currentIndex + this.shownElements) % (this.items.length - 1)]; + this.itemsToShow.push(itemToAdd); + //console.log('added', itemToAdd.name); + this.currentIndex = (this.currentIndex + 1); + container.scrollTop = (container.scrollHeight - container.clientHeight) / 2; + } + }); + } + + clickItem(index: number) { + } + + calcVisibility(i: number) { + //return ((Math.sin((((i) / this.shownElements) - this.scroll) * Math.PI) + 1) / 2) + const iPercent = (i + 1 - this.scroll) / this.shownElements; + return iPercent; + } + + calcStyle(i: number) { + const a = this.calcVisibility(i) + const v = (Math.sin(a * Math.PI) + 1) / 2; + return `transform: translateY(${v * 100}%) scale(${v}) perspective(${v * 200}em) rotateX(${(1 - a) * 180 - 90}deg); + opacity: ${v}; + height: ${this.height}rem;`; + } +} diff --git a/frontend/src/app/_elements/graph/graph.component.html b/frontend/src/app/_elements/graph/graph.component.html index 1c21fb6c..92e9df38 100644 --- a/frontend/src/app/_elements/graph/graph.component.html +++ b/frontend/src/app/_elements/graph/graph.component.html @@ -1,3 +1,3 @@
- +
\ No newline at end of file diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html index 7d0c4cd8..41105405 100644 --- a/frontend/src/app/_elements/navbar/navbar.component.html +++ b/frontend/src/app/_elements/navbar/navbar.component.html @@ -2,32 +2,24 @@
- + diff --git a/frontend/src/app/_elements/notifications/notifications.component.ts b/frontend/src/app/_elements/notifications/notifications.component.ts index 9b460240..d64530b9 100644 --- a/frontend/src/app/_elements/notifications/notifications.component.ts +++ b/frontend/src/app/_elements/notifications/notifications.component.ts @@ -25,6 +25,7 @@ export class NotificationsComponent implements OnInit { const existingNotification = this.notifications.find(x => x.id === mId) const progress = ((currentEpoch + 1) / totalEpochs); console.log("Ukupno epoha", totalEpochs, "Trenutna epoha:", currentEpoch); + console.log("stat:", stat); if (!existingNotification) this.notifications.push(new Notification(`Treniranje modela: ${mName}`, mId, progress, true)); else { diff --git a/frontend/src/app/_elements/playlist/playlist.component.css b/frontend/src/app/_elements/playlist/playlist.component.css new file mode 100644 index 00000000..7ce320d9 --- /dev/null +++ b/frontend/src/app/_elements/playlist/playlist.component.css @@ -0,0 +1,57 @@ +.ns-wrapper { + width: 100%; + max-width: 800px; + max-height: 600px; + height: 100%; + transform-style: preserve-3d; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; +} + +.ns-cards { + position: relative; + width: 300%; + height: 36rem; + margin-bottom: 20px; +} + +.ns-card { + position: absolute; + width: 60%; + height: 100%; + left: 0; + right: 0; + margin: auto; + transition: transform 0.4s ease; + cursor: pointer; +} + +input[type=radio] { + display: none; +} + +#item-1:checked~.ns-cards #view-item-3, +#item-2:checked~.ns-cards #view-item-1, +#item-3:checked~.ns-cards #view-item-2 { + transform: translatex(-40%) scale(0.8); + opacity: 0.4; + z-index: 0; +} + +#item-1:checked~.ns-cards #view-item-2, +#item-2:checked~.ns-cards #view-item-3, +#item-3:checked~.ns-cards #view-item-1 { + transform: translatex(40%) scale(0.8); + opacity: 0.4; + z-index: 0; +} + +#item-1:checked~.ns-cards #view-item-1, +#item-2:checked~.ns-cards #view-item-2, +#item-3:checked~.ns-cards #view-item-3 { + transform: translatex(0) scale(1); + opacity: 1; + z-index: 1; +} \ No newline at end of file diff --git a/frontend/src/app/_elements/playlist/playlist.component.html b/frontend/src/app/_elements/playlist/playlist.component.html new file mode 100644 index 00000000..fdb426ed --- /dev/null +++ b/frontend/src/app/_elements/playlist/playlist.component.html @@ -0,0 +1,19 @@ +
+ + + +
+ + + +
+
+ +
+
\ No newline at end of file diff --git a/frontend/src/app/_elements/playlist/playlist.component.spec.ts b/frontend/src/app/_elements/playlist/playlist.component.spec.ts new file mode 100644 index 00000000..0afe8041 --- /dev/null +++ b/frontend/src/app/_elements/playlist/playlist.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PlaylistComponent } from './playlist.component'; + +describe('PlaylistComponent', () => { + let component: PlaylistComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PlaylistComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PlaylistComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/playlist/playlist.component.ts b/frontend/src/app/_elements/playlist/playlist.component.ts new file mode 100644 index 00000000..74527b39 --- /dev/null +++ b/frontend/src/app/_elements/playlist/playlist.component.ts @@ -0,0 +1,49 @@ +import { Component, Input, OnInit } from '@angular/core'; +import Dataset from 'src/app/_data/Dataset'; +import { TableData } from 'src/app/_elements/datatable/datatable.component'; +import { CsvParseService } from 'src/app/_services/csv-parse.service'; +import { DatasetsService } from 'src/app/_services/datasets.service'; + +@Component({ + selector: 'app-playlist', + templateUrl: './playlist.component.html', + styleUrls: ['./playlist.component.css'] +}) +export class PlaylistComponent implements OnInit { + + selectedId: string = "0"; + + @Input() datasets!: Dataset[]; + + tableDatas?: TableData[]; + + constructor(private datasetService: DatasetsService, private csv: CsvParseService) { + + } + + getIndex(str: string) { + return parseInt(str); + } + + ngOnInit(): void { + this.tableDatas = []; + + this.datasets.forEach((dataset, index) => { + if (index < 3) { + this.datasetService.getDatasetFile(dataset.fileId).subscribe((file: string | undefined) => { + if (file) { + const tableData = new TableData(); + tableData.hasInput = true; + tableData.loaded = true; + tableData.numRows = dataset.rowCount; + tableData.numCols = dataset.columnInfo.length; + tableData.data = this.csv.csvToArray(file, (dataset.delimiter == "razmak") ? " " : (dataset.delimiter == "") ? "," : dataset.delimiter); + this.tableDatas!.push(tableData); + } + }); + } + }); + + console.log(this.tableDatas); + } +} diff --git a/frontend/src/app/_elements/select-item-list/select-item-list.component.css b/frontend/src/app/_elements/select-item-list/select-item-list.component.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/_elements/select-item-list/select-item-list.component.html b/frontend/src/app/_elements/select-item-list/select-item-list.component.html new file mode 100644 index 00000000..b92b7adb --- /dev/null +++ b/frontend/src/app/_elements/select-item-list/select-item-list.component.html @@ -0,0 +1 @@ +

select-item-list works!

diff --git a/frontend/src/app/_elements/select-item-list/select-item-list.component.spec.ts b/frontend/src/app/_elements/select-item-list/select-item-list.component.spec.ts new file mode 100644 index 00000000..0abc7ab5 --- /dev/null +++ b/frontend/src/app/_elements/select-item-list/select-item-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SelectItemListComponent } from './select-item-list.component'; + +describe('SelectItemListComponent', () => { + let component: SelectItemListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SelectItemListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SelectItemListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/select-item-list/select-item-list.component.ts b/frontend/src/app/_elements/select-item-list/select-item-list.component.ts new file mode 100644 index 00000000..f6aae7a0 --- /dev/null +++ b/frontend/src/app/_elements/select-item-list/select-item-list.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-select-item-list', + templateUrl: './select-item-list.component.html', + styleUrls: ['./select-item-list.component.css'] +}) +export class SelectItemListComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/_pages/home/home.component.html b/frontend/src/app/_pages/home/home.component.html index 8294a73b..b673d074 100644 --- a/frontend/src/app/_pages/home/home.component.html +++ b/frontend/src/app/_pages/home/home.component.html @@ -1,5 +1,8 @@
- + +
@@ -11,7 +14,7 @@
-
+
storage

Moji izvori podataka

@@ -20,7 +23,7 @@

-
+
model_training @@ -30,7 +33,7 @@

-
+
batch_prediction @@ -44,23 +47,28 @@
-
-

Pogledajte javne izvore podataka!

-
- - +
+ + - -
-

Iskoristite već trenirane modele!

-
- - +
\ No newline at end of file diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 26417373..7862c872 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -50,6 +50,9 @@ import { YesNoDialogComponent } from './_modals/yes-no-dialog/yes-no-dialog.comp import { Configuration } from './configuration.service'; import { PlaygroundComponent } from './_pages/playground/playground.component'; import { GradientBackgroundComponent } from './_elements/gradient-background/gradient-background.component'; +import { CarouselVerticalComponent } from './_elements/carousel-vertical/carousel-vertical.component'; +import { SelectItemListComponent } from './_elements/select-item-list/select-item-list.component'; +import { PlaylistComponent } from './_elements/playlist/playlist.component'; export function initializeApp(appConfig: Configuration) { return () => appConfig.load(); @@ -91,7 +94,10 @@ export function initializeApp(appConfig: Configuration) { ItemExperimentComponent, YesNoDialogComponent, PlaygroundComponent, - GradientBackgroundComponent + GradientBackgroundComponent, + CarouselVerticalComponent, + SelectItemListComponent, + PlaylistComponent ], imports: [ BrowserModule, diff --git a/frontend/src/app/training/training.component.html b/frontend/src/app/training/training.component.html index 0ce4cc89..9f2481a2 100644 --- a/frontend/src/app/training/training.component.html +++ b/frontend/src/app/training/training.component.html @@ -2,36 +2,33 @@

Trenirajte veštačku neuronsku mrežu

-
+

1. Izaberite eksperiment iz kolekcije

- +
    -
  • - +
  • +
- +

2. Izaberite model

- +

3. Treniranje modela

- +

Rezultati treniranja

Rezultati treniranja:

diff --git a/frontend/src/assets/images/add_model_background.jpg b/frontend/src/assets/images/add_model_background.jpg deleted file mode 100644 index d86f0566..00000000 Binary files a/frontend/src/assets/images/add_model_background.jpg and /dev/null differ diff --git a/frontend/src/assets/images/logo_igrannonica_temp - Copy.png b/frontend/src/assets/images/logo_igrannonica_temp - Copy.png new file mode 100644 index 00000000..a9d7d396 Binary files /dev/null and b/frontend/src/assets/images/logo_igrannonica_temp - Copy.png differ diff --git a/frontend/src/assets/images/logo_igrannonica_temp.png b/frontend/src/assets/images/logo_igrannonica_temp.png new file mode 100644 index 00000000..9e8e8855 Binary files /dev/null and b/frontend/src/assets/images/logo_igrannonica_temp.png differ diff --git a/frontend/src/styles.css b/frontend/src/styles.css index b6555f43..5e59e735 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -4,18 +4,96 @@ body { background-color: #003459; } -.shadowed { - box-shadow: rgba(240, 46, 170, 0.4) 0px 5px, rgba(240, 46, 170, 0.3) 0px 10px, rgba(240, 46, 170, 0.2) 0px 15px, rgba(240, 46, 170, 0.1) 0px 20px, rgba(240, 46, 170, 0.05) 0px 25px; +.shadowed:hover { + box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; } -.shadowed:last-child { - box-shadow: rgba(240, 46, 170, 0.4) -5px 5px, rgba(240, 46, 170, 0.3) -10px 10px, rgba(240, 46, 170, 0.2) -15px 15px, rgba(240, 46, 170, 0.1) -20px 20px, rgba(240, 46, 170, 0.05) -25px 25px; +.shadowed:first-child:hover { + box-shadow: rgba(0, 152, 189, 0.4) -5px 5px, rgba(0, 152, 189, 0.3) -10px 10px, rgba(0, 152, 189, 0.2) -15px 15px, rgba(0, 152, 189, 0.1) -20px 20px, rgba(0, 152, 189, 0.05) -25px 25px; } -.shadowed:first-child { - box-shadow: rgba(240, 46, 170, 0.4) 5px 5px, rgba(240, 46, 170, 0.3) 10px 10px, rgba(240, 46, 170, 0.2) 15px 15px, rgba(240, 46, 170, 0.1) 20px 20px, rgba(240, 46, 170, 0.05) 25px 25px; +.shadowed:last-child:hover { + box-shadow: rgba(0, 152, 189, 0.4) 5px 5px, rgba(0, 152, 189, 0.3) 10px 10px, rgba(0, 152, 189, 0.2) 15px 15px, rgba(0, 152, 189, 0.1) 20px 20px, rgba(0, 152, 189, 0.05) 25px 25px; } -.shadow-accent { - box-shadow: rgba(240, 46, 170, 0.4) 0px 5px, rgba(240, 46, 170, 0.3) 0px 10px, rgba(240, 46, 170, 0.2) 0px 15px, rgba(240, 46, 170, 0.1) 0px 20px, rgba(240, 46, 170, 0.05) 0px 25px; +.shadow-accent:hover { + box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; + animation-name: holo-hover; + animation-duration: 300ms; + transform: perspective(100em) rotateX(10deg); +} + + +/*Mora da se ispravi za media kada je ekran premali pa se poredjaju u kolonu*/ + +.align-items-view>*:first-child { + transform: perspective(100em) rotateY(25deg) translateZ(1em); +} + +.align-items-view>* { + transform: perspective(100em) translateZ(-2em); +} + +.align-items-view>*:last-child { + transform: perspective(100em) rotateY(-25deg) translateZ(1em); +} + +.bg-light { + background-color: rgba(0, 152, 189, 0.3) !important; +} + +a { + color: #00a8e8 !important; +} + +@keyframes holo-hover { + to { + transform: perspective(100em) rotateX(10deg); + } +} + +@keyframes logo-animation { + from { + transform: perspective(100em) rotateX(50deg) rotateZ(0deg); + } + to { + transform: perspective(100em) rotateX(50deg) rotateZ(360deg); + } +} + +.ann-logo { + animation-name: logo-animation; + animation-duration: 3140ms; + animation-timing-function: linear; + animation-iteration-count: infinite; +} + + +/* width */ + +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + + +/* Track */ + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0); +} + + +/* Handle */ + +::-webkit-scrollbar-thumb { + background: rgba(0, 188, 252, 0.6); + border-radius: 25px; +} + + +/* Handle on hover */ + +::-webkit-scrollbar-thumb:hover { + background: rgba(0, 188, 252, 0.8); } \ No newline at end of file -- cgit v1.2.3 From 054d567cef92cae42cd75f56c55e16febdac658c Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Tue, 19 Apr 2022 16:52:03 +0200 Subject: Omoguceno pravljenje privremenog korisnika. --- backend/api/api/Controllers/ModelController.cs | 2 +- backend/api/api/Models/IJwtToken.cs | 2 +- backend/api/api/Models/JwtToken.cs | 5 +++-- backend/api/api/Models/User.cs | 1 + backend/api/api/Services/AuthService.cs | 14 +++++++++++++- backend/api/api/Services/IAuthService.cs | 1 + 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/backend/api/api/Controllers/ModelController.cs b/backend/api/api/Controllers/ModelController.cs index ce1759ca..d60e3236 100644 --- a/backend/api/api/Controllers/ModelController.cs +++ b/backend/api/api/Controllers/ModelController.cs @@ -98,7 +98,7 @@ namespace api.Controllers // GET: api//mymodels [HttpGet("mymodels")] - [Authorize(Roles = "User")] + [Authorize(Roles = "User,Guest")] public ActionResult> Get() { string uploaderId = getUserId(); diff --git a/backend/api/api/Models/IJwtToken.cs b/backend/api/api/Models/IJwtToken.cs index 2afb6683..96b96997 100644 --- a/backend/api/api/Models/IJwtToken.cs +++ b/backend/api/api/Models/IJwtToken.cs @@ -4,7 +4,7 @@ namespace api.Models { public interface IJwtToken { - string GenGuestToken(); + string GenGuestToken(string id); string GenToken(AuthRequest user); string RenewToken(string existingToken); string TokenToUsername(string token); diff --git a/backend/api/api/Models/JwtToken.cs b/backend/api/api/Models/JwtToken.cs index 06b3a666..3ec75468 100644 --- a/backend/api/api/Models/JwtToken.cs +++ b/backend/api/api/Models/JwtToken.cs @@ -100,15 +100,16 @@ namespace api.Models } - public string GenGuestToken() + public string GenGuestToken(string id) { + var user=_userService.GetUserById(id); var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_configuration.GetSection("AppSettings:JwtToken").Value); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim("name",""), new Claim("role", "Guest"), - new Claim("id","")}), + new Claim("id",user._id)}), Expires = DateTime.UtcNow.AddMinutes(20), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; diff --git a/backend/api/api/Models/User.cs b/backend/api/api/Models/User.cs index 1ae8e437..ce289af1 100644 --- a/backend/api/api/Models/User.cs +++ b/backend/api/api/Models/User.cs @@ -25,6 +25,7 @@ namespace api.Models public string LastName { get; set; } public string photoId { get; set; } + public bool isPermament { get; set; } } } diff --git a/backend/api/api/Services/AuthService.cs b/backend/api/api/Services/AuthService.cs index c7161dee..b734fa7a 100644 --- a/backend/api/api/Services/AuthService.cs +++ b/backend/api/api/Services/AuthService.cs @@ -37,6 +37,7 @@ namespace api.Services u.FirstName = user.firstName; u.LastName = user.lastName; u.photoId = "1"; + u.isPermament = true; if (_users.Find(user => user.Username == u.Username).FirstOrDefault() != null) return "Username Already Exists"; if (_users.Find(user => user.Email == u.Email).FirstOrDefault() != null) @@ -45,6 +46,13 @@ namespace api.Services _users.InsertOne(u); return "User added"; } + public void RegisterGuest() + { + User u=new User(); + u._id = ""; + _users.InsertOne(u); + _jwt.GenGuestToken(u._id); + } public string RenewToken(string header) { @@ -60,7 +68,11 @@ namespace api.Services public string GuestToken() { - return _jwt.GenGuestToken(); + User u = new User(); + u._id = ""; + _users.InsertOne(u); + return _jwt.GenGuestToken(u._id); + } diff --git a/backend/api/api/Services/IAuthService.cs b/backend/api/api/Services/IAuthService.cs index 9a109208..4ed9a761 100644 --- a/backend/api/api/Services/IAuthService.cs +++ b/backend/api/api/Services/IAuthService.cs @@ -8,5 +8,6 @@ namespace api.Services string Register(RegisterRequest user); string RenewToken(string token); public string GuestToken(); + public void RegisterGuest(); } } \ No newline at end of file -- cgit v1.2.3 From 0af2ddb9f7fbdb48b043ae030709eac8def794bb Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Tue, 19 Apr 2022 17:32:04 +0200 Subject: Promenjeno brisanje temp fajlova i dodato brisanje za tempKorisnika. --- backend/api/api/Models/User.cs | 3 +- backend/api/api/Services/AuthService.cs | 9 +--- backend/api/api/Services/IAuthService.cs | 1 - backend/api/api/Services/TempRemovalService.cs | 69 +++++++++++++++----------- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/backend/api/api/Models/User.cs b/backend/api/api/Models/User.cs index ce289af1..bea467fa 100644 --- a/backend/api/api/Models/User.cs +++ b/backend/api/api/Models/User.cs @@ -26,6 +26,7 @@ namespace api.Models public string photoId { get; set; } public bool isPermament { get; set; } - + public DateTime dateCreated { get; set; } + } } diff --git a/backend/api/api/Services/AuthService.cs b/backend/api/api/Services/AuthService.cs index b734fa7a..7fd0c59f 100644 --- a/backend/api/api/Services/AuthService.cs +++ b/backend/api/api/Services/AuthService.cs @@ -38,6 +38,7 @@ namespace api.Services u.LastName = user.lastName; u.photoId = "1"; u.isPermament = true; + u.dateCreated= DateTime.Now.ToUniversalTime(); if (_users.Find(user => user.Username == u.Username).FirstOrDefault() != null) return "Username Already Exists"; if (_users.Find(user => user.Email == u.Email).FirstOrDefault() != null) @@ -46,13 +47,6 @@ namespace api.Services _users.InsertOne(u); return "User added"; } - public void RegisterGuest() - { - User u=new User(); - u._id = ""; - _users.InsertOne(u); - _jwt.GenGuestToken(u._id); - } public string RenewToken(string header) { @@ -70,6 +64,7 @@ namespace api.Services { User u = new User(); u._id = ""; + u.dateCreated = DateTime.Now.ToUniversalTime(); _users.InsertOne(u); return _jwt.GenGuestToken(u._id); diff --git a/backend/api/api/Services/IAuthService.cs b/backend/api/api/Services/IAuthService.cs index 4ed9a761..9a109208 100644 --- a/backend/api/api/Services/IAuthService.cs +++ b/backend/api/api/Services/IAuthService.cs @@ -8,6 +8,5 @@ namespace api.Services string Register(RegisterRequest user); string RenewToken(string token); public string GuestToken(); - public void RegisterGuest(); } } \ No newline at end of file diff --git a/backend/api/api/Services/TempRemovalService.cs b/backend/api/api/Services/TempRemovalService.cs index 302ca974..9e6b7f96 100644 --- a/backend/api/api/Services/TempRemovalService.cs +++ b/backend/api/api/Services/TempRemovalService.cs @@ -10,6 +10,8 @@ namespace api.Services private readonly IMongoCollection _model; private readonly IMongoCollection _dataset; private readonly IMongoCollection _experiment; + private readonly IMongoCollection _user; + private readonly IMongoCollection _predictor; public TempRemovalService(IUserStoreDatabaseSettings settings, IMongoClient mongoClient) { @@ -18,43 +20,42 @@ namespace api.Services _model= database.GetCollection(settings.ModelCollectionName); _dataset = database.GetCollection(settings.DatasetCollectionName); _experiment= database.GetCollection(settings.ExperimentCollectionName); + _user = database.GetCollection(settings.CollectionName); + _predictor = database.GetCollection(settings.PredictorCollectionName); + } - public void DeleteTemps() + public void DeleteTemps() { - List files = _file.Find(file => file.uploaderId == "").ToList(); - foreach (var file in files) + List tempUsers=_user.Find(u=>u.isPermament==false).ToList(); + foreach (User user in tempUsers) { - if ((DateTime.Now.ToUniversalTime() - file.date).TotalDays >= 1) + if ((DateTime.Now.ToUniversalTime() - user.dateCreated).TotalDays < 1) + continue; + List tempPredictors=_predictor.Find(p=>p.uploaderId==user._id).ToList(); + List tempModels=_model.Find(m=>m.uploaderId==user._id).ToList(); + List tempExperiment = _experiment.Find(e => e.uploaderId == user._id).ToList(); + List tempDatasets = _dataset.Find(d => d.uploaderId == user._id).ToList(); + List tempFiles = _file.Find(f => f.uploaderId == user._id).ToList(); + + + foreach (Predictor predictor in tempPredictors) + DeletePredictor(predictor._id); + foreach(Model model in tempModels) + DeleteModel(model._id); + foreach(Experiment experiment in tempExperiment) + DeleteExperiment(experiment._id); + foreach(Dataset dataset in tempDatasets) + DeleteDataset(dataset._id); + foreach(FileModel file in tempFiles) { DeleteFile(file._id); - List datasets = _dataset.Find(dataset => dataset.fileId == file._id && dataset.uploaderId=="").ToList(); - foreach(var dataset in datasets) - { - DeleteDataset(dataset._id); - List experiments = _experiment.Find(experiment=>experiment.datasetId== dataset._id && experiment.uploaderId=="").ToList(); - foreach(var experiment in experiments) - { - DeleteExperiment(experiment._id); - foreach(var modelId in experiment.ModelIds) - { - var delModel=_model.Find(model=> modelId== model._id && model.uploaderId=="").FirstOrDefault(); - if(delModel!= null) - DeleteModel(delModel._id); - } - } - } - if (File.Exists(file.path)) + if(File.Exists(file.path)) File.Delete(file.path); } - } - //Brisanje modela ukoliko gost koristi vec postojeci dataset - List models1= _model.Find(model =>model.uploaderId == "").ToList(); - foreach(var model in models1) - { - if ((DateTime.Now.ToUniversalTime() - model.dateCreated.ToUniversalTime()).TotalDays >= 1) - { - DeleteModel(model._id); - } + DeleteUser(user._id); + + + } @@ -79,6 +80,14 @@ namespace api.Services { _experiment.DeleteOne(experiment => experiment._id == id); } + public void DeletePredictor(string id) + { + _predictor.DeleteOne(predictor=> predictor._id == id); + } + public void DeleteUser(string id) + { + _user.DeleteOne(user=>user._id == id); + } } -- cgit v1.2.3 From 9b4ac5f9535c02d1ec8288a2b20bea4fd00ed53d Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Tue, 19 Apr 2022 17:53:21 +0200 Subject: Dodato da gost moze da resfresha jwtToken.Gost koristi isti api za refresh tokena kao ulogovan korisnik. --- backend/api/api/Controllers/AuthController.cs | 2 +- backend/api/api/Models/IJwtToken.cs | 2 +- backend/api/api/Models/JwtToken.cs | 20 ++++++++++---------- backend/api/api/Services/AuthService.cs | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/backend/api/api/Controllers/AuthController.cs b/backend/api/api/Controllers/AuthController.cs index 901454e1..df8a514c 100644 --- a/backend/api/api/Controllers/AuthController.cs +++ b/backend/api/api/Controllers/AuthController.cs @@ -45,7 +45,7 @@ namespace api.Controllers } [HttpPost("renewJwt")] - [Authorize(Roles = "User")] + [Authorize(Roles = "User,Guest")] public async Task> RenewJwt() { var authorization = Request.Headers[HeaderNames.Authorization]; diff --git a/backend/api/api/Models/IJwtToken.cs b/backend/api/api/Models/IJwtToken.cs index 96b96997..5c54e4e3 100644 --- a/backend/api/api/Models/IJwtToken.cs +++ b/backend/api/api/Models/IJwtToken.cs @@ -5,7 +5,7 @@ namespace api.Models public interface IJwtToken { string GenGuestToken(string id); - string GenToken(AuthRequest user); + string GenToken(User user); string RenewToken(string existingToken); string TokenToUsername(string token); public string TokenToId(string token); diff --git a/backend/api/api/Models/JwtToken.cs b/backend/api/api/Models/JwtToken.cs index 3ec75468..20b0bc73 100644 --- a/backend/api/api/Models/JwtToken.cs +++ b/backend/api/api/Models/JwtToken.cs @@ -19,16 +19,17 @@ namespace api.Models } - public string GenToken(AuthRequest user) + public string GenToken(User user) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_configuration.GetSection("AppSettings:JwtToken").Value); - var fullUser = _userService.GetUserByUsername(user.UserName); + string role=(user.isPermament)?"User":"Guest"; + string name = (user.isPermament) ? user.Username : ""; var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("name", fullUser.Username), - new Claim("role", "User"), - new Claim("id",fullUser._id)}), + Subject = new ClaimsIdentity(new[] { new Claim("name", name), + new Claim("role", role), + new Claim("id",user._id)}), Expires = DateTime.UtcNow.AddMinutes(20), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; @@ -39,13 +40,12 @@ namespace api.Models public string RenewToken(string existingToken) { - var userName = TokenToUsername(existingToken); - if (userName == null) + var id = TokenToId(existingToken); + if (id == null) return null; - var authUser = new AuthRequest(); - authUser.UserName = userName; + var user = _userService.GetUserById(id); - return GenToken(authUser); + return GenToken(user); } diff --git a/backend/api/api/Services/AuthService.cs b/backend/api/api/Services/AuthService.cs index 7fd0c59f..2d7d753d 100644 --- a/backend/api/api/Services/AuthService.cs +++ b/backend/api/api/Services/AuthService.cs @@ -25,7 +25,7 @@ namespace api.Services return "Username doesn't exist"; if (!PasswordCrypt.checkPassword(user.Password, u.Password)) return "Wrong password"; - return _jwt.GenToken(user); + return _jwt.GenToken(u); } public string Register(RegisterRequest user) -- cgit v1.2.3 From 211b2534aea43ff0df771fb700688cbf7e35a264 Mon Sep 17 00:00:00 2001 From: Danijel Anđelković Date: Fri, 22 Apr 2022 23:29:10 +0200 Subject: Razdvojio css po fajlovima da bi smanjili buduce konflikte. --- frontend/src/styles.css | 103 ++------------------------------------ frontend/src/styles/fx.css | 24 +++++++++ frontend/src/styles/helper.css | 15 ++++++ frontend/src/styles/layout.css | 13 +++++ frontend/src/styles/scrollbar.css | 28 +++++++++++ frontend/src/styles/theme.css | 18 +++++++ 6 files changed, 103 insertions(+), 98 deletions(-) create mode 100644 frontend/src/styles/fx.css create mode 100644 frontend/src/styles/helper.css create mode 100644 frontend/src/styles/layout.css create mode 100644 frontend/src/styles/scrollbar.css create mode 100644 frontend/src/styles/theme.css diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 5e59e735..1100222e 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -1,99 +1,6 @@ @import '~bootstrap/dist/css/bootstrap.min.css'; -body { - /*background-image: url('/assets/images/add_model_background.jpg');*/ - background-color: #003459; -} - -.shadowed:hover { - box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; -} - -.shadowed:first-child:hover { - box-shadow: rgba(0, 152, 189, 0.4) -5px 5px, rgba(0, 152, 189, 0.3) -10px 10px, rgba(0, 152, 189, 0.2) -15px 15px, rgba(0, 152, 189, 0.1) -20px 20px, rgba(0, 152, 189, 0.05) -25px 25px; -} - -.shadowed:last-child:hover { - box-shadow: rgba(0, 152, 189, 0.4) 5px 5px, rgba(0, 152, 189, 0.3) 10px 10px, rgba(0, 152, 189, 0.2) 15px 15px, rgba(0, 152, 189, 0.1) 20px 20px, rgba(0, 152, 189, 0.05) 25px 25px; -} - -.shadow-accent:hover { - box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; - animation-name: holo-hover; - animation-duration: 300ms; - transform: perspective(100em) rotateX(10deg); -} - - -/*Mora da se ispravi za media kada je ekran premali pa se poredjaju u kolonu*/ - -.align-items-view>*:first-child { - transform: perspective(100em) rotateY(25deg) translateZ(1em); -} - -.align-items-view>* { - transform: perspective(100em) translateZ(-2em); -} - -.align-items-view>*:last-child { - transform: perspective(100em) rotateY(-25deg) translateZ(1em); -} - -.bg-light { - background-color: rgba(0, 152, 189, 0.3) !important; -} - -a { - color: #00a8e8 !important; -} - -@keyframes holo-hover { - to { - transform: perspective(100em) rotateX(10deg); - } -} - -@keyframes logo-animation { - from { - transform: perspective(100em) rotateX(50deg) rotateZ(0deg); - } - to { - transform: perspective(100em) rotateX(50deg) rotateZ(360deg); - } -} - -.ann-logo { - animation-name: logo-animation; - animation-duration: 3140ms; - animation-timing-function: linear; - animation-iteration-count: infinite; -} - - -/* width */ - -::-webkit-scrollbar { - width: 10px; - height: 10px; -} - - -/* Track */ - -::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0); -} - - -/* Handle */ - -::-webkit-scrollbar-thumb { - background: rgba(0, 188, 252, 0.6); - border-radius: 25px; -} - - -/* Handle on hover */ - -::-webkit-scrollbar-thumb:hover { - background: rgba(0, 188, 252, 0.8); -} \ No newline at end of file +@import './styles/theme.css'; +@import './styles/layout.css'; +@import './styles/helper.css'; +@import './styles/scrollbar.css'; +@import './styles/fx.css'; \ No newline at end of file diff --git a/frontend/src/styles/fx.css b/frontend/src/styles/fx.css new file mode 100644 index 00000000..9c29ad58 --- /dev/null +++ b/frontend/src/styles/fx.css @@ -0,0 +1,24 @@ +.shadowed:hover { + box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; +} + +.shadowed:first-child:hover { + box-shadow: rgba(0, 152, 189, 0.4) -5px 5px, rgba(0, 152, 189, 0.3) -10px 10px, rgba(0, 152, 189, 0.2) -15px 15px, rgba(0, 152, 189, 0.1) -20px 20px, rgba(0, 152, 189, 0.05) -25px 25px; +} + +.shadowed:last-child:hover { + box-shadow: rgba(0, 152, 189, 0.4) 5px 5px, rgba(0, 152, 189, 0.3) 10px 10px, rgba(0, 152, 189, 0.2) 15px 15px, rgba(0, 152, 189, 0.1) 20px 20px, rgba(0, 152, 189, 0.05) 25px 25px; +} + +.shadow-accent:hover { + box-shadow: rgba(0, 152, 189, 0.4) 0px 5px, rgba(0, 152, 189, 0.3) 0px 10px, rgba(0, 152, 189, 0.2) 0px 15px, rgba(0, 152, 189, 0.1) 0px 20px, rgba(0, 152, 189, 0.05) 0px 25px; + animation-name: holo-hover; + animation-duration: 300ms; + transform: perspective(100em) rotateX(10deg); +} + +@keyframes holo-hover { + to { + transform: perspective(100em) rotateX(10deg); + } +} \ No newline at end of file diff --git a/frontend/src/styles/helper.css b/frontend/src/styles/helper.css new file mode 100644 index 00000000..bed289e4 --- /dev/null +++ b/frontend/src/styles/helper.css @@ -0,0 +1,15 @@ +@keyframes logo-animation { + from { + transform: perspective(100em) rotateX(50deg) rotateZ(0deg); + } + to { + transform: perspective(100em) rotateX(50deg) rotateZ(360deg); + } +} + +.ann-logo { + animation-name: logo-animation; + animation-duration: 3140ms; + animation-timing-function: linear; + animation-iteration-count: infinite; +} \ No newline at end of file diff --git a/frontend/src/styles/layout.css b/frontend/src/styles/layout.css new file mode 100644 index 00000000..e24da375 --- /dev/null +++ b/frontend/src/styles/layout.css @@ -0,0 +1,13 @@ +/*Mora da se ispravi za media kada je ekran premali pa se poredjaju u kolonu*/ + +.align-items-view>*:first-child { + transform: perspective(100em) rotateY(25deg) translateZ(1em); +} + +.align-items-view>* { + transform: perspective(100em) translateZ(-2em); +} + +.align-items-view>*:last-child { + transform: perspective(100em) rotateY(-25deg) translateZ(1em); +} \ No newline at end of file diff --git a/frontend/src/styles/scrollbar.css b/frontend/src/styles/scrollbar.css new file mode 100644 index 00000000..7fb79329 --- /dev/null +++ b/frontend/src/styles/scrollbar.css @@ -0,0 +1,28 @@ +/* width */ + +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + + +/* Track */ + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0); +} + + +/* Handle */ + +::-webkit-scrollbar-thumb { + background: rgba(0, 188, 252, 0.6); + border-radius: 25px; +} + + +/* Handle on hover */ + +::-webkit-scrollbar-thumb:hover { + background: rgba(0, 188, 252, 0.8); +} \ No newline at end of file diff --git a/frontend/src/styles/theme.css b/frontend/src/styles/theme.css new file mode 100644 index 00000000..3ef44e54 --- /dev/null +++ b/frontend/src/styles/theme.css @@ -0,0 +1,18 @@ +:root { + --ns-primary: #00a8e8; + --ns-bg: #003459; + --ns-bg-transparent: rgba(0, 152, 189, 0.3) +} + +body { + /*background-image: url('/assets/images/add_model_background.jpg');*/ + background-color: var(--ns-bg); +} + +.bg-light { + background-color: var(--ns-bg-transparent) !important; +} + +a { + color: var(--ns-primary) !important; +} \ No newline at end of file -- cgit v1.2.3 From be16eb5bf36c69c599b81cfdac866811bdbc4df6 Mon Sep 17 00:00:00 2001 From: Sonja Galovic Date: Mon, 18 Apr 2022 00:20:08 +0200 Subject: Omogucen izbor enkodiranja za svaku kolonu. Izmenjena klasa Experiment da sadrzi niz parova naziv kolone - enkoding. Ispravljen bag kod menjanja dugmica "izaberi" i "dodaj dataset". --- frontend/src/app/_data/Experiment.ts | 11 +- .../dataset-load/dataset-load.component.ts | 6 +- .../src/app/experiment/experiment.component.html | 297 ++++++++++----------- .../src/app/experiment/experiment.component.ts | 17 +- 4 files changed, 168 insertions(+), 163 deletions(-) diff --git a/frontend/src/app/_data/Experiment.ts b/frontend/src/app/_data/Experiment.ts index 453f6ca0..23fd77d4 100644 --- a/frontend/src/app/_data/Experiment.ts +++ b/frontend/src/app/_data/Experiment.ts @@ -18,8 +18,7 @@ export default class Experiment { public randomTestSet: boolean = true, public randomTestSetDistribution: number = 0.1, //0.1-0.9 (10% - 90%) JESTE OVDE ZAKUCANO 10, AL POSLATO JE KAO 0.1 BACK-U - //TODO - za svaku kolonu se bira enkoding - public encoding: Encoding = Encoding.Label + public encodings: ColumnEncoding[] = []//[{columnName: "", columnEncoding: Encoding.Label}] ) { } } @@ -65,4 +64,12 @@ export enum Encoding { WOE = 'woe', Quantile = 'quantile' */ +} + +export class ColumnEncoding { + constructor ( + public columnName: string, + public encoding: Encoding + ) + {} } \ No newline at end of file diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts index 62cca456..73dbf2d2 100644 --- a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts +++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts @@ -41,12 +41,14 @@ export class DatasetLoadComponent implements OnInit { viewMyDatasetsForm() { this.showMyDatasets = true; - this.resetSelectedDataset(); + if (this.selectedDataset != undefined) + this.resetSelectedDataset(); //this.resetCbsAndRbs(); //TREBA DA SE DESI } viewNewDatasetForm() { this.showMyDatasets = false; - this.resetSelectedDataset(); + if (this.selectedDataset != undefined) + this.resetSelectedDataset(); //this.resetCbsAndRbs(); //TREBA DA SE DESI } diff --git a/frontend/src/app/experiment/experiment.component.html b/frontend/src/app/experiment/experiment.component.html index e46f5bd9..5b3b2c43 100644 --- a/frontend/src/app/experiment/experiment.component.html +++ b/frontend/src/app/experiment/experiment.component.html @@ -13,150 +13,131 @@