diff options
Diffstat (limited to 'frontend/src/app/_elements')
19 files changed, 350 insertions, 32 deletions
diff --git a/frontend/src/app/_elements/carousel/carousel.component.css b/frontend/src/app/_elements/carousel/carousel.component.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/frontend/src/app/_elements/carousel/carousel.component.css diff --git a/frontend/src/app/_elements/carousel/carousel.component.html b/frontend/src/app/_elements/carousel/carousel.component.html new file mode 100644 index 00000000..755899a7 --- /dev/null +++ b/frontend/src/app/_elements/carousel/carousel.component.html @@ -0,0 +1,14 @@ +<div class="container"> + <div class="row d-flex align-items-stretch flex-row mx-5 align-items-stretch"> + <div class="col my-1" *ngFor=" let item of items" [ngSwitch]="item.constructor.name"> + <ng-template ngSwitchCase="Dataset"> + <app-item-dataset [dataset]="item"> + </app-item-dataset> + </ng-template> + <ng-template ngSwitchCase="Predictor"> + <app-item-predictor [predictor]="item"> + </app-item-predictor> + </ng-template> + </div> + </div> +</div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/carousel/carousel.component.spec.ts b/frontend/src/app/_elements/carousel/carousel.component.spec.ts new file mode 100644 index 00000000..9196e044 --- /dev/null +++ b/frontend/src/app/_elements/carousel/carousel.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CarouselComponent } from './carousel.component'; + +describe('CarouselComponent', () => { + let component: CarouselComponent; + let fixture: ComponentFixture<CarouselComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CarouselComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CarouselComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/carousel/carousel.component.ts b/frontend/src/app/_elements/carousel/carousel.component.ts new file mode 100644 index 00000000..ed4fa4a5 --- /dev/null +++ b/frontend/src/app/_elements/carousel/carousel.component.ts @@ -0,0 +1,17 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-carousel', + templateUrl: './carousel.component.html', + styleUrls: ['./carousel.component.css'] +}) +export class CarouselComponent { + + @Input() items: any[] = []; + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.css b/frontend/src/app/_elements/dataset-load/dataset-load.component.css index e69de29b..05819702 100644 --- a/frontend/src/app/_elements/dataset-load/dataset-load.component.css +++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.css @@ -0,0 +1,6 @@ +#divInputs { + margin-left: 20px; +} +#divOutputs { + margin-left: 20px; +}
\ No newline at end of file diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.html b/frontend/src/app/_elements/dataset-load/dataset-load.component.html index c89add43..fcec6ec3 100644 --- a/frontend/src/app/_elements/dataset-load/dataset-load.component.html +++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.html @@ -1,38 +1,57 @@ <div> - <input style="display: inline-block; width:350px;" list=delimiterOptions - placeholder="Izaberite ili ukucajte delimiter za .csv fajl" class="form-control" [(ngModel)]="delimiter" - (input)="update()"> - <datalist id=delimiterOptions> - <option *ngFor="let option of delimiterOptions">{{option}}</option> - </datalist> - - <label for="checkboxHeader">Da li .csv ima header?</label> - <input (input)="update()" [(ngModel)]="hasHeader" type="checkbox" value="" id="checkboxHeader" checked> - <br><br> + <div class="row mb-4"> + <div class="col-2"> + </div> + <div class="col-3"> + <label for="name" class="col-form-label">Naziv dataseta:</label> + <input type="text" class="form-control mb-3" name="name" placeholder="Naziv..." + [(ngModel)]="dataset.name"> + <label for="desc" class="col-sm-2 col-form-label">Opis:</label> + <div> + <textarea class="form-control" name="desc" rows="3" [(ngModel)]="dataset.description"></textarea> + </div> + </div> + <div class="col-1"> + </div> + <div class="col-4 mt-4"> + <input list=delimiterOptions + placeholder="Izaberite ili ukucajte delimiter za .csv fajl" class="form-control mt-2" [(ngModel)]="delimiter" + (input)="update()"> + <datalist id=delimiterOptions> + <option *ngFor="let option of delimiterOptions">{{option}}</option> + </datalist> - <input id="fileInput" class="form-control mb-5" type="file" class="upload" (change)="changeListener($event)" accept=".csv"> + <label for="type" class="form-check-label my-5">Da li .csv ima header? + <input class="mx-3 form-check-input" type="checkbox" (input)="update()" [(ngModel)]="hasHeader" type="checkbox" value="" id="checkboxHeader" checked> + </label> + <br> + <input id="fileInput" class="form-control" type="file" class="upload" (change)="changeListener($event)" accept=".csv"> + </div> + </div> - <table *ngIf="csvRecords.length > 0 && hasHeader" class="table table-bordered table-light mt-5"> - <thead> - <tr> - <th *ngFor="let item of csvRecords[0]; let i = index">{{item}}</th> - </tr> - </thead> - <tbody> - <tr *ngFor="let row of csvRecords | slice:1:11"> - <td *ngFor="let col of row">{{col}}</td> - </tr> - </tbody> - </table> + <div class="table-responsive"> + <table *ngIf="csvRecords.length > 0 && hasHeader" class="table table-bordered table-light mt-4"> + <thead> + <tr> + <th *ngFor="let item of csvRecords[0]; let i = index">{{item}}</th> + </tr> + </thead> + <tbody> + <tr *ngFor="let row of csvRecords | slice:1:11"> + <td *ngFor="let col of row">{{col}}</td> + </tr> + </tbody> + </table> - <table *ngIf="csvRecords.length > 0 && !hasHeader" class="table table-bordered table-light mt-5"> - <tbody> - <tr *ngFor="let row of csvRecords | slice:0:10"> - <td *ngFor="let col of row">{{col}}</td> - </tr> - </tbody> - </table> + <table *ngIf="csvRecords.length > 0 && !hasHeader" class="table table-bordered table-light mt-4"> + <tbody> + <tr *ngFor="let row of csvRecords | slice:0:10"> + <td *ngFor="let col of row">{{col}}</td> + </tr> + </tbody> + </table> + </div> <div *ngIf="csvRecords.length > 0" id="info"> . . . <br> 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 843a5709..8465c3d6 100644 --- a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts +++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts @@ -1,5 +1,6 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Output, ViewChild } from '@angular/core'; import { NgxCsvParser, NgxCSVParserError } from 'ngx-csv-parser'; +import Dataset from 'src/app/_data/Dataset'; @Component({ selector: 'app-dataset-load', @@ -8,6 +9,8 @@ import { NgxCsvParser, NgxCSVParserError } from 'ngx-csv-parser'; }) export class DatasetLoadComponent { + @Output() loaded = new EventEmitter<string>(); + delimiter: string = ""; delimiterOptions: Array<string> = [",", ";", "\t", "razmak", "|"]; //podrazumevano "," @@ -20,7 +23,10 @@ export class DatasetLoadComponent { rowsNumber: number = 0; colsNumber: number = 0; + dataset: Dataset; + constructor(private ngxCsvParser: NgxCsvParser) { + this.dataset = new Dataset(); } @ViewChild('fileImportInput', { static: false }) fileImportInput: any; @@ -38,7 +44,7 @@ export class DatasetLoadComponent { this.ngxCsvParser.parse(this.files[0], { header: false, delimiter: (this.delimiter == "razmak") ? " " : (this.delimiter == "") ? "," : this.delimiter}) .pipe().subscribe((result) => { - //console.log('Result', result); + console.log('Result', result); if (result.constructor === Array) { this.csvRecords = result; if (this.hasHeader) @@ -46,9 +52,14 @@ export class DatasetLoadComponent { else this.rowsNumber = this.csvRecords.length; this.colsNumber = this.csvRecords[0].length; + + this.dataset.header = this.csvRecords[0]; + + this.loaded.emit("loaded"); } }, (error: NgxCSVParserError) => { console.log('Error', error); }); } + } diff --git a/frontend/src/app/_elements/item-dataset/item-dataset.component.css b/frontend/src/app/_elements/item-dataset/item-dataset.component.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/frontend/src/app/_elements/item-dataset/item-dataset.component.css diff --git a/frontend/src/app/_elements/item-dataset/item-dataset.component.html b/frontend/src/app/_elements/item-dataset/item-dataset.component.html new file mode 100644 index 00000000..cf39a125 --- /dev/null +++ b/frontend/src/app/_elements/item-dataset/item-dataset.component.html @@ -0,0 +1,15 @@ +<div class="card" style="min-width: 12rem;"> + <div class="card-header"> + {{dataset.name}} + </div> + <div class="card-body"> + <p class="card-text"> + {{dataset.description}} + </p> + <table class="table table-bordered table-sm"> + <thead> + <th scope="col" *ngFor="let column of dataset.header">{{column}}</th> + </thead> + </table> + </div> +</div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/item-dataset/item-dataset.component.spec.ts b/frontend/src/app/_elements/item-dataset/item-dataset.component.spec.ts new file mode 100644 index 00000000..603889b2 --- /dev/null +++ b/frontend/src/app/_elements/item-dataset/item-dataset.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ItemDatasetComponent } from './item-dataset.component'; + +describe('ItemDatasetComponent', () => { + let component: ItemDatasetComponent; + let fixture: ComponentFixture<ItemDatasetComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ItemDatasetComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemDatasetComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/item-dataset/item-dataset.component.ts b/frontend/src/app/_elements/item-dataset/item-dataset.component.ts new file mode 100644 index 00000000..e12de34d --- /dev/null +++ b/frontend/src/app/_elements/item-dataset/item-dataset.component.ts @@ -0,0 +1,15 @@ +import { Component, Input, OnInit } from '@angular/core'; +import Dataset from 'src/app/_data/Dataset'; + +@Component({ + selector: 'app-item-dataset', + templateUrl: './item-dataset.component.html', + styleUrls: ['./item-dataset.component.css'] +}) +export class ItemDatasetComponent { + + @Input() dataset: Dataset = new Dataset(); + + constructor() { + } +} diff --git a/frontend/src/app/_elements/item-predictor/item-predictor.component.css b/frontend/src/app/_elements/item-predictor/item-predictor.component.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/frontend/src/app/_elements/item-predictor/item-predictor.component.css diff --git a/frontend/src/app/_elements/item-predictor/item-predictor.component.html b/frontend/src/app/_elements/item-predictor/item-predictor.component.html new file mode 100644 index 00000000..92d747e2 --- /dev/null +++ b/frontend/src/app/_elements/item-predictor/item-predictor.component.html @@ -0,0 +1,24 @@ +<div class="card" style="min-width: 12rem;"> + <div class="card-header"> + {{predictor.name}} + </div> + <div class="card-body"> + <p class="card-text"> + {{predictor.description}} + </p> + <div class="d-flex flex-column align-items-center"> + <table class="table table-bordered table-sm"> + <thead> + <th class="text-center" *ngFor="let column of predictor.inputs">{{column}}</th> + </thead> + </table> + <mat-icon>arrow_downward</mat-icon> + <p> + {{predictor.output}} + </p> + </div> + </div> + <div class="card-footer text-center"> + <a routerLink="predict" mat-raised-button color="primary">Iskoristi</a> + </div> +</div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/item-predictor/item-predictor.component.spec.ts b/frontend/src/app/_elements/item-predictor/item-predictor.component.spec.ts new file mode 100644 index 00000000..b5c2d91c --- /dev/null +++ b/frontend/src/app/_elements/item-predictor/item-predictor.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ItemPredictorComponent } from './item-predictor.component'; + +describe('ItemPredictorComponent', () => { + let component: ItemPredictorComponent; + let fixture: ComponentFixture<ItemPredictorComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ItemPredictorComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemPredictorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/item-predictor/item-predictor.component.ts b/frontend/src/app/_elements/item-predictor/item-predictor.component.ts new file mode 100644 index 00000000..cc782f45 --- /dev/null +++ b/frontend/src/app/_elements/item-predictor/item-predictor.component.ts @@ -0,0 +1,18 @@ +import { Component, Input, OnInit } from '@angular/core'; +import Predictor from 'src/app/_data/Predictor'; + +@Component({ + selector: 'app-item-predictor', + templateUrl: './item-predictor.component.html', + styleUrls: ['./item-predictor.component.css'] +}) +export class ItemPredictorComponent implements OnInit { + + @Input() predictor: Predictor = new Predictor(); + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/_elements/navbar/navbar.component.css b/frontend/src/app/_elements/navbar/navbar.component.css new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/frontend/src/app/_elements/navbar/navbar.component.css diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html new file mode 100644 index 00000000..b9c450af --- /dev/null +++ b/frontend/src/app/_elements/navbar/navbar.component.html @@ -0,0 +1,49 @@ +<header class="sticky-top p-3 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"> + <img src="../../../assets/svg/logo_no_text.svg" class="bi me-2" width="64" height="40"> + </a> + + <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="my-predictors" class="nav-link px-2" + [class]="(currentUrl === '/my-predictors') ? 'text-secondary' : 'text-white'">Predvidi</a></li> + </ul> + + <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="https://github.com/mdo.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);" + data-popper-placement="bottom-end"> + <li><a class="dropdown-item" routerLink="add-model">Nov model...</a></li> + <li><a class="dropdown-item" routerLink="settings">Podešavanja</a></li> + <li><a class="dropdown-item" routerLink="profile">Moj profil</a></li> + <li> + <hr class="dropdown-divider"> + </li> + <li><a class="dropdown-item" routerLink="" (click)="logOut()">Odjavi se</a></li> + </ul> + </div> + <div *ngIf="!shared.loggedIn" class="dropdown text-end"> + <button type="button" mat-raised-button color="primary" class="mx-2" data-bs-toggle="modal" + data-bs-target="#modalForLogin"> + Prijavi se + </button> + <button type="button" mat-raised-button color="primary" data-bs-toggle="modal" + data-bs-target="#modalForRegister"> + Registruj se + </button> + </div> + </div> + </div> +</header> + +<app-login-modal></app-login-modal> +<app-register-modal></app-register-modal>
\ No newline at end of file diff --git a/frontend/src/app/_elements/navbar/navbar.component.spec.ts b/frontend/src/app/_elements/navbar/navbar.component.spec.ts new file mode 100644 index 00000000..f8ccd6f4 --- /dev/null +++ b/frontend/src/app/_elements/navbar/navbar.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NavbarComponent } from './navbar.component'; + +describe('NavbarComponent', () => { + let component: NavbarComponent; + let fixture: ComponentFixture<NavbarComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ NavbarComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NavbarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/_elements/navbar/navbar.component.ts b/frontend/src/app/_elements/navbar/navbar.component.ts new file mode 100644 index 00000000..c16e3e9d --- /dev/null +++ b/frontend/src/app/_elements/navbar/navbar.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { AuthService } from '../../_services/auth.service'; +import shared from 'src/app/Shared'; + +@Component({ + selector: 'app-navbar', + templateUrl: './navbar.component.html', + styleUrls: ['./navbar.component.css'] +}) +export class NavbarComponent implements OnInit { + + currentUrl: string; + shared = shared; + + constructor(public location: Location, private auth: AuthService) { + this.currentUrl = this.location.path(); + this.location.onUrlChange(() => { + this.currentUrl = this.location.path(); + }) + } + + ngOnInit(): void { + this.auth.updateUser(); + } + + logOut() { + this.auth.logOut(); + } +} |