@@ -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"> | ||||