| @@ -14,7 +14,7 @@ import { SelectEntitiesComponent } from './widgets/select-entities/select-entiti | |||||
| import { CheckStatusComponent } from './widgets/check-status/check-status.component'; | import { CheckStatusComponent } from './widgets/check-status/check-status.component'; | ||||
| import { TableComponent } from './widgets/table/table.component'; | import { TableComponent } from './widgets/table/table.component'; | ||||
| import { KeyValueHolderComponent } from './widgets/key-value-holder/key-value-holder.component'; | import { KeyValueHolderComponent } from './widgets/key-value-holder/key-value-holder.component'; | ||||
| import { DownloadButtonComponent } from './widgets/download-button/download-button.component'; | |||||
| import { FileComponent } from './widgets/file/file.component'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| @@ -29,7 +29,7 @@ import { DownloadButtonComponent } from './widgets/download-button/download-butt | |||||
| CheckStatusComponent, | CheckStatusComponent, | ||||
| TableComponent, | TableComponent, | ||||
| KeyValueHolderComponent, | KeyValueHolderComponent, | ||||
| DownloadButtonComponent | |||||
| FileComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| @@ -59,12 +59,13 @@ | |||||
| <div class="table-holder"> | <div class="table-holder"> | ||||
| <app-table | <app-table | ||||
| [headings]="['A', 'B', 'C']" | |||||
| [tableDetails]="[['Val 1', 'Val 2 ', 'Val 3'], ['V1', 'V2', 'V3'], ['A1', 'A2', 'A3']]"></app-table> | |||||
| [headings]="['A', 'B', 'C']" | |||||
| [tableDetails]="[['Val 1', 'Val 2 ', 'Val 3'], ['V1', 'V2', 'V3'], ['A1', 'A2', 'A3']]" | |||||
| ></app-table> | |||||
| </div> | </div> | ||||
| <div class="key-value-holder"> | <div class="key-value-holder"> | ||||
| <app-key-value-holder [keyValues]="keyValues"></app-key-value-holder> | <app-key-value-holder [keyValues]="keyValues"></app-key-value-holder> | ||||
| </div> | </div> | ||||
| <app-download-button [fileDetails]="{name: 'Downladable Table', size: '30MB', extension: 'xls'}"></app-download-button> | |||||
| <app-file [name]="'Downladable Table'" [sizeInBytes]="30000" [extension]="'xls'" [link]="'http://localhost:4200/assets/icons/bell.svg'"></app-file> | |||||
| @@ -1,6 +1,6 @@ | |||||
| <div class="container"> | <div class="container"> | ||||
| <figure class="logo"> | <figure class="logo"> | ||||
| <img src="assets/icons/logo.svg" alt="bizfile plus logo"> | |||||
| <img src="./../../../assets/icons/logo.svg" alt="bizfile plus logo"> | |||||
| </figure> | </figure> | ||||
| <section class="form"> | <section class="form"> | ||||
| @@ -1,9 +0,0 @@ | |||||
| <section class="download-button" *ngIf="fileDetails"> | |||||
| <div class="extension"> | |||||
| {{ fileDetails.extension }} | |||||
| </div> | |||||
| <div class="file-labels"> | |||||
| <h5> {{ fileDetails.name }} </h5> | |||||
| <p> {{ fileDetails.size }} </p> | |||||
| </div> | |||||
| </section> | |||||
| @@ -1,43 +0,0 @@ | |||||
| .download-button { | |||||
| display: inline-flex; | |||||
| border: 1px solid var(--border-grey); | |||||
| border-radius: 1rem; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| cursor: pointer; | |||||
| min-height: 4rem; | |||||
| padding: 1rem; | |||||
| &:hover{ | |||||
| background-color: var(--border-grey); | |||||
| } | |||||
| .extension { | |||||
| padding: 1rem; | |||||
| text-align: center; | |||||
| border: 1px solid var(--border-grey); | |||||
| height: 2rem; | |||||
| border-radius: 0.5rem; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| color: var(--dark-grey); | |||||
| font-size: 1.4rem; | |||||
| margin-right: 1rem; | |||||
| } | |||||
| .file-labels { | |||||
| flex-grow: 1; | |||||
| line-height: 1.5; | |||||
| h5 { | |||||
| font-size: 1.2rem; | |||||
| color: var(--teal); | |||||
| } | |||||
| p { | |||||
| font-size: 1.1rem; | |||||
| color: var(--dark-grey); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,20 +0,0 @@ | |||||
| import { Component, Input, OnInit } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-download-button', | |||||
| templateUrl: './download-button.component.html', | |||||
| styleUrls: ['./download-button.component.scss'] | |||||
| }) | |||||
| export class DownloadButtonComponent implements OnInit { | |||||
| @Input() fileDetails: { | |||||
| name: string, | |||||
| size: string, | |||||
| extension: string, | |||||
| } | undefined = undefined; | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| <section class="file"> | |||||
| <div class="file-avatar"> | |||||
| <div class="file-outline"></div> | |||||
| <section *ngIf="extension" class="extension"> | |||||
| {{ extension }} | |||||
| </section> | |||||
| </div> | |||||
| <div class="file-labels"> | |||||
| <h5 *ngIf="name"> {{ name }} </h5> | |||||
| <p *ngIf="readableSize"> {{ readableSize }} </p> | |||||
| </div> | |||||
| <a *ngIf="link" [href]="link" download class="download-button"> | |||||
| <img src="assets/icons/chevron-down.svg" alt="chevron down image"> | |||||
| </a> | |||||
| </section> | |||||
| @@ -0,0 +1,109 @@ | |||||
| .file { | |||||
| display: inline-flex; | |||||
| border: 1px solid var(--border-grey); | |||||
| border-radius: 1rem; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| height: 7rem; | |||||
| padding-left: 1rem; | |||||
| box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); | |||||
| .file-avatar { | |||||
| position: relative; | |||||
| width: 5rem; | |||||
| height: 7rem; | |||||
| .file-outline { | |||||
| position: absolute; | |||||
| top: 1.25rem; | |||||
| left: 0; | |||||
| width: 3.5rem; | |||||
| height: 4.5rem; | |||||
| border: 1px solid var(--border-grey); | |||||
| &::before { | |||||
| position: absolute; | |||||
| top: -1px; | |||||
| right: -1px; | |||||
| width: 1rem; | |||||
| height: 1rem; | |||||
| display: block; | |||||
| content: ""; | |||||
| background-color: white; | |||||
| } | |||||
| &::after { | |||||
| position: absolute; | |||||
| top: -1px; | |||||
| right: calc(-0.414rem - 1px); | |||||
| width: 1.414rem; | |||||
| height: 1px; | |||||
| display: block; | |||||
| content: ""; | |||||
| background-color: var(--border-grey); | |||||
| transform-origin: center left; | |||||
| transform: rotate(45deg); | |||||
| } | |||||
| } | |||||
| .extension { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| position: absolute; | |||||
| right: 0.5rem; | |||||
| bottom: 1.75rem; | |||||
| border: 1px solid var(--border-grey); | |||||
| text-align: center; | |||||
| background-color: var(--highlight); | |||||
| color: white; | |||||
| letter-spacing: 0.1rem; | |||||
| font-size: 1.2rem; | |||||
| padding: 0.1rem 0.4rem; | |||||
| padding-left: 0.6rem; | |||||
| font-weight: bold; | |||||
| } | |||||
| } | |||||
| .file-labels { | |||||
| width: 12rem; | |||||
| flex-grow: 1; | |||||
| line-height: 1.5; | |||||
| h5 { | |||||
| font-size: 1.2rem; | |||||
| color: var(--primary); | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| white-space: nowrap; | |||||
| } | |||||
| p { | |||||
| font-size: 1.1rem; | |||||
| color: var(--dark-grey); | |||||
| } | |||||
| } | |||||
| .download-button { | |||||
| height: 100%; | |||||
| width: 3rem; | |||||
| border-left: 1px solid var(--border-grey); | |||||
| margin-left: 1rem; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| cursor: pointer; | |||||
| &:hover{ | |||||
| background-color: var(--border-grey); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,20 +1,20 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { DownloadButtonComponent } from './download-button.component'; | |||||
| import { FileComponent } from './file.component'; | |||||
| describe('DownloadButtonComponent', () => { | |||||
| let component: DownloadButtonComponent; | |||||
| let fixture: ComponentFixture<DownloadButtonComponent>; | |||||
| describe('FileComponent', () => { | |||||
| let component: FileComponent; | |||||
| let fixture: ComponentFixture<FileComponent>; | |||||
| beforeEach(async () => { | beforeEach(async () => { | ||||
| await TestBed.configureTestingModule({ | await TestBed.configureTestingModule({ | ||||
| declarations: [ DownloadButtonComponent ] | |||||
| declarations: [ FileComponent ] | |||||
| }) | }) | ||||
| .compileComponents(); | .compileComponents(); | ||||
| }); | }); | ||||
| beforeEach(() => { | beforeEach(() => { | ||||
| fixture = TestBed.createComponent(DownloadButtonComponent); | |||||
| fixture = TestBed.createComponent(FileComponent); | |||||
| component = fixture.componentInstance; | component = fixture.componentInstance; | ||||
| fixture.detectChanges(); | fixture.detectChanges(); | ||||
| }); | }); | ||||
| @@ -0,0 +1,72 @@ | |||||
| import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; | |||||
| type SizeUnit = 'B' | 'KB' | 'MB' | 'GB' | 'TB'; | |||||
| @Component({ | |||||
| selector: 'app-file', | |||||
| templateUrl: './file.component.html', | |||||
| styleUrls: ['./file.component.scss'] | |||||
| }) | |||||
| export class FileComponent implements OnInit, OnChanges { | |||||
| @Input() name = ''; | |||||
| @Input() sizeInBytes = 0; | |||||
| @Input() extension = ''; | |||||
| @Input() link = ''; | |||||
| readableSize = ''; | |||||
| constructor() { } | |||||
| getNextUnit(unit: SizeUnit): SizeUnit|undefined { | |||||
| switch (unit) { | |||||
| case 'B': | |||||
| return 'KB'; | |||||
| case 'KB': | |||||
| return 'MB'; | |||||
| case 'MB': | |||||
| return 'GB'; | |||||
| case 'GB': | |||||
| return 'TB'; | |||||
| case 'TB': | |||||
| return undefined | |||||
| default: | |||||
| throw new Error('Unknown unit: ' + unit); | |||||
| } | |||||
| } | |||||
| getReadableSize(sizeInBytes?: number) { | |||||
| let unit: SizeUnit = 'B'; | |||||
| if (typeof sizeInBytes === 'undefined') { | |||||
| return ''; | |||||
| } | |||||
| let size: number = sizeInBytes; | |||||
| while (size > 1024 && unit !== 'TB') { | |||||
| size /= 1024; | |||||
| const nextUnit = this.getNextUnit(unit); | |||||
| if (typeof nextUnit === 'undefined') { | |||||
| break; | |||||
| } | |||||
| unit = nextUnit; | |||||
| } | |||||
| return `${size.toFixed(1)} ${unit}`; | |||||
| } | |||||
| ngOnChanges(simpleChanges: SimpleChanges) { | |||||
| if (simpleChanges.sizeInBytes && simpleChanges.sizeInBytes.currentValue !== simpleChanges.sizeInBytes.previousValue) { | |||||
| this.readableSize = this.getReadableSize(simpleChanges.sizeInBytes.currentValue); | |||||
| } | |||||
| } | |||||
| ngOnInit(): void { | |||||
| if (typeof this.sizeInBytes !== 'undefined') { | |||||
| this.readableSize = this.getReadableSize(this.sizeInBytes); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,5 @@ | |||||
| <ul> | <ul> | ||||
| <li *ngFor="const entity of entities" (click)="selectEntity(entity)" | |||||
| <li *ngFor="let entity of entities" (click)="selectEntity(entity)" | |||||
| [ngClass]="{'isActive': entity.isSelected}"> | [ngClass]="{'isActive': entity.isSelected}"> | ||||
| <img [src]="entity.avatar" alt="entity.name"> | <img [src]="entity.avatar" alt="entity.name"> | ||||
| <div class="user-data"> | <div class="user-data"> | ||||