aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authorSonja Galovic <galovicsonja@gmail.com>2022-04-25 22:22:04 +0200
committerSonja Galovic <galovicsonja@gmail.com>2022-04-25 22:22:04 +0200
commit1a3e9c2879fd9be723a195def352ae00e690a4fe (patch)
tree30f3ed9ef268d5f74784fb89c7dbcb939ab43e64 /frontend
parent3e07b3304b65fcab6740a05231999dfc453ffbb9 (diff)
parentf20f77226f0106ed2c9e2bb7b49550f5e5eb4c50 (diff)
Merge branch 'redesign' of http://gitlab.pmf.kg.ac.rs/igrannonica/neuronstellar into redesign
# Conflicts: # frontend/src/app/app-routing.module.ts # frontend/src/app/app.module.ts
Diffstat (limited to 'frontend')
-rw-r--r--frontend/angular.json216
-rw-r--r--frontend/package-lock.json12
-rw-r--r--frontend/src/app/Shared.ts12
-rw-r--r--frontend/src/app/_data/Model.ts8
-rw-r--r--frontend/src/app/_elements/_charts/box-plot/box-plot.component.html2
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css0
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html1
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts25
-rw-r--r--frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts34
-rw-r--r--frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html2
-rw-r--r--frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts27
-rw-r--r--frontend/src/app/_elements/folder/folder.component.css27
-rw-r--r--frontend/src/app/_elements/folder/folder.component.html59
-rw-r--r--frontend/src/app/_elements/folder/folder.component.ts36
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.css49
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.html223
-rw-r--r--frontend/src/app/_elements/form-model/form-model.component.ts133
-rw-r--r--frontend/src/app/_elements/navbar/navbar.component.html2
-rw-r--r--frontend/src/app/_elements/reactive-background/reactive-background.component.ts19
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.css62
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.html60
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.ts80
-rw-r--r--frontend/src/app/_pages/home/home.component.html1
-rw-r--r--frontend/src/app/_pages/test/test.component.css0
-rw-r--r--frontend/src/app/_pages/test/test.component.html3
-rw-r--r--frontend/src/app/_pages/test/test.component.spec.ts25
-rw-r--r--frontend/src/app/_pages/test/test.component.ts15
-rw-r--r--frontend/src/app/app-routing.module.ts4
-rw-r--r--frontend/src/app/app.component.html6
-rw-r--r--frontend/src/app/app.component.ts18
-rw-r--r--frontend/src/app/app.module.ts6
-rw-r--r--frontend/src/custom-theme.scss267
-rw-r--r--frontend/src/styles/helper.css23
-rw-r--r--frontend/src/styles/layout.css5
-rw-r--r--frontend/src/styles/theme.css18
35 files changed, 1096 insertions, 384 deletions
diff --git a/frontend/angular.json b/frontend/angular.json
index d1983d31..13c27f40 100644
--- a/frontend/angular.json
+++ b/frontend/angular.json
@@ -1,117 +1,113 @@
{
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "version": 1,
- "newProjectRoot": "projects",
- "projects": {
- "frontend": {
- "projectType": "application",
- "schematics": {
- "@schematics/angular:application": {
- "strict": true
- }
- },
- "root": "",
- "sourceRoot": "src",
- "prefix": "app",
- "architect": {
- "build": {
- "builder": "@angular-devkit/build-angular:browser",
- "options": {
- "outputPath": "dist/frontend",
- "index": "src/index.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.app.json",
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "src/custom-theme.scss",
- "node_modules/bootstrap/dist/css/bootstrap.min.css",
- "src/styles.css",
- "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css"
- ],
- "scripts": [
- "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
- ]
- },
- "configurations": {
- "production": {
- "budgets": [
- {
- "type": "initial",
- "maximumWarning": "2mb",
- "maximumError": "4mb"
- },
- {
- "type": "anyComponentStyle",
- "maximumWarning": "10kb",
- "maximumError": "15kb"
- }
- ],
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "frontend": {
+ "projectType": "application",
+ "schematics": {
+ "@schematics/angular:application": {
+ "strict": true
}
- ],
- "outputHashing": "all"
},
- "development": {
- "buildOptimizer": false,
- "optimization": false,
- "vendorChunk": true,
- "extractLicenses": false,
- "sourceMap": true,
- "namedChunks": true
- }
- },
- "defaultConfiguration": "production"
- },
- "serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
- "configurations": {
- "production": {
- "browserTarget": "frontend:build:production"
- },
- "development": {
- "browserTarget": "frontend:build:development"
+ "root": "",
+ "sourceRoot": "src",
+ "prefix": "app",
+ "architect": {
+ "build": {
+ "builder": "@angular-devkit/build-angular:browser",
+ "options": {
+ "outputPath": "dist/frontend",
+ "index": "src/index.html",
+ "main": "src/main.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "tsconfig.app.json",
+ "assets": [
+ "src/favicon.ico",
+ "src/assets"
+ ],
+ "styles": [
+ "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "src/styles.css",
+ "src/custom-theme.scss"
+ ],
+ "scripts": [
+ "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
+ ]
+ },
+ "configurations": {
+ "production": {
+ "budgets": [{
+ "type": "initial",
+ "maximumWarning": "2mb",
+ "maximumError": "4mb"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "10kb",
+ "maximumError": "15kb"
+ }
+ ],
+ "fileReplacements": [{
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.prod.ts"
+ }],
+ "outputHashing": "all"
+ },
+ "development": {
+ "buildOptimizer": false,
+ "optimization": false,
+ "vendorChunk": true,
+ "extractLicenses": false,
+ "sourceMap": true,
+ "namedChunks": true
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "builder": "@angular-devkit/build-angular:dev-server",
+ "configurations": {
+ "production": {
+ "browserTarget": "frontend:build:production"
+ },
+ "development": {
+ "browserTarget": "frontend:build:development"
+ }
+ },
+ "defaultConfiguration": "development"
+ },
+ "extract-i18n": {
+ "builder": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "browserTarget": "frontend:build"
+ }
+ },
+ "test": {
+ "builder": "@angular-devkit/build-angular:karma",
+ "options": {
+ "main": "src/test.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "tsconfig.spec.json",
+ "karmaConfig": "karma.conf.js",
+ "assets": [
+ "src/favicon.ico",
+ "src/assets"
+ ],
+ "styles": [
+ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
+ "src/styles.css"
+ ],
+ "scripts": []
+ }
+ }
}
- },
- "defaultConfiguration": "development"
- },
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "frontend:build"
- }
- },
- "test": {
- "builder": "@angular-devkit/build-angular:karma",
- "options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.spec.json",
- "karmaConfig": "karma.conf.js",
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
- "src/styles.css"
- ],
- "scripts": []
- }
}
- }
- }
- },
- "defaultProject": "frontend",
- "cli": {
- "warnings": {
- "versionMismatch": false
+ },
+ "defaultProject": "frontend",
+ "cli": {
+ "warnings": {
+ "versionMismatch": false
+ }
}
- }
} \ No newline at end of file
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index b997f7c2..a62a1117 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -3433,9 +3433,9 @@
}
},
"node_modules/async": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
- "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
@@ -14406,9 +14406,9 @@
"dev": true
},
"async": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
- "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dev": true,
"requires": {
"lodash": "^4.17.14"
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/_data/Model.ts b/frontend/src/app/_data/Model.ts
index b273f56a..00ac0d0c 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -14,14 +14,16 @@ export default class Model {
public optimizer: Optimizer = Optimizer.Adam,
public lossFunction: LossFunction = LossFunction.MeanSquaredError,
public inputNeurons: number = 1,
- public hiddenLayerNeurons: number = 1,
+ public hiddenLayerNeurons: number=1,
public hiddenLayers: number = 1,
public batchSize: number = 5,
public hiddenLayerActivationFunctions: string[] = ['sigmoid'],
public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
public uploaderId: string = '',
public metrics: string[] = [], // TODO add to add-model form
- public epochs: number = 5 // TODO add to add-model form
+ public epochs: number = 5, // TODO add to add-model form
+ public inputColNum:number=5,
+ public learningRate:number=0.01
) { }
}
@@ -156,4 +158,4 @@ export enum MetricsMultiClassification {
Precision = 'precision_score',
Recall = 'recall_score',
F1 = 'f1_score',
-}
+} \ No newline at end of file
diff --git a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html
index 20cf6487..2006eada 100644
--- a/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html
+++ b/frontend/src/app/_elements/_charts/box-plot/box-plot.component.html
@@ -1 +1 @@
-<p>box-plot works!</p>
+<p>Box-plot</p> \ No newline at end of file
diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.css
diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html
new file mode 100644
index 00000000..4befc7dc
--- /dev/null
+++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.html
@@ -0,0 +1 @@
+<canvas #doughnut width="800" height="450"></canvas>
diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts
new file mode 100644
index 00000000..67309670
--- /dev/null
+++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DoughnutChartComponent } from './doughnut-chart.component';
+
+describe('DoughnutChartComponent', () => {
+ let component: DoughnutChartComponent;
+ let fixture: ComponentFixture<DoughnutChartComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ DoughnutChartComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DoughnutChartComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts
new file mode 100644
index 00000000..4c7508fe
--- /dev/null
+++ b/frontend/src/app/_elements/_charts/doughnut-chart/doughnut-chart.component.ts
@@ -0,0 +1,34 @@
+import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import {Chart} from 'node_modules/chart.js';
+
+@Component({
+ selector: 'app-doughnut-chart',
+ templateUrl: './doughnut-chart.component.html',
+ styleUrls: ['./doughnut-chart.component.css']
+})
+export class DoughnutChartComponent implements AfterViewInit {
+
+ @ViewChild('doughnut') chartRef!: ElementRef;
+ constructor() { }
+
+ ngAfterViewInit(): void {
+ const myChart = new Chart(this.chartRef.nativeElement, {
+ type: 'doughnut',
+ data: {
+ labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
+ datasets: [{
+ label: "Population (millions)",
+ backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
+ data: [2478,5267,734,784,433]
+ }]
+ },
+ /*options: {
+ title: {
+ display: true,
+ text: 'Predicted world population (millions) in 2050'
+ }
+ }*/
+ });
+ }
+
+}
diff --git a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html
index 43a2d766..413aa6f3 100644
--- a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html
+++ b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.html
@@ -1 +1 @@
-<p>pie-chart works!</p>
+<canvas #piechart width="800" height="450"></canvas>
diff --git a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts
index dde5cbab..e7d79615 100644
--- a/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts
+++ b/frontend/src/app/_elements/_charts/pie-chart/pie-chart.component.ts
@@ -1,15 +1,36 @@
-import { Component, OnInit } from '@angular/core';
+import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import {Chart} from 'node_modules/chart.js';
@Component({
selector: 'app-pie-chart',
templateUrl: './pie-chart.component.html',
styleUrls: ['./pie-chart.component.css']
})
-export class PieChartComponent implements OnInit {
+export class PieChartComponent implements AfterViewInit {
+ @ViewChild('piechart') chartRef!: ElementRef;
constructor() { }
- ngOnInit(): void {
+ ngAfterViewInit(): void {
+ const myChart = new Chart(this.chartRef.nativeElement, {
+ type: 'pie',
+ data: {
+ labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
+ datasets: [{
+ label: "Population (millions)",
+ backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
+ data: [2478,5267,734,784,433]
+ }]
+ },
+ /*options: {
+ title: {
+ display: true,
+ text: 'Predicted world population (millions) in 2050'
+ }
+ }*/
+});
+
}
+
}
diff --git a/frontend/src/app/_elements/folder/folder.component.css b/frontend/src/app/_elements/folder/folder.component.css
index cfb0d087..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 {
@@ -55,7 +57,7 @@
}
.tab-link:active {
- color: var(--ns-accent) !important;
+ text-decoration: underline !important;
}
.selected-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-100);
+ 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 11fccc56..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" *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" *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 34c8db82..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
}
@@ -98,6 +111,23 @@ export class FolderComponent implements OnInit {
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/form-model/form-model.component.css b/frontend/src/app/_elements/form-model/form-model.component.css
index 9340fed5..f4d085ea 100644
--- a/frontend/src/app/_elements/form-model/form-model.component.css
+++ b/frontend/src/app/_elements/form-model/form-model.component.css
@@ -1,3 +1,50 @@
-*{
+#container{
+ color:var(--offwhite);
+}
+mat-label{
color: var(--offwhite) !important;
+}
+select{
+ color: var(--offwhite) !important;
+}
+mat-form-field{
+ color: var(--offwhite) !important;
+ padding: 0;
+}
+hr{
+ color: var(--offwhite) !important;
+ margin-bottom: 30px;;
+}
+.row{
+ margin: 0;
+ padding: 0;
+}
+mat-icon{
+ color: var(--ns-primary);
+}
+#rowhn{
+ margin-bottom:-50px;
+ padding: 0;
+}
+.neuron{
+
+ text-align: justify;
+ border: 1px solid white;
+ border-radius: 5px;
+ padding: 0;
+ color: white!important;
+ background-color: var(--ns-bg-dark-100) !important;
+ min-width: none;
+ max-width: 12.5rem;
+
+}
+mat-form-field{
+ font-size: 12px;
+}
+col-1{
+ text-align: center;
+}
+mat-icon{
+ margin-right: 5px;
+ margin-left: -7px;
} \ No newline at end of file
diff --git a/frontend/src/app/_elements/form-model/form-model.component.html b/frontend/src/app/_elements/form-model/form-model.component.html
index 5db2cb49..0b63c5ac 100644
--- a/frontend/src/app/_elements/form-model/form-model.component.html
+++ b/frontend/src/app/_elements/form-model/form-model.component.html
@@ -1,31 +1,29 @@
-<div class="container">
+<div id="container">
<div class="row">
<div class="col-sm">
<div class="row">
- <mat-form-field appearance="fill">
- <mat-label>Naziv</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option label="--select something --"></option>
- <option value="saab">Saab</option>
- <option value="mercedes">Mercedes</option>
- <option value="audi">Audi</option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
- Obavezno polje
- </mat-error>
- </mat-form-field>
+ <mat-form-field class="example-full-width" appearance="fill">
+ <mat-label>Naziv</mat-label>
+ <input type="text" matInput [formControl]="nameFormControl">
+ <mat-error *ngIf="nameFormControl.hasError('name') && !nameFormControl.hasError('required')">
+ Unesite naziv
+ </mat-error>
+ <mat-error *ngIf="nameFormControl.hasError('required')">
+ Naziv je <strong>obavezan</strong>
+ </mat-error>
+ </mat-form-field>
</div>
<div class="row">
<mat-form-field appearance="fill">
<mat-label>Tip problema</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option
+ <mat-select matNativeControl required [formControl]="selectTypeFormControl">
+ <mat-option
*ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
[value]="option">
{{ optionName }}
- </option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
+ </mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectTypeFormControl.hasError('required')">
Obavezno polje
</mat-error>
</mat-form-field>
@@ -35,105 +33,152 @@
<div class="row">
<mat-form-field appearance="fill">
<mat-label>Optimizacija</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option
+ <mat-select matNativeControl required [formControl]="selectOptFormControl">
+ <mat-option
*ngFor="let option of Object.keys(Optimizer); let optionName of Object.values(Optimizer)"
[value]="option">
{{ optionName }}
- </option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
+ </mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectOptFormControl.hasError('required')">
Obavezno polje
</mat-error>
</mat-form-field>
</div>
<div class="row">
- <mat-form-field appearance="fill">
- <mat-label>Learning rate</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option label="--select something --"></option>
- <option value="saab">Saab</option>
- <option value="mercedes">Mercedes</option>
- <option value="audi">Audi</option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
- Obavezno polje
+ <mat-form-field appearance="fill">
+ <mat-label>Funkcija troška</mat-label>
+ <mat-select matNativeControl required [formControl]="selectLFFormControl">
+ <mat-option
+ *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)"
+ [value]="option">
+ {{ optionName }}
+ </mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectLFFormControl.hasError('required')">
+ Obavezno polje
</mat-error>
</mat-form-field>
</div>
</div>
<div class="col-sm">
<div class="row">
- <mat-form-field appearance="fill">
- <mat-label>Broj epoha</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option label="--select something --"></option>
- <option value="saab">Saab</option>
- <option value="mercedes">Mercedes</option>
- <option value="audi">Audi</option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
- Obavezno polje
- </mat-error>
- </mat-form-field>
+
+ <mat-form-field appearance="fill">
+ <mat-label>Funkcija aktivacije izlaznog sloja</mat-label>
+ <mat-select matNativeControl required [formControl]="selectAFFormControl" name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction">
+ <mat-option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectAFFormControl.hasError('required')">
+ Obavezno polje
+ </mat-error>
+ </mat-form-field>
+
</div>
<div class="row">
- <mat-form-field appearance="fill">
- <mat-label>Broj uzoraka po iteraciji</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option label="--select something --"></option>
- <option value="saab">Saab</option>
- <option value="mercedes">Mercedes</option>
- <option value="audi">Audi</option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
- Obavezno polje
+ <mat-form-field appearance="fill">
+ <mat-label>Funkcija troška</mat-label>
+ <mat-select matNativeControl required [formControl]="selectLFFormControl">
+ <mat-option
+ *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)"
+ [value]="option">
+ {{ optionName }}
+ </mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectLFFormControl.hasError('required')">
+ Obavezno polje
</mat-error>
</mat-form-field>
</div>
</div>
- <div class="col-sm">
+ <div class="col">
+ <div class="row">
+ <div class="col-7">Broj Epoha</div>
+ <mat-icon (click)="addEpoch()">add_circle</mat-icon>
+ <div class="col-1">{{newModel.epochs}}</div>
+ <mat-icon (click)="removeEpoch()">remove_circle</mat-icon>
+ </div>
+ <br>
+ <br>
<div class="row">
+ <div class="col-7">Broj Uzoraka Po Iteraciji</div>
+ <mat-icon (click)="addBatch()">add_circle</mat-icon>
+ <div class="col-1">{{newModel.batchSize}}</div>
+ <mat-icon (click)="removeBatch()">remove_circle</mat-icon>
+ </div>
+ </div>
+ </div><!--kraj unosa parametara-->
+ <hr>
+ <div class="m-5">
+ <app-graph [model]="newModel" [inputCols]="newModel.inputColNum"></app-graph>
+ <div class="row" id="rowhn">
+ <div class="col-3"></div>
+ <div class="col-2">Broj Skrivenih Slojeva</div>
+ <div class="col-1"><mat-icon (click)="addLayer()" (ngModelChange)="updateGraph()">add_circle</mat-icon></div>
+ <div class="col-1">{{newModel.hiddenLayers}}</div>
+ <div class="col-1"><mat-icon (click)="removeLayer()" (ngModelChange)="updateGraph()">remove_circle</mat-icon></div>
+ </div>
+ </div>
+ <hr>
+ <div class="row" style="max-width:60rem ;">
+
+ <div class="col text-center" *ngFor="let item of numSequence(newModel.hiddenLayers)" >
+ {{item}}
+ <div class="neuron">
+ <div style="text-align: center;">
+ <label >Skriveni sloj</label>
+ </div>
+ <div class="row" style="margin-bottom: -10px;">
<mat-form-field appearance="fill">
- <mat-label>Funkcija aktivacije izlaznog sloja</mat-label>
- <select matNativeControl required [formControl]="selectFormControl" name="outputLayerActivationFunction" [(ngModel)]="newModel.outputLayerActivationFunction">
- <option
- *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
- [value]="option">
- {{ optionName }}
- </option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
+ <mat-label>Aktivaciona funkcija</mat-label>
+ <mat-select matNativeControl required [formControl]="selectActivationFormControl">
+ <mat-option value="saab">Relu</mat-option>
+ <mat-option value="mercedes">Sigmoid</mat-option>
+ <mat-option value="audi">Softmax</mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectActivationFormControl.hasError('required')">
Obavezno polje
</mat-error>
</mat-form-field>
+ </div>
+ <div class="row" >
+ <div class="col-6" style="font-size: 13px;" >Broj čvorova</div>
+ <mat-icon (click)="addNeuron()">add_circle</mat-icon>
+ <div class="col-1">{{newModel.hiddenLayerNeurons}}</div>
+ <mat-icon (click)="removeNeuron()">remove_circle</mat-icon>
+
</div>
- <div class="row">
- <mat-form-field appearance="fill">
- <mat-label>Funkcija troška</mat-label>
- <select matNativeControl required [formControl]="selectFormControl">
- <option
- *ngFor="let option of Object.keys(lossFunction); let optionName of Object.values(lossFunction)"
- [value]="option">
- {{ optionName }}
- </option>
- </select>
- <mat-error *ngIf="selectFormControl.hasError('required')">
- Obavezno polje
+ <div class='row' style="margin-bottom: -7px;">
+ <mat-form-field appearance="fill">
+ <mat-label>Regularizacija</mat-label>
+ <mat-select matNativeControl required [formControl]="selectRegularisationFormControl">
+ <mat-option value="l1">L1</mat-option>
+ <mat-option value="l2">L2</mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectRegularisationFormControl.hasError('required')">
+ Obavezno polje
+ </mat-error>
+ </mat-form-field>
+ </div>
+ <div class="row" style="margin-bottom: -7px;">
+ <mat-form-field appearance="fill">
+ <mat-label>Stopa regularizacije</mat-label>
+ <mat-select matNativeControl required [formControl]="selectRRateFormControl">
+ <mat-option value="saab">0.001</mat-option>
+ <mat-option value="mercedes">0.01</mat-option>
+ <mat-option value="audi">0.1</mat-option>
+ </mat-select>
+ <mat-error *ngIf="selectRRateFormControl.hasError('required')">
+ Obavezno polje
</mat-error>
</mat-form-field>
+ </div>
</div>
+ <br>
</div>
- </div><!--kraj unosa parametara-->
-
- <div class="col-1">
- <input type="number" min="1" class="form-control" name="hiddenLayerNeurons" [(ngModel)]="newModel.hiddenLayerNeurons" (ngModelChange)="updateGraph()">
- </div>
- <div class="m-5">
- <app-graph [model]="newModel" [inputCols]="4"></app-graph>
- <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])" (ngModelChange)="updateGraph()">
- </div>
- </div>
-
+
</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/form-model/form-model.component.ts b/frontend/src/app/_elements/form-model/form-model.component.ts
index 6f795161..b1d0a2a9 100644
--- a/frontend/src/app/_elements/form-model/form-model.component.ts
+++ b/frontend/src/app/_elements/form-model/form-model.component.ts
@@ -4,6 +4,8 @@ import Shared from 'src/app/Shared';
import Experiment from 'src/app/_data/Experiment';
import Model, { ActivationFunction, LossFunction, LossFunctionBinaryClassification, LossFunctionMultiClassification, LossFunctionRegression, Metrics, MetricsBinaryClassification, MetricsMultiClassification, MetricsRegression, NullValueOptions, Optimizer, ProblemType } from 'src/app/_data/Model';
import { GraphComponent } from '../graph/graph.component';
+import {FormGroupDirective, NgForm} from '@angular/forms';
+import {ErrorStateMatcher} from '@angular/material/core';
@Component({
selector: 'app-form-model',
templateUrl: './form-model.component.html',
@@ -14,19 +16,25 @@ export class FormModelComponent implements OnInit {
@Input() forExperiment?: Experiment;
@Output() selectedModelChangeEvent = new EventEmitter<Model>();
- constructor() { }
+ constructor() {
+ this.newModel.epochs=1;
+ this.newModel.batchSize=1;
+}
ngOnInit(): void {
}
- animalControl = new FormControl('', Validators.required);
selectFormControl = new FormControl('', Validators.required);
- /*animals: Animal[] = [
- {name: 'Dog', sound: 'Woof!'},
- {name: 'Cat', sound: 'Meow!'},
- {name: 'Cow', sound: 'Moo!'},
- {name: 'Fox', sound: 'Wa-pa-pa-pa-pa-pa-pow!'},
- ];
- */
+ nameFormControl = new FormControl('', [Validators.required, Validators.email]);
+ selectTypeFormControl=new FormControl('', Validators.required);
+ selectOptFormControl=new FormControl('', Validators.required);
+ selectLFFormControl=new FormControl('', Validators.required);
+ selectLRFormControl=new FormControl('', Validators.required);
+ selectEpochFormControl=new FormControl('', Validators.required);
+ selectAFFormControl=new FormControl('', Validators.required);
+ selectBSFormControl=new FormControl('', Validators.required);
+ selectActivationFormControl = new FormControl('', Validators.required);
+ selectRegularisationFormControl = new FormControl('', Validators.required);
+ selectRRateFormControl = new FormControl('', Validators.required);
newModel: Model = new Model();
myModels?: Model[];
selectedModel?: Model;
@@ -45,10 +53,115 @@ export class FormModelComponent implements OnInit {
lossFunction: any = LossFunction;
showMyModels: boolean = true;
+
+ hiddenLayers=[];
+
+
- batchSizePower: number = 2;
updateGraph() {
this.graph.update();
}
+ removeLayer(){
+ if(this.newModel.hiddenLayers>1)
+ {
+ this.newModel.hiddenLayers-=1;
+ this.updateGraph();
+ }
+ else
+ {
+ this.newModel.hiddenLayers=this.newModel.hiddenLayers;
+ }
+
+ }
+ addLayer(){
+ if(this.newModel.hiddenLayers<12)
+ {
+ this.newModel.hiddenLayers+=1;
+ this.updateGraph();
+ }
+ else
+ {
+ this.newModel.hiddenLayers=this.newModel.hiddenLayers;
+
+ }
+ }
+ removeBatch(){
+ if(this.newModel.batchSize>1)
+ {
+ this.newModel.batchSize=this.newModel.batchSize/2;
+ }
+ else
+ {
+ this.newModel.batchSize=this.newModel.batchSize;
+ }
+
+ }
+ addBatch(){
+ if(this.newModel.batchSize<600)
+ {
+ this.newModel.batchSize=this.newModel.batchSize*2;
+ }
+ else
+ {
+ this.newModel.batchSize=this.newModel.batchSize;
+
+ }
+ }
+ removeEpoch(){
+ if(this.newModel.epochs>1)
+ {
+ this.newModel.epochs=this.newModel.epochs-1;
+ }
+ else
+ {
+ this.newModel.epochs=this.newModel.epochs;
+ }
+
+ }
+ addEpoch(){
+ if(this.newModel.epochs<100)
+ {
+ this.newModel.epochs=this.newModel.epochs+1;
+ }
+ else
+ {
+ this.newModel.epochs=this.newModel.epochs;
+
+ }
+ }
+ /*
+ setNeurons()
+ {
+ for(let i=0;i<this.newModel.hiddenLayers;i++){
+ this.newModel.hiddenLayerNeurons[i]=1;
+ }
+ }*/
+ numSequence(n: number): Array<number> {
+ return Array(n);
+ }
+ removeNeuron(){
+ if(this.newModel.hiddenLayerNeurons>1)
+ {
+ this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons-1;
+ this.updateGraph();
+ }
+ else
+ {
+ this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons;
+ }
+
+ }
+ addNeuron(){
+ if(this.newModel.hiddenLayerNeurons<100)
+ {
+ this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons+1;
+ this.updateGraph();
+ }
+ else
+ {
+ this.newModel.hiddenLayerNeurons=this.newModel.hiddenLayerNeurons;
+
+ }
+ }
}
diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html
index 5390136d..09d83bd1 100644
--- a/frontend/src/app/_elements/navbar/navbar.component.html
+++ b/frontend/src/app/_elements/navbar/navbar.component.html
@@ -1,4 +1,4 @@
-<header class="sticky-top p-3 bg-dark text-white">
+<header class="bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a routerLink="" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
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 34e412ef..2fde8e7f 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.css
+++ b/frontend/src/app/_pages/experiment/experiment.component.css
@@ -1,37 +1,49 @@
-ul{
+ul {
list-style: none;
}
-.navmenu{
- position: absolute;
- background-color: var(--ns-bg-dark-50);
- height: 90%;
- width: 250px;
+
+.holder {
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
}
-.navmenuwrapper{
- position: relative;
- top:40%;
- transform: translateY(-50%);
+
+.sidenav {
+ width: 250px;
+ background-color: var(--ns-bg-dark-50);
}
+@media only screen and (max-width: 400px) {
+ .sidenav {
+ width: 100%;
+ background-color: var(--ns-bg-dark-100);
+ }
+ .holder {
+ flex-direction: column;
+ }
+}
-mat-stepper{
+mat-stepper {
background-color: transparent;
}
-::ng-deep .mat-step-header .mat-step-icon .mat-step-content{
- background-color: white;
- color:var(--ns-primary);
- }
-::ng-deep .mat-step-header .mat-step-icon{
- color:white;
-}
-::ng-deep .mat-step-header .mat-step-icon-state-done{
- background: var(--ns-primary);
- color:var(--ns-primary)
+.label {
+ color: white;
}
-::ng-deep .mat-step-header .mat-step-icon-state-done .label{
- color:var(--ns-primary)
+
+.steps-container {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ overflow-y: auto;
}
-.label{
- color: white;
+
+.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 e0746d4a..c988a50a 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.html
+++ b/frontend/src/app/_pages/experiment/experiment.component.html
@@ -1,37 +1,35 @@
-<app-folder></app-folder>
-<div class="wrapper">
-
- <nav class="navmenu">
- <div class="navmenuwrapper text-offwhite">
- <mat-stepper orientation="vertical" (selectionChange)="test($event)">
+<div class="container-fluid p-0 text-offwhite holder" style="height: calc(100vh - 64px);">
+ <div class="d-flex flex-colum align-items-center sidenav">
+ <mat-stepper orientation="vertical" (selectionChange)="changePage($event)">
<mat-step>
- <ng-template matStepLabel><span class="label">Izvor podataka</span></ng-template>
- <ng-template matStepContent>
- <p>Izaberite vas izvor podataka</p>
- </ng-template>
+ <!--editable="false"-->
+ <ng-template matStepLabel><span class="label">Izvor podataka</span></ng-template>
+ <ng-template matStepContent>
+ <p>Izaberite vas izvor podataka</p>
+ </ng-template>
</mat-step>
<mat-step>
- <ng-template matStepLabel> <span class="label">Odabir kolona</span></ng-template>
- <ng-template matStepContent>
- <p>Pripremite podatke i izaberite izlazne kolone</p>
- </ng-template>
+ <ng-template matStepLabel> <span class="label">Odabir kolona</span></ng-template>
+ <ng-template matStepContent>
+ <p>Pripremite podatke i izaberite izlazne kolone</p>
+ </ng-template>
</mat-step>
- <mat-step >
- <ng-template matStepLabel><span class="label">Treniranje</span></ng-template>
- <p>Odaberite parametre i trenirajte model</p>
+ <mat-step>
+ <ng-template matStepLabel><span class="label">Treniranje</span></ng-template>
+ <p>Odaberite parametre i trenirajte model</p>
</mat-step>
- </mat-stepper>
+ </mat-stepper>
+ </div>
+ <div #stepsContainer class="steps-container">
+ <div #steps id="step_1" class="step-content">
+ <app-folder (okPressed)="goToPage(1)"></app-folder>
+ </div>
+ <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 #steps id="step_3" class="step-content">
+
+ <app-form-model></app-form-model>
</div>
-
-
-
- </nav>
-
-
-
-
-
-</div>
-
-
-
+ </div>
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts
index f06a7c48..ad0f1df2 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.ts
+++ b/frontend/src/app/_pages/experiment/experiment.component.ts
@@ -1,19 +1,89 @@
-import { Component, OnInit } 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 implements OnInit {
+export class ExperimentComponent implements AfterViewInit {
+
+ @ViewChild(MatStepper) stepper!: MatStepper;
+ @ViewChild('stepsContainer') stepsContainer!: ElementRef;
+ @ViewChildren('steps') steps!: ElementRef[];
+
+ event: number = 0;
constructor() { }
- ngOnInit(): void {
+ stepHeight = this.calcStepHeight();
+
+ calcStepHeight() {
+ return window.innerHeight - 64;
+ }
+
+ ngAfterViewInit(): void {
+ window.addEventListener('resize', () => {
+ this.updatePageHeight();
+ })
+ this.updatePageHeight();
+
+ setInterval(() => {
+ this.updatePageIfScrolled();
+ }, 100);
+
+ 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.updatePage(<number>event.selectedIndex)
}
- test(event:StepperSelectionEvent){
- console.log(event);
+ goToPage(pageNum: number) {
+ this.stepper.selectedIndex = pageNum;
+ this.updatePage(pageNum);
}
+ scrollTimeout: any;
+
+ updatePage(pageNum: number) {
+ this.scrolling = true;
+ this.event = pageNum;
+ let scrollAmount = 0;
+ this.steps.forEach((step, index) => {
+ if (index == pageNum) {
+ scrollAmount = step.nativeElement.offsetTop;
+ }
+ })
+ clearTimeout(this.scrollTimeout);
+ this.scrollTimeout = setTimeout(() => {
+ this.scrolling = false;
+ }, 800);
+ this.stepsContainer.nativeElement.scroll({
+ top: scrollAmount,
+ behavior: 'smooth' //auto, smooth, initial, inherit
+ });
+ }
+
+ scrolling: boolean = false;
+
}
diff --git a/frontend/src/app/_pages/home/home.component.html b/frontend/src/app/_pages/home/home.component.html
index f73e7571..e682d8dd 100644
--- a/frontend/src/app/_pages/home/home.component.html
+++ b/frontend/src/app/_pages/home/home.component.html
@@ -16,4 +16,5 @@
</div>
+
</div> \ No newline at end of file
diff --git a/frontend/src/app/_pages/test/test.component.css b/frontend/src/app/_pages/test/test.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.css
diff --git a/frontend/src/app/_pages/test/test.component.html b/frontend/src/app/_pages/test/test.component.html
new file mode 100644
index 00000000..625739f8
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.html
@@ -0,0 +1,3 @@
+<app-pie-chart></app-pie-chart>
+<app-doughnut-chart></app-doughnut-chart>
+<app-barchart></app-barchart> \ No newline at end of file
diff --git a/frontend/src/app/_pages/test/test.component.spec.ts b/frontend/src/app/_pages/test/test.component.spec.ts
new file mode 100644
index 00000000..e0f9bcc9
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TestComponent } from './test.component';
+
+describe('TestComponent', () => {
+ let component: TestComponent;
+ let fixture: ComponentFixture<TestComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ TestComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TestComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_pages/test/test.component.ts b/frontend/src/app/_pages/test/test.component.ts
new file mode 100644
index 00000000..b3c0d8cf
--- /dev/null
+++ b/frontend/src/app/_pages/test/test.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-test',
+ templateUrl: './test.component.html',
+ styleUrls: ['./test.component.css']
+})
+export class TestComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit(): void {
+ }
+
+}
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index 30cf2ea8..f5f1ccae 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -8,6 +8,7 @@ import { PlaygroundComponent } from './_pages/playground/playground.component';
import { ExperimentComponent } from './_pages/experiment/experiment.component';
import { ArchiveComponent } from './_pages/archive/archive.component';
import { ColumnTableComponent } from './_elements/column-table/column-table.component';
+import { TestComponent } from './_pages/test/test.component';
const routes: Routes = [
{ path: '', component: HomeComponent, data: { title: 'Početna strana' } },
@@ -15,7 +16,8 @@ const routes: Routes = [
{ path: 'archive', component: ArchiveComponent, data: { title: 'Arhiva' } },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuardService], data: { title: 'Profil' } },
{ path: 'playground', component: PlaygroundComponent, data: { title: 'Zabava' } },
- { path: 'sonja', component: ColumnTableComponent }
+ { path: 'sonja', component: ColumnTableComponent },
+ { path: 'test', component: TestComponent, data: { title: 'Test' } }
];
@NgModule({
diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html
index 8c3f4e9e..d15793e7 100644
--- a/frontend/src/app/app.component.html
+++ b/frontend/src/app/app.component.html
@@ -6,10 +6,8 @@
<app-reactive-background [speed]="0.001" [scrollSpeed]="1" [minDistance]="0.14" [maxSize]="5" [cursorDistance]="0.22" lineColor="#00a8e8" pointColor="rgba(0, 188, 252, 1)" cursorLineColor="#00a8e8" [numPoints]="100">
</app-reactive-background>
<app-navbar></app-navbar>
-<a class="bg-controls" routerLink="playground">
+<a class="bg-controls" style="z-index: 1000;" routerLink="playground">
<mat-icon color="accent">settings_suggest</mat-icon>
</a>
-<div class="h-100">
- <router-outlet></router-outlet>
-</div>
+<router-outlet></router-outlet>
<app-notifications></app-notifications> \ No newline at end of file
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index 4a0d85c8..f9bc2726 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { AfterViewInit, Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map } from 'rxjs';
@@ -11,10 +11,12 @@ import Shared from './Shared';
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
-export class AppComponent implements OnInit {
+export class AppComponent implements OnInit, AfterViewInit {
constructor(private router: Router, private titleService: Title, private authService: AuthService, private signalRService: SignalRService, private http: HttpClient) {
}
+ ngAfterViewInit(): void {
+ }
ngOnInit() {
this.router.events
@@ -42,17 +44,5 @@ export class AppComponent implements OnInit {
}
this.signalRService.startConnection();
//this.startHttpRequest();
-
-
-
-
- }
- private startHttpRequest = () => {
- this.http.get('http://localhost:5283/chatHub')
- .subscribe(res => {
- console.log(res);
- })
}
-
-
}
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 70e78394..c46381d5 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -45,6 +45,8 @@ import { FormDatasetComponent } from './_elements/form-dataset/form-dataset.comp
import { FormModelComponent } from './_elements/form-model/form-model.component';
import { ColumnTableComponent } from './_elements/column-table/column-table.component';
import { FolderComponent } from './_elements/folder/folder.component';
+import { TestComponent } from './_pages/test/test.component';
+import { DoughnutChartComponent } from './_elements/_charts/doughnut-chart/doughnut-chart.component';
export function initializeApp(appConfig: Configuration) {
return () => appConfig.load();
@@ -78,7 +80,9 @@ export function initializeApp(appConfig: Configuration) {
BoxPlotComponent,
FolderComponent,
EncodingDialogComponent,
- MissingvaluesDialogComponent
+ MissingvaluesDialogComponent,
+ TestComponent,
+ DoughnutChartComponent,
],
imports: [
BrowserModule,
diff --git a/frontend/src/custom-theme.scss b/frontend/src/custom-theme.scss
index a6538c37..8f716240 100644
--- a/frontend/src/custom-theme.scss
+++ b/frontend/src/custom-theme.scss
@@ -1,35 +1,250 @@
+/**
+* Generated theme by Material Theme Generator
+* https://materialtheme.arcsine.dev
+* Fork at: https://materialtheme.arcsine.dev/?c=YHBhbGV0dGU$YHByaW1hcnk$YF48IzAwNjNhYiIsIj9lcjwjYjNkMGU2IiwiO2VyPCMwMDQ3OTF$LCIlPmBePCMwMGE4ZTgiLCI~ZXI8I2IzZTVmOCIsIjtlcjwjMDA4ZGRlfiwid2Fybj5gXjwjZjliN2I3IiwiP2VyPCNmZGU5ZTkiLCI7ZXI8I2Y2OWY5Zn4sIj9UZXh0PCMwMDQxNjUiLCI~PTwjZGZkN2Q3IiwiO1RleHQ8I2RmZDdkNyIsIjs9PCMwMDQxNjV$LCJmb250cz5bYEA8KC00fixgQDwoLTN$LGBAPCgtMn4sYEA8KC0xfixgQDxoZWFkbGluZX4sYEA8dGl0bGV$LGBAPHN1YiktMn4sYEA8c3ViKS0xfixgQDxib2R5LTJ$LGBAPGJvZHktMX4sYEA8YnV0dG9ufixgQDxjYXB0aW9ufixgQDxpbnB1dCIsInNpemU$bnVsbH1dLCJpY29uczxGaWxsZWQiLCI~bmVzcz5mYWxzZSwidmVyc2lvbj4xM30=
+*/
-// Custom Theming for Angular Material
-// For more information: https://material.angular.io/guide/theming
@use '@angular/material' as mat;
-// Plus imports for other components in your app.
-
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
-// Be sure that you only ever include this mixin once!
-@include mat.core();
+// Fonts
+@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
+@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap');
+$fontConfig: ( display-4: mat.define-typography-level(112px, 112px, 300, 'Roboto', -0.0134em),
+display-3: mat.define-typography-level(56px, 56px, 400, 'Roboto', -0.0089em),
+display-2: mat.define-typography-level(45px, 48px, 400, 'Roboto', 0.0000em),
+display-1: mat.define-typography-level(34px, 40px, 400, 'Roboto', 0.0074em),
+headline: mat.define-typography-level(24px, 32px, 400, 'Roboto', 0.0000em),
+title: mat.define-typography-level(20px, 32px, 500, 'Roboto', 0.0075em),
+subheading-2: mat.define-typography-level(16px, 28px, 400, 'Roboto', 0.0094em),
+subheading-1: mat.define-typography-level(15px, 24px, 500, 'Roboto', 0.0067em),
+body-2: mat.define-typography-level(14px, 24px, 500, 'Roboto', 0.0179em),
+body-1: mat.define-typography-level(14px, 20px, 400, 'Roboto', 0.0179em),
+button: mat.define-typography-level(14px, 14px, 500, 'Roboto', 0.0893em),
+caption: mat.define-typography-level(12px, 20px, 400, 'Roboto', 0.0333em),
+input: mat.define-typography-level(inherit, 1.125, 400, 'Roboto', 1.5px));
+// Foreground Elements
+// Light Theme Text
+$dark-text: #004165;
+$dark-primary-text: rgba($dark-text,
+0.87);
+$dark-accent-text: rgba($dark-primary-text,
+0.54);
+$dark-disabled-text: rgba($dark-primary-text,
+0.38);
+$dark-dividers: rgba($dark-primary-text,
+0.12);
+$dark-focused: rgba($dark-primary-text,
+0.12);
+$mat-light-theme-foreground: ( base : black,
+divider : $dark-dividers,
+dividers : $dark-dividers,
+disabled : $dark-disabled-text,
+disabled-button : rgba($dark-text, 0.26),
+disabled-text : $dark-disabled-text,
+elevation : black,
+secondary-text : $dark-accent-text,
+hint-text : $dark-disabled-text,
+accent-text : $dark-accent-text,
+icon : $dark-accent-text,
+icons : $dark-accent-text,
+text : $dark-primary-text,
+slider-min : $dark-primary-text,
+slider-off : rgba($dark-text, 0.26),
+slider-off-active: $dark-disabled-text,
+);
+// Dark Theme text
+$light-text: #dfd7d7;
+$light-primary-text: $light-text;
+$light-accent-text: rgba($light-primary-text,
+0.7);
+$light-disabled-text: rgba($light-primary-text,
+0.5);
+$light-dividers: rgba($light-primary-text,
+0.12);
+$light-focused: rgba($light-primary-text,
+0.12);
+$mat-dark-theme-foreground: ( base : $light-text,
+divider : $light-dividers,
+dividers : $light-dividers,
+disabled : $light-disabled-text,
+disabled-button : rgba($light-text, 0.3),
+disabled-text : $light-disabled-text,
+elevation : black,
+hint-text : $light-disabled-text,
+secondary-text : $light-accent-text,
+accent-text : $light-accent-text,
+icon : $light-text,
+icons : $light-text,
+text : $light-text,
+slider-min : $light-text,
+slider-off : rgba($light-text, 0.3),
+slider-off-active: rgba($light-text, 0.3),
+);
+// Background config
+// Light bg
+$light-background : #dfd7d7;
+$light-bg-darker-5 : darken($light-background,
+5%);
+$light-bg-darker-10 : darken($light-background,
+10%);
+$light-bg-darker-20 : darken($light-background,
+20%);
+$light-bg-darker-30 : darken($light-background,
+30%);
+$light-bg-lighter-5 : lighten($light-background,
+5%);
+$dark-bg-tooltip : lighten(#004165,
+20%);
+$dark-bg-alpha-4 : rgba(#004165,
+0.04);
+$dark-bg-alpha-12 : rgba(#004165,
+0.12);
+$mat-light-theme-background: ( background : $light-background,
+status-bar : $light-bg-darker-20,
+app-bar : $light-bg-darker-5,
+hover : $dark-bg-alpha-4,
+card : $light-bg-lighter-5,
+dialog : $light-bg-lighter-5,
+tooltip : $dark-bg-tooltip,
+disabled-button : $dark-bg-alpha-12,
+raised-button : $light-bg-lighter-5,
+focused-button : $dark-focused,
+selected-button : $light-bg-darker-20,
+selected-disabled-button: $light-bg-darker-30,
+disabled-button-toggle : $light-bg-darker-10,
+unselected-chip : $light-bg-darker-10,
+disabled-list-option : $light-bg-darker-10,
+);
+// Dark bg
+$dark-background : #004165;
+$dark-bg-lighter-5 : lighten($dark-background,
+5%);
+$dark-bg-lighter-10 : lighten($dark-background,
+10%);
+$dark-bg-lighter-20 : lighten($dark-background,
+20%);
+$dark-bg-lighter-30 : lighten($dark-background,
+30%);
+$light-bg-alpha-4 : rgba(#dfd7d7,
+0.04);
+$light-bg-alpha-12 : rgba(#dfd7d7,
+0.12);
+// Background palette for dark themes.
+$mat-dark-theme-background: ( background : $dark-background,
+status-bar : $dark-bg-lighter-20,
+app-bar : $dark-bg-lighter-5,
+hover : $light-bg-alpha-4,
+card : $dark-bg-lighter-5,
+dialog : $dark-bg-lighter-5,
+tooltip : $dark-bg-lighter-20,
+disabled-button : $light-bg-alpha-12,
+raised-button : $dark-bg-lighter-5,
+focused-button : $light-focused,
+selected-button : $dark-bg-lighter-20,
+selected-disabled-button: $dark-bg-lighter-30,
+disabled-button-toggle : $dark-bg-lighter-10,
+unselected-chip : $dark-bg-lighter-20,
+disabled-list-option : $dark-bg-lighter-10,
+);
+// Compute font config
+@include mat.core($fontConfig);
+// Theme Config
+body {
+ --primary-color: #0063ab;
+ --primary-lighter-color: #b3d0e6;
+ --primary-darker-color: #004791;
+ --text-primary-color: #{$light-primary-text};
+ --text-primary-lighter-color: #{$dark-primary-text};
+ --text-primary-darker-color: #{$light-primary-text};
+}
+
+$mat-primary: ( main: #0063ab,
+lighter: #b3d0e6,
+darker: #004791,
+200: #0063ab, // For slide toggle,
+contrast: ( main: $light-primary-text, lighter: $dark-primary-text, darker: $light-primary-text, ));
+$theme-primary: mat.define-palette($mat-primary,
+main,
+lighter,
+darker);
+body {
+ --accent-color: #00a8e8;
+ --accent-lighter-color: #b3e5f8;
+ --accent-darker-color: #008dde;
+ --text-accent-color: #{$light-primary-text};
+ --text-accent-lighter-color: #{$dark-primary-text};
+ --text-accent-darker-color: #{$light-primary-text};
+}
-// Define the palettes for your theme using the Material Design palettes available in palette.scss
-// (imported above). For each palette, you can optionally specify a default, lighter, and darker
-// hue. Available color palettes: https://material.io/design/color/
-$frontend-primary: mat.define-palette(mat.$indigo-palette);
-$frontend-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
+$mat-accent: ( main: #00a8e8,
+lighter: #b3e5f8,
+darker: #008dde,
+200: #00a8e8, // For slide toggle,
+contrast: ( main: $light-primary-text, lighter: $dark-primary-text, darker: $light-primary-text, ));
+$theme-accent: mat.define-palette($mat-accent,
+main,
+lighter,
+darker);
+body {
+ --warn-color: #f9b7b7;
+ --warn-lighter-color: #fde9e9;
+ --warn-darker-color: #f69f9f;
+ --text-warn-color: #{$dark-primary-text};
+ --text-warn-lighter-color: #{$dark-primary-text};
+ --text-warn-darker-color: #{$dark-primary-text};
+}
-// The warn palette is optional (defaults to red).
-$frontend-warn: mat.define-palette(mat.$red-palette);
+$mat-warn: ( main: #f9b7b7,
+lighter: #fde9e9,
+darker: #f69f9f,
+200: #f9b7b7, // For slide toggle,
+contrast: ( main: $dark-primary-text, lighter: $dark-primary-text, darker: $dark-primary-text, ));
+$theme-warn: mat.define-palette($mat-warn,
+main,
+lighter,
+darker);
+;
+$theme: ( primary: $theme-primary,
+accent: $theme-accent,
+warn: $theme-warn,
+is-dark: true,
+foreground: $mat-dark-theme-foreground,
+background: $mat-dark-theme-background,
+);
+$altTheme: ( primary: $theme-primary,
+accent: $theme-accent,
+warn: $theme-warn,
+is-dark: false,
+foreground: $mat-light-theme-foreground,
+background: $mat-light-theme-background,
+);
+// Theme Init
+@include mat.all-component-themes($theme);
+.theme-alternate {
+ @include mat.all-component-themes($altTheme);
+}
-// Create the theme object. A theme consists of configurations for individual
-// theming systems such as "color" or "typography".
-$frontend-theme: mat.define-light-theme((
- color: (
- primary: $frontend-primary,
- accent: $frontend-accent,
- warn: $frontend-warn,
- )
-));
+// Specific component overrides, pieces that are not in line with the general theming
+// Handle buttons appropriately, with respect to line-height
+.mat-raised-button,
+.mat-stroked-button,
+.mat-flat-button {
+ padding: 0 1.15em;
+ margin: 0 .65em;
+ min-width: 3em;
+ line-height: 36.4px
+}
-// Include theme styles for core and each component used in your app.
-// Alternatively, you can import and @include the theme mixins for each component
-// that you are using.
-@include mat.all-component-themes($frontend-theme);
+.mat-standard-chip {
+ padding: .5em .85em;
+ min-height: 2.5em;
+}
+.material-icons {
+ font-size: 24px;
+ font-family: 'Material Icons', 'Material Icons';
+ .mat-badge-content {
+ font-family: 'Roboto';
+ }
+} \ No newline at end of file
diff --git a/frontend/src/styles/helper.css b/frontend/src/styles/helper.css
index 9c520ac3..875b94f1 100644
--- a/frontend/src/styles/helper.css
+++ b/frontend/src/styles/helper.css
@@ -51,4 +51,27 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+}
+
+.btn-clear {
+ border: unset;
+ background-color: unset;
+ outline: unset;
+ position: relative;
+}
+
+.input-icon {
+ color: var(--offwhite);
+ transform: translateY(25%);
+}
+
+.input-icon:hover {
+ color: var(--ns-primary);
+}
+
+.f-row {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
} \ No newline at end of file
diff --git a/frontend/src/styles/layout.css b/frontend/src/styles/layout.css
index e24da375..33f4cf2b 100644
--- a/frontend/src/styles/layout.css
+++ b/frontend/src/styles/layout.css
@@ -1,5 +1,10 @@
/*Mora da se ispravi za media kada je ekran premali pa se poredjaju u kolonu*/
+html,
+body {
+ height: 100%;
+}
+
.align-items-view>*:first-child {
transform: perspective(100em) rotateY(25deg) translateZ(1em);
}
diff --git a/frontend/src/styles/theme.css b/frontend/src/styles/theme.css
index d0ccc935..f2e84e8b 100644
--- a/frontend/src/styles/theme.css
+++ b/frontend/src/styles/theme.css
@@ -35,4 +35,22 @@ a {
.text-offwhite {
color: var(--offwhite) !important;
+}
+
+
+/* Ripple effect */
+
+.bubble {
+ background-position: center;
+ transition: background 0.8s;
+}
+
+.bubble:hover {
+ background: #47a7f5 radial-gradient(circle, transparent 1%, #47a7f5 1%) center/15000%;
+}
+
+.bubble:active {
+ background-color: #6eb9f7;
+ background-size: 100%;
+ transition: background 0s;
} \ No newline at end of file