aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app/_elements
diff options
context:
space:
mode:
authorNevena Bojovic <nenabojov@gmail.com>2022-04-06 21:20:32 +0200
committerNevena Bojovic <nenabojov@gmail.com>2022-04-06 21:20:32 +0200
commit8295292c8f593ec7ab9dd527ad8afce0bc474364 (patch)
treeb381a151784856d3f0e40c751d96ec012321f8a1 /frontend/src/app/_elements
parent45201c5c388b4988af3b319d6702c60397929dfc (diff)
parent499f641683767d2da735fb760c89f0c611e37596 (diff)
Merge branch 'dev' of http://gitlab.pmf.kg.ac.rs/igrannonica/neuronstellar into dev
# Conflicts: # backend/api/api/appsettings.json
Diffstat (limited to 'frontend/src/app/_elements')
-rw-r--r--frontend/src/app/_elements/annvisual/annvisual.component.ts3
-rw-r--r--frontend/src/app/_elements/datatable/datatable.component.html46
-rw-r--r--frontend/src/app/_elements/datatable/datatable.component.ts2
-rw-r--r--frontend/src/app/_elements/loading/loading.component.css81
-rw-r--r--frontend/src/app/_elements/loading/loading.component.html11
-rw-r--r--frontend/src/app/_elements/loading/loading.component.spec.ts25
-rw-r--r--frontend/src/app/_elements/loading/loading.component.ts15
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.css0
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.html221
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.spec.ts25
-rw-r--r--frontend/src/app/_elements/model-load/model-load.component.ts79
-rw-r--r--frontend/src/app/_elements/navbar/navbar.component.html8
-rw-r--r--frontend/src/app/_elements/notifications/notifications.component.html23
-rw-r--r--frontend/src/app/_elements/notifications/notifications.component.ts12
14 files changed, 521 insertions, 30 deletions
diff --git a/frontend/src/app/_elements/annvisual/annvisual.component.ts b/frontend/src/app/_elements/annvisual/annvisual.component.ts
index 53e4e2ca..df0a3898 100644
--- a/frontend/src/app/_elements/annvisual/annvisual.component.ts
+++ b/frontend/src/app/_elements/annvisual/annvisual.component.ts
@@ -18,7 +18,7 @@ export class AnnvisualComponent implements OnInit {
let hiddenlayerstring: string = '';
let digraphstring: string = 'digraph {';
- for (let i = 0; i < this.model.inputColumns.length; i++) {
+ for (let i = 0; i < /*this.model.inputColumns.length*/ 10; i++) {
inputlayerstring = inputlayerstring + 'i' + i + ',';
}
inputlayerstring = inputlayerstring.slice(0, -1);
@@ -35,7 +35,6 @@ export class AnnvisualComponent implements OnInit {
}
digraphstring = digraphstring + 'o}';
-
graphviz('#graph').renderDot(digraphstring);
}
diff --git a/frontend/src/app/_elements/datatable/datatable.component.html b/frontend/src/app/_elements/datatable/datatable.component.html
index bd9e7a13..8fcd44ac 100644
--- a/frontend/src/app/_elements/datatable/datatable.component.html
+++ b/frontend/src/app/_elements/datatable/datatable.component.html
@@ -1,25 +1,31 @@
<div *ngIf="data">
- <div class="table-responsive" style="max-height: 50vh; max-width: 100%; overflow: scroll;">
- <table *ngIf="hasHeader" class="table table-bordered table-light">
- <thead>
- <tr>
- <th *ngFor="let item of data[0]; let i = index">{{item}}</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let row of data | slice:1">
- <td *ngFor="let col of row">{{col}}</td>
- </tr>
- </tbody>
- </table>
+ <div class="table-responsive" style="height: 34rem; overflow: auto; border-radius: 5px;" class="mh-5">
+ <div *ngIf="!loaded" style="background-color: #003459; width: 100%; height: 100%;"
+ class="d-flex justify-content-center align-items-center">
+ <app-loading></app-loading>
+ </div>
+ <div *ngIf="loaded">
+ <table *ngIf="hasHeader" class="table table-bordered table-light">
+ <thead>
+ <tr>
+ <th *ngFor="let item of data[0]; let i = index">{{item}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let row of data | slice:1">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ </tbody>
+ </table>
- <table *ngIf="data.length > 0 && !hasHeader" class="table table-bordered table-light">
- <tbody>
- <tr *ngFor="let row of data">
- <td *ngFor="let col of row">{{col}}</td>
- </tr>
- </tbody>
- </table>
+ <table *ngIf="data.length > 0 && !hasHeader" class="table table-bordered table-light">
+ <tbody>
+ <tr *ngFor="let row of data">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
<div id="info">
diff --git a/frontend/src/app/_elements/datatable/datatable.component.ts b/frontend/src/app/_elements/datatable/datatable.component.ts
index d3740d83..3343f6f0 100644
--- a/frontend/src/app/_elements/datatable/datatable.component.ts
+++ b/frontend/src/app/_elements/datatable/datatable.component.ts
@@ -11,6 +11,8 @@ export class DatatableComponent implements OnInit {
@Input() data?: any[] = [];
+ loaded = false;
+
constructor() { }
ngOnInit(): void {
diff --git a/frontend/src/app/_elements/loading/loading.component.css b/frontend/src/app/_elements/loading/loading.component.css
new file mode 100644
index 00000000..f39f60ee
--- /dev/null
+++ b/frontend/src/app/_elements/loading/loading.component.css
@@ -0,0 +1,81 @@
+.lds-grid {
+ display: inline-block;
+ position: relative;
+ width: 80px;
+ height: 80px;
+}
+
+.lds-grid div {
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ background: #fff;
+ animation: lds-grid 1.2s linear infinite;
+}
+
+.lds-grid div:nth-child(1) {
+ top: 8px;
+ left: 8px;
+ animation-delay: 0s;
+}
+
+.lds-grid div:nth-child(2) {
+ top: 8px;
+ left: 32px;
+ animation-delay: -0.4s;
+}
+
+.lds-grid div:nth-child(3) {
+ top: 8px;
+ left: 56px;
+ animation-delay: -0.8s;
+}
+
+.lds-grid div:nth-child(4) {
+ top: 32px;
+ left: 8px;
+ animation-delay: -0.4s;
+}
+
+.lds-grid div:nth-child(5) {
+ top: 32px;
+ left: 32px;
+ animation-delay: -0.8s;
+}
+
+.lds-grid div:nth-child(6) {
+ top: 32px;
+ left: 56px;
+ animation-delay: -1.2s;
+}
+
+.lds-grid div:nth-child(7) {
+ top: 56px;
+ left: 8px;
+ animation-delay: -0.8s;
+}
+
+.lds-grid div:nth-child(8) {
+ top: 56px;
+ left: 32px;
+ animation-delay: -1.2s;
+}
+
+.lds-grid div:nth-child(9) {
+ top: 56px;
+ left: 56px;
+ animation-delay: -1.6s;
+}
+
+@keyframes lds-grid {
+
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0.5;
+ }
+} \ No newline at end of file
diff --git a/frontend/src/app/_elements/loading/loading.component.html b/frontend/src/app/_elements/loading/loading.component.html
new file mode 100644
index 00000000..d2c7b74e
--- /dev/null
+++ b/frontend/src/app/_elements/loading/loading.component.html
@@ -0,0 +1,11 @@
+<div class="lds-grid">
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/loading/loading.component.spec.ts b/frontend/src/app/_elements/loading/loading.component.spec.ts
new file mode 100644
index 00000000..7aacfad9
--- /dev/null
+++ b/frontend/src/app/_elements/loading/loading.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoadingComponent } from './loading.component';
+
+describe('LoadingComponent', () => {
+ let component: LoadingComponent;
+ let fixture: ComponentFixture<LoadingComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ LoadingComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoadingComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_elements/loading/loading.component.ts b/frontend/src/app/_elements/loading/loading.component.ts
new file mode 100644
index 00000000..4dff0cdf
--- /dev/null
+++ b/frontend/src/app/_elements/loading/loading.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-loading',
+ templateUrl: './loading.component.html',
+ styleUrls: ['./loading.component.css']
+})
+export class LoadingComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit(): void {
+ }
+
+}
diff --git a/frontend/src/app/_elements/model-load/model-load.component.css b/frontend/src/app/_elements/model-load/model-load.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_elements/model-load/model-load.component.css
diff --git a/frontend/src/app/_elements/model-load/model-load.component.html b/frontend/src/app/_elements/model-load/model-load.component.html
new file mode 100644
index 00000000..0c6735a9
--- /dev/null
+++ b/frontend/src/app/_elements/model-load/model-load.component.html
@@ -0,0 +1,221 @@
+<div>
+ <div class="form-group row mt-3 mb-2 d-flex justify-content-center">
+ <h2 class="col-2"> Nov model: </h2>
+ <div class="col-3">
+ <label for="name" class="col-form-label">Naziv modela:</label>
+ <input type="text" class="form-control" name="name" placeholder="Naziv..." [(ngModel)]="newModel.name">
+ </div>
+ <div class="col-5">
+ <label for="desc" class="col-sm-2 col-form-label">Opis:</label>
+ <div>
+ <textarea class="form-control" name="desc" rows="3" [(ngModel)]="newModel.description"></textarea>
+ </div>
+ </div>
+ <div class="col-2">
+ <label for="dateCreated" class="col-form-label">Datum:</label> &nbsp;&nbsp;
+ <input type="text" class="form-control-plaintext" id="dateCreated" placeholder="--/--/--"
+ value="{{newModel.dateCreated | date: 'dd/MM/yyyy'}}" readonly>
+ </div>
+ </div>
+ <h2 class="mt-5 mb-4">Parametri treniranja:</h2>
+ <div>
+ <div class="row p-2">
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="type" class="col-form-label">Tip problema: </label>
+ </div>
+ <div class="col-2">
+ <select id=typeOptions class="form-control" name="type" [(ngModel)]="newModel.type"
+ (change)="filterOptions()">
+ <option
+ *ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="hiddenLayers" class="col-form-label">Broj skrivenih slojeva: </label>
+ </div>
+ <div class="col-1">
+ <input type="number" min="1" class="form-control" name="hiddenLayers"
+ [(ngModel)]="newModel.hiddenLayers"
+ (change)="newModel.hiddenLayerActivationFunctions = [].constructor(newModel.hiddenLayers).fill(newModel.hiddenLayerActivationFunctions[0])">
+ </div>
+ </div>
+
+ <div class="row p-2">
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="encoding" class="col-form-label">Enkoding: </label>
+ </div>
+ <div class="col-2">
+ <select id=encodingOptions class="form-control" name="encoding" [(ngModel)]="newModel.encoding">
+ <option *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="hiddenLayerNeurons" class="col-form-label">Broj neurona skrivenih slojeva: </label>
+ </div>
+ <div class="col-1">
+ <input type="number" min="1" class="form-control" name="hiddenLayerNeurons"
+ [(ngModel)]="newModel.hiddenLayerNeurons">
+ </div>
+ </div>
+
+ <div class="row p-2">
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="optimizer" class="col-form-label">Optimizacija: </label>
+ </div>
+ <div class="col-2">
+ <select id=optimizerOptions class="form-control" name="optimizer" [(ngModel)]="newModel.optimizer">
+ <option *ngFor="let option of Object.keys(Optimizer); let optionName of Object.values(Optimizer)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="batchSize" class="col-form-label">Broj uzorka po iteraciji: </label>
+ </div>
+ <div class="col-1">
+ <input type="number" min="1" class="form-control" name="batchSize" [(ngModel)]="newModel.batchSize">
+ </div>
+ </div>
+ <div class="row p-2">
+ <div class="col-1">
+ </div>
+ <div class="col-3">
+ <label for="lossFunction" class="col-form-label">Funkcija obrade gubitka: </label>
+ </div>
+ <div class="col-2">
+ <select id=lossFunctionOptions class="form-control" name="lossFunction"
+ [(ngModel)]="newModel.lossFunction" aria-checked="true">
+ <option
+ *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ <div class="col-1"></div>
+ <div class="col-3 mt-2">
+ <label for="type" class="form-check-label">Nasumičan redosled podataka?</label>
+ <input class="mx-3 form-check-input" type="checkbox" [(ngModel)]="newModel.randomOrder" type="checkbox"
+ value="" checked>
+ </div>
+ </div>
+ <div class="border m-3">
+ <div class="row p-2 m-2">
+ <div class="col-4">
+ <label for="splitYesNo" class="form-check-label">
+ <h3>Podela test skupa:&nbsp;&nbsp;
+ <input id="splitYesNo" class="form-check-input" type="checkbox"
+ [checked]="newModel.randomTestSet"
+ (change)="newModel.randomTestSet = !newModel.randomTestSet">
+ </h3>
+ </label>
+ </div>
+ <div class="col-8">
+ trening
+ <mat-slider style="width: 85%;" min="10" max="90" step="10" value="10"
+ name="randomTestSetDistribution" thumbLabel [disabled]="!newModel.randomTestSet"
+ [(ngModel)]="tempTestSetDistribution">
+ </mat-slider>
+ test
+ </div>
+ </div>
+
+ <div class="row p-2 mx-2">
+ <div class="col-4">
+ <label for="percentage" class="form-label">Procenat podataka koji se uzima za trening
+ skup:</label>
+ </div>
+ <div class="col-2">
+ <input id="percentage" type="number" class="form-control" min="10" max="90" step="10" value="90"
+ [(ngModel)]="tempTestSetDistribution" [disabled]="!newModel.randomTestSet">
+ </div>
+ </div>
+ </div>
+ <h3>Aktivacione funkcije:</h3>
+
+ <div class="row p-2 m-2" style="align-self: center;">
+ <div class="col-3">
+ <label for="hiddenLayerActivationFunction" class="col-form-label" style="text-align: center;">Funkcija
+ aktivacije skrivenih
+ slojeva:</label>
+ </div>
+ <div class="col-3">
+ <div *ngFor="let item of [].constructor(newModel.hiddenLayers); let i = index">
+ <div class="input-group mb-2">
+ <div class="input-group-prepend">
+ <span class="input-group-text">#{{i+1}}</span>
+ </div>
+ <select [id]="'hiddenLayerActivationFunctionOption_'+i" class="form-control"
+ [(ngModel)]="newModel.hiddenLayerActivationFunctions[i]">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="col-3">
+ <label for="outputLayerActivationFunction" class="col-form-label" style="text-align: center;">Funkcija
+ aktivacije izlaznog
+ sloja:</label>
+ </div>
+ <div class="col-3">
+ <select id=outputLayerActivationFunctionOptions class="form-control"
+ name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ <div class="col">
+ </div>
+ </div>
+ </div>
+ <br><br>
+ <hr>
+ <div class="form-check form-check-inline overflow-auto " style="width: max-content;">
+ <h3>Izaberite metrike:</h3>
+ <div id="divMetricsinput">
+
+ <div *ngFor="let option of Object.keys(metrics); let optionName of Object.values(metrics) "
+ class="form-check form-check-inline">
+
+ <input name="cbmetrics" class="form-check-input" type="checkbox" value="{{option}}"
+ id="metrics_{{option}}" style="float: left;">
+ <label class="form-check-label" for="metrics_{{option}}" for="inlineCheckbox2">
+ {{optionName}}
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="form-group row mt-5 mb-3">
+ <div class="col"></div>
+ <button class="btn btn-lg col-4" style="background-color:#003459; color:white;" (click)="addModel();">Sačuvaj
+ model</button>
+ <div class="col"></div>
+ </div>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/model-load/model-load.component.spec.ts b/frontend/src/app/_elements/model-load/model-load.component.spec.ts
new file mode 100644
index 00000000..1dafd966
--- /dev/null
+++ b/frontend/src/app/_elements/model-load/model-load.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ModelLoadComponent } from './model-load.component';
+
+describe('ModelLoadComponent', () => {
+ let component: ModelLoadComponent;
+ let fixture: ComponentFixture<ModelLoadComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ ModelLoadComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ModelLoadComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_elements/model-load/model-load.component.ts b/frontend/src/app/_elements/model-load/model-load.component.ts
new file mode 100644
index 00000000..1d38de68
--- /dev/null
+++ b/frontend/src/app/_elements/model-load/model-load.component.ts
@@ -0,0 +1,79 @@
+import { Component, OnInit } from '@angular/core';
+import Shared from 'src/app/Shared';
+import Model, { ActivationFunction, Encoding, LossFunction, LossFunctionBinaryClassification, LossFunctionMultiClassification, LossFunctionRegression, Metrics, MetricsBinaryClassification, MetricsMultiClassification, MetricsRegression, NullValueOptions, Optimizer, ProblemType } from 'src/app/_data/Model';
+import { ModelsService } from 'src/app/_services/models.service';
+
+@Component({
+ selector: 'app-model-load',
+ templateUrl: './model-load.component.html',
+ styleUrls: ['./model-load.component.css']
+})
+export class ModelLoadComponent implements OnInit {
+
+ newModel: Model = new Model();
+
+ ProblemType = ProblemType;
+ Encoding = Encoding;
+ ActivationFunction = ActivationFunction;
+ metrics: any = Metrics;
+ LossFunction = LossFunction;
+ Optimizer = Optimizer;
+ Object = Object;
+ document = document;
+ shared = Shared;
+
+ term: string = "";
+ selectedProblemType: string = '';
+ selectedMetrics = [];
+ tempTestSetDistribution = 90;
+ lossFunction: any = LossFunction;
+
+ constructor(private models: ModelsService) { }
+
+ ngOnInit(): void {
+ }
+
+ getMetrics() {
+ this.newModel.metrics = [];
+ let cb = document.getElementsByName("cbmetrics");
+
+ for (let i = 0; i < cb.length; i++) {
+ let chb = <HTMLInputElement>cb[i];
+ if (chb.checked == true)
+ this.newModel.metrics.push(chb.value);
+ }
+ }
+
+ addModel() {
+ this.getMetrics();
+
+ this.newModel.randomTestSetDistribution = 1 - Math.round(this.tempTestSetDistribution / 100 * 10) / 10;
+ this.newModel.username = Shared.username;
+
+ this.models.addModel(this.newModel).subscribe((response) => {
+ Shared.openDialog('Model dodat', 'Model je uspešno dodat u bazu.');
+ // treba da se selektuje nov model u listi modela
+ }, (error) => {
+ Shared.openDialog('Greška', 'Model sa unetim nazivom već postoji u Vašoj kolekciji.\nPromenite naziv modela i nastavite sa kreiranim datasetom.');
+ });
+ }
+
+ filterOptions() {
+ switch (this.newModel.type) {
+ case 'regresioni':
+ this.lossFunction = LossFunctionRegression;
+ this.metrics = MetricsRegression;
+ break;
+ case 'binarni-klasifikacioni':
+ this.lossFunction = LossFunctionBinaryClassification;
+ this.metrics = MetricsBinaryClassification;
+ break;
+ case 'multi-klasifikacioni':
+ this.lossFunction = LossFunctionMultiClassification;
+ this.metrics = MetricsMultiClassification;
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html
index 82a1ea07..dbee4773 100644
--- a/frontend/src/app/_elements/navbar/navbar.component.html
+++ b/frontend/src/app/_elements/navbar/navbar.component.html
@@ -8,8 +8,9 @@
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a routerLink="" class="nav-link px-2"
[class]="(currentUrl === '') ? 'text-secondary' : 'text-white'">Početna</a></li>
- <li><a routerLink="add-model" class="nav-link px-2"
- [class]="(currentUrl === '/add-model') ? 'text-secondary' : 'text-white'">Dodaj model</a></li>
+ <li><a routerLink="experiment" class="nav-link px-2"
+ [class]="(currentUrl === '/add-model') ? 'text-secondary' : 'text-white'">Eksperimentiši</a>
+ </li>
<li><a routerLink="my-predictors" class="nav-link px-2"
[class]="(currentUrl === '/my-predictors') ? 'text-secondary' : 'text-white' + (shared.loggedIn) ? '' : 'disabled'">Predvidi</a>
</li>
@@ -18,7 +19,8 @@
<div *ngIf="shared.loggedIn" class="dropdown text-end">
<a href="#" class="d-block link-light text-decoration-none dropdown-toggle" id="dropdownUser1"
data-bs-toggle="dropdown" aria-expanded="false">
- <img [src]="'/assets/profilePictures/'+ shared.photoId +'.png'" alt="mdo" width="32" height="32" class="rounded-circle">
+ <img [src]="'/assets/profilePictures/'+ shared.photoId +'.png'" alt="mdo" width="32" height="32"
+ class="rounded-circle">
</a>
<ul class="dropdown-menu text-small" aria-labelledby="dropdownUser1"
style="position: absolute; inset: 0px 0px auto auto; margin: 0px; transform: translate(0px, 34px);"
diff --git a/frontend/src/app/_elements/notifications/notifications.component.html b/frontend/src/app/_elements/notifications/notifications.component.html
index d1da41b4..0b87e4fc 100644
--- a/frontend/src/app/_elements/notifications/notifications.component.html
+++ b/frontend/src/app/_elements/notifications/notifications.component.html
@@ -1,3 +1,20 @@
-<div *ngIf="notifications" class="position-fixed card card-body bg-dark text-white m-3" style="bottom: 0; right: 0;">
- <h3>Notifikacije</h3>
-</div> \ No newline at end of file
+<div *ngIf="notifications" class="position-fixed card card-body p-1 m-3" style="bottom: 0; right: 0; width: 18rem;">
+ <h2 class="m-auto" (click)="closed = !closed;" data-bs-toggle="collapse" href="#collapseNotifs" role="button"
+ aria-expanded="true" aria-controls="collapseNotifs">Notifikacije
+ <button class="border-0 bg-white">
+ <mat-icon class="position-absolute" style="top: 8px; right: 12px;">{{closed ? 'keyboard_arrow_up' :
+ 'keyboard_arrow_down'}}</mat-icon>
+ </button>
+ </h2>
+
+ <div id="collapseNotifs" class="collapse show">
+ <div *ngFor="let notification of notifications" class="p-2 m-1 border rounded">
+ <div class="d-flex flex-row">
+ <p>{{notification.title}}</p>
+ </div>
+ <div class="border-3 border-primary bg-dark m-1" style="height: 5px; margin-top: -10px !important;">
+ <div class="bg-primary" style="height: 5px;" [style]="'width: '+(notification.progress*100)+'%;'">
+ </div>
+ </div>
+ </div>
+ </div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/notifications/notifications.component.ts b/frontend/src/app/_elements/notifications/notifications.component.ts
index 6c1d555b..82613448 100644
--- a/frontend/src/app/_elements/notifications/notifications.component.ts
+++ b/frontend/src/app/_elements/notifications/notifications.component.ts
@@ -1,5 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { WebSocketService } from 'src/app/_services/web-socket.service';
+import Notification from 'src/app/_data/Notification';
@Component({
selector: 'app-notifications',
@@ -8,9 +9,16 @@ import { WebSocketService } from 'src/app/_services/web-socket.service';
})
export class NotificationsComponent implements OnInit {
- notifications?: any[];
+ notifications?: Notification[];
+ closed: boolean = false;
- constructor(private wsService: WebSocketService) { }
+ constructor(private wsService: WebSocketService) {
+ this.notifications = [
+ new Notification("Titanik (Preziveli)", "79768456867", 0.2),
+ new Notification("Test Prediktor 1", "56758768678", 0.4),
+ new Notification("Test Prediktor 2", "11344556425", 0.7)
+ ]
+ }
ngOnInit(): void {
// this.wsService.send('test');