From cc155f7d9631331718e80453a6517c8d41ecada8 Mon Sep 17 00:00:00 2001 From: charlotte Date: Wed, 9 Oct 2024 17:06:40 +0200 Subject: [PATCH] Add a UI for bulk meter read upload using CSV --- src/app/nav/sidemenu/sidemenu.component.html | 336 +++++++++++++----- .../add-bulk-reads.component.html | 162 +++++++++ .../add-bulk-reads.component.scss | 196 ++++++++++ .../add-bulk-reads.component.spec.ts | 23 ++ .../add-bulk-reads.component.ts | 134 +++++++ .../meter-read/meter-read-routing.module.ts | 3 +- src/app/view/meter-read/meter-read.module.ts | 2 + 7 files changed, 775 insertions(+), 81 deletions(-) create mode 100644 src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.html create mode 100644 src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.scss create mode 100644 src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.spec.ts create mode 100644 src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.ts diff --git a/src/app/nav/sidemenu/sidemenu.component.html b/src/app/nav/sidemenu/sidemenu.component.html index 5bba2e1..4ea5149 100644 --- a/src/app/nav/sidemenu/sidemenu.component.html +++ b/src/app/nav/sidemenu/sidemenu.component.html @@ -1,60 +1,115 @@ -
-

{{loginuser.email}}

-

{{loginuser.role}}

+
+

+ {{ loginuser.email }} +

+

+ {{ loginuser.role }} +

- - + account_circle Organization - + My Organizations - + Add Organizations - + All Organizations - + All Users - - + All ApiUser - + Invitation - - - - + + devices Device @@ -63,35 +118,60 @@ list My Devices --> - - + My Devices - + Add Devices - + Bulk Upload - - - + + list MeterRead @@ -100,25 +180,54 @@ list My Devices --> - + All Reads - + Add MeterRead - + + Bulk Upload + + Certified MeterReads - - + + list Yield Configuration @@ -127,21 +236,34 @@ list My Devices --> - + All Yield - + Add - - - - + + list Permission @@ -150,93 +272,147 @@ list My Devices --> - + ACL Module - + User Role Permission - + ApiUser Permission - - - + + list Permission - - + Permission Request - + My Permission - - - - - - + account_circle Account Setting - - + Profile - - - - \ No newline at end of file + diff --git a/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.html b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.html new file mode 100644 index 0000000..850c221 --- /dev/null +++ b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.html @@ -0,0 +1,162 @@ +
+ + +
+

+ MeterRead Bulk Registration +

+
+
+ +
+
+
+ +
+
+
+
+ + Organization + + + + + + {{ code.name }} + + + +
+
+ +
+ + + +
+ +
+
+
+
+
+   + +
+
+ +
+ {{ message }} +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID{{ i + 1 }} + Created At + + {{ element.createdAt | date: 'dd MMM y hh:mm' }} + JobId{{ element.jobId }}File Id{{ element.fileId }}Status{{ element.status }}Action + + + +
+ +
+
+
+
diff --git a/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.scss b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.scss new file mode 100644 index 0000000..9cb6fe4 --- /dev/null +++ b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.scss @@ -0,0 +1,196 @@ +.body-bg { + padding: 35px 30px 35px 30px; + background: #f2f2f2; + + .mat-mdc-card { + box-shadow: 3px 0px 33px rgba(0, 0, 0, 0.1) !important; + border: none !important; + } + } + + p { + font-family: Lato; + } + + .output { + background-color: rgb(253, 253, 253); + padding: 0px 10px 10px 10px; + margin-bottom: 40px; + margin-top: 20px; + + box-shadow: 2px 2px 2px #000; + } + + .example-container { + background-color: white; + padding: 10px 20px 20px 20px; + + } + + .example-container1 mat-form-field+mat-form-field { + margin-left: 8px; + padding: 10px 0px 0px 0px; + } + + .example-right-align { + text-align: right; + } + + .addbtn { + width: 200px; + margin: 20px 50px 20px 20px; + } + + input.example-right-align::-webkit-outer-spin-button, + input.example-right-align::-webkit-inner-spin-button { + display: none; + } + + input.example-right-align { + -moz-appearance: textfield; + } + .danger-btn + { + border-radius: 50px!important; + padding: 3px; + font-size: 10px!important; + .material-icons{ + font-size: 18px !important; + } + .mat-icon{ + height: 19px; + width: 19px; + } + } + .btn-outline-danger{ + --bs-btn-color: #f2be1a; + --bs-btn-border-color: #f2be1a; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #f2be1a; + --bs-btn-hover-border-color: #f2be1a; + --bs-btn-focus-shadow-rgb: 220, 53, 69; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #f2be1a; + --bs-btn-active-border-color: #f2be1a; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #f2be1a; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #f2be1a; + --bs-gradient: none; + } + + .cursor-pointer + { + cursor: pointer; + } + + + @-webkit-keyframes scroll-inner { + from { + position: relative; + top: 5%; + } + to { + position: relative; + top: 10%; + } + } + @keyframes scroll-inner { + from { + position: relative; + top:5%; + } + to { + position: relative; + top: 10%; + } + } + @-webkit-keyframes scroll-mouse { + from { + position: relative; + top: 0; + } + to { + position: relative; + top: 15px; + } + } + @keyframes scroll-mouse { + from { + position: relative; + top: 0; + } + to { + position: relative; + top: 15px; + } + } + + + + + .scroll-down { + + -webkit-animation: scroll-inner 1.5s; + animation: scroll-inner 1.5s; + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-timing-function: ease; + animation-timing-function: ease; + } + .progress-bar { + padding: 0; + } + + .progress { + width: 50px; + } + + #fileInput { + position: absolute; + cursor: pointer; + z-index: 10; + opacity: 0; + height: 100%; + left: 0px; + top: 0px; + } + + .mat-toolbar-single-row { + height: auto !important; + background: transparent; + padding: 0; + } + + .mat-toolbar-single-row button { + width: 100px; + } + + .mat-form-field { + width: 100%; + } + + .mat-mdc-form-field { + display: block; + } + + .message { + background-color: #ddd; + padding: 15px; + color: #333; + border: #aaa solid 1px; + border-radius: 4px; + margin-bottom: 10px; + } + mat-progress-spinner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 5; + } + + .upload-reset-buttons + { + margin-top: 30px; + } \ No newline at end of file diff --git a/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.spec.ts b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.spec.ts new file mode 100644 index 0000000..edaf6a7 --- /dev/null +++ b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddBulkReadsComponent } from './add-bulk-reads.component'; + +describe('AddBulkReadsComponent', () => { + let component: AddBulkReadsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AddBulkReadsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AddBulkReadsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.ts b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.ts new file mode 100644 index 0000000..9aab526 --- /dev/null +++ b/src/app/view/meter-read/add-bulk-reads/add-bulk-reads.component.ts @@ -0,0 +1,134 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Observable } from 'rxjs'; +import { FileuploadService } from '../../../auth/services/fileupload.service'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatSort } from '@angular/material/sort'; +import { MatPaginator } from '@angular/material/paginator'; +import { AdminService, OrganizationService } from '../../../auth/services'; +import { OrganizationInformation } from '../../../models'; + +@Component({ + selector: 'app-add-bulk-reads', + templateUrl: './add-bulk-reads.component.html', + styleUrls: ['./add-bulk-reads.component.scss'], +}) +export class AddBulkReadsComponent implements OnInit { + currentFile?: File | null; + progress = 0; + message = ''; + pageSize: number = 10; + fileName = 'Please click here to select file'; + fileInfos?: Observable; + showmeterreadinfo: boolean = false; + MeterreadstatusList: any = []; + loading: boolean = true; + objectKeys = Object.keys; + displayedColumns = [ + 'serialno', + 'createdAt', + 'jobId', + 'fileId', + 'status', + 'actions', + ]; + displayedColumns1 = [ + 'serialno', + 'externalId', + 'errorsList', + 'Status', + 'Action', + ]; + constructor( + private uploadService: FileuploadService, + // private router: Router, + // private toastrService: ToastrService, + private adminService: AdminService, + private orgService: OrganizationService, + ) { + this.loginuser = JSON.parse(sessionStorage.getItem('loginuser')!); + } + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + dataSource: MatTableDataSource; + dataSource1: MatTableDataSource; + data: any; + orglist: any; + filteredOrgList: OrganizationInformation[] = []; + orgname: string; + orgId: number; + loginuser: any; + + ngOnInit(): void { + if (this.loginuser.role === 'Admin') { + this.adminService.GetAllOrganization().subscribe((data) => { + this.orglist = data.organizations.filter( + (org: OrganizationInformation) => org.organizationType !== 'Buyer', + ); + this.filteredOrgList = this.orglist; + }); + } else if (this.loginuser.role === 'ApiUser') { + this.orgService.GetApiUserAllOrganization().subscribe((data) => { + this.orglist = data.organizations.filter( + (org) => org.organizationType != 'Buyer', + ); + this.filteredOrgList = this.orglist; + }); + } + this.JobDisplayList(); + } + + filterOrgList() { + this.filteredOrgList = this.orglist.filter( + (org: OrganizationInformation) => { + return org.name.toLowerCase().includes(this.orgname.toLowerCase()); + }, + ); + } + selectOrg(event: any) { + const selectedCountry = this.orglist.find( + (option: any) => option.name === event.option.value, + ); + if (selectedCountry) { + this.orgId = selectedCountry.id; + } + } + reset() { + this.currentFile = null; + this.fileName = 'Please click here to select file'; + } + selectFile(event: any): void { + if (event.target.files && event.target.files[0]) { + const file: File = event.target.files[0]; + this.currentFile = file; + this.fileName = this.currentFile.name; + if (!this.fileName.endsWith('.csv')) { + this.fileName = 'Invalid file'; + this.currentFile = null; + } + } else { + this.fileName = 'Please click here to select file'; + } + event.target.value = ''; + } + + openFileExplorer() { + document.getElementById('fileInput')?.click(); + } + + upload(): void { + this.progress = 0; + this.message = ''; + } + JobDisplayList() { + this.showmeterreadinfo = false; + this.loading = true; + this.uploadService.getCsvJobList().subscribe((data) => { + // display list in the console + this.loading = false; + this.data = data; + this.dataSource = new MatTableDataSource(this.data.csvJobs); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + }); + } +} diff --git a/src/app/view/meter-read/meter-read-routing.module.ts b/src/app/view/meter-read/meter-read-routing.module.ts index fc1ddac..404b304 100644 --- a/src/app/view/meter-read/meter-read-routing.module.ts +++ b/src/app/view/meter-read/meter-read-routing.module.ts @@ -2,11 +2,12 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { AddreadComponent } from './addread/addread.component'; import { AllMetereadsComponent } from '../meter-read/all-metereads/all-metereads.component'; +import { AddBulkReadsComponent } from './add-bulk-reads/add-bulk-reads.component'; const routes: Routes = [ { path: '', redirectTo: 'Allreads', pathMatch: 'full' }, { path: 'All', component: AllMetereadsComponent }, { path: 'add', component: AddreadComponent }, - // { path: 'bulk_upload', component: AddBulkDeviceComponent }, + { path: 'bulk_upload', component: AddBulkReadsComponent }, // { path: 'edit/:id', component: EditDeviceComponent }, ]; diff --git a/src/app/view/meter-read/meter-read.module.ts b/src/app/view/meter-read/meter-read.module.ts index a957606..e48d8b6 100644 --- a/src/app/view/meter-read/meter-read.module.ts +++ b/src/app/view/meter-read/meter-read.module.ts @@ -8,11 +8,13 @@ import { AllMetereadsComponent } from './all-metereads/all-metereads.component'; import { MeterReadTableComponent } from './meter-read-table/meter-read-table.component'; import { PipesModule } from '../../pipes.module'; +import { AddBulkReadsComponent } from './add-bulk-reads/add-bulk-reads.component'; @NgModule({ declarations: [ AllMetereadsComponent, AddreadComponent, + AddBulkReadsComponent, MeterReadTableComponent, ], imports: [