From 6eddb7180e18746af69b9ee0e8122bbd265c41ba Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 22:39:42 +0200
Subject: [PATCH 01/32] Update package-lock.json
---
package-lock.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/package-lock.json b/package-lock.json
index 4b7e90c..e65ff26 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
+ "name": "fe-test-app",
"version": "1.0.0",
"dependencies": {
"@angular/animations": "~8.2.14",
From 686d4c03fa745524cabfbf108e37de726b788126 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 22:44:34 +0200
Subject: [PATCH 02/32] added api domain url
---
src/environments/environment.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index ffe8aed..0a007cf 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1,3 +1,4 @@
export const environment = {
- production: false
+ production: false,
+ domain: 'http://localhost:3000'
};
From c8b7fd7854d702689d9f41e4f2c3a7715b55b6dd Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 22:46:37 +0200
Subject: [PATCH 03/32] renamed url
---
src/environments/environment.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 0a007cf..60aaac8 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1,4 +1,4 @@
export const environment = {
production: false,
- domain: 'http://localhost:3000'
+ apiBaseUrl: 'http://localhost:3000',
};
From 97a7bee0961456bc2ad1bb26d4348658129bd057 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 22:56:59 +0200
Subject: [PATCH 04/32] created usersTableComponent
with routing
---
src/app/app-routing.module.ts | 8 +++++-
src/app/app.module.ts | 6 +++--
.../users-table/users-table.component.html | 1 +
.../users-table/users-table.component.scss | 0
.../users-table/users-table.component.spec.ts | 25 +++++++++++++++++++
.../users-table/users-table.component.ts | 15 +++++++++++
src/app/users/users.component.html | 1 +
src/app/users/users.component.scss | 0
src/app/users/users.component.spec.ts | 25 +++++++++++++++++++
9 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 src/app/components/users-table/users-table.component.html
create mode 100644 src/app/components/users-table/users-table.component.scss
create mode 100644 src/app/components/users-table/users-table.component.spec.ts
create mode 100644 src/app/components/users-table/users-table.component.ts
create mode 100644 src/app/users/users.component.html
create mode 100644 src/app/users/users.component.scss
create mode 100644 src/app/users/users.component.spec.ts
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 06c7342..020667c 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,8 +1,14 @@
+import { UsersTableComponent } from './components/users-table/users-table.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-const routes: Routes = [];
+const routes: Routes = [
+ {
+ path: 'users',
+ component: UsersTableComponent
+ }
+];
@NgModule({
imports: [RouterModule.forRoot(routes)],
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 0cadd23..58f3d01 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -4,11 +4,13 @@ import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { UsersTableComponent } from './components/users-table/users-table.component';
@NgModule({
declarations: [
- AppComponent
- ],
+ AppComponent,
+ UsersTableComponent
+ ],
imports: [
BrowserModule,
AppRoutingModule,
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
new file mode 100644
index 0000000..d55e7ad
--- /dev/null
+++ b/src/app/components/users-table/users-table.component.html
@@ -0,0 +1 @@
+
users-table works!
diff --git a/src/app/components/users-table/users-table.component.scss b/src/app/components/users-table/users-table.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/users-table/users-table.component.spec.ts b/src/app/components/users-table/users-table.component.spec.ts
new file mode 100644
index 0000000..5b29b69
--- /dev/null
+++ b/src/app/components/users-table/users-table.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UsersTableComponent } from './users-table.component';
+
+describe('UsersTableComponent', () => {
+ let component: UsersTableComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ UsersTableComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UsersTableComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
new file mode 100644
index 0000000..b5696be
--- /dev/null
+++ b/src/app/components/users-table/users-table.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'exads-users-table',
+ templateUrl: './users-table.component.html',
+ styleUrls: ['./users-table.component.scss']
+})
+export class UsersTableComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/src/app/users/users.component.html b/src/app/users/users.component.html
new file mode 100644
index 0000000..065c5c6
--- /dev/null
+++ b/src/app/users/users.component.html
@@ -0,0 +1 @@
+users works!
diff --git a/src/app/users/users.component.scss b/src/app/users/users.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/users/users.component.spec.ts b/src/app/users/users.component.spec.ts
new file mode 100644
index 0000000..909b5ba
--- /dev/null
+++ b/src/app/users/users.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UsersComponent } from './users.component';
+
+describe('UsersComponent', () => {
+ let component: UsersComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ UsersComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UsersComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
From 63c7fc7de597f402a1a836fd9ce2ea4320977e65 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 22:57:31 +0200
Subject: [PATCH 05/32] created routing service
---
src/app/app.component.ts | 8 +++++++-
src/app/services/routing.service.spec.ts | 12 ++++++++++++
src/app/services/routing.service.ts | 15 +++++++++++++++
3 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 src/app/services/routing.service.spec.ts
create mode 100644 src/app/services/routing.service.ts
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 3b59aaa..ae8a768 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,8 +1,14 @@
import { Component } from '@angular/core';
+import { RoutingService } from './services/routing.service';
@Component({
selector: 'exads-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
-export class AppComponent { }
+export class AppComponent {
+
+ constructor(private routingService: RoutingService){
+ this.routingService.navigateToUsersTable();
+ }
+}
diff --git a/src/app/services/routing.service.spec.ts b/src/app/services/routing.service.spec.ts
new file mode 100644
index 0000000..43fe84f
--- /dev/null
+++ b/src/app/services/routing.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { RoutingService } from './routing.service';
+
+describe('RoutingService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: RoutingService = TestBed.get(RoutingService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/services/routing.service.ts b/src/app/services/routing.service.ts
new file mode 100644
index 0000000..359b6a0
--- /dev/null
+++ b/src/app/services/routing.service.ts
@@ -0,0 +1,15 @@
+import { Injectable } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class RoutingService {
+
+ constructor(private router: Router) { }
+
+ public navigateToUsersTable(): void {
+ this.router.navigateByUrl('users');
+ }
+
+}
From 5a9c7e5412b3f80bd3f6a011c9a93bb8a651c72b Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Mon, 28 Mar 2022 23:29:58 +0200
Subject: [PATCH 06/32] added create user component, updated routing
updated routing to fall back to 'users' put a routes enum in, added in the create user component
---
src/app/app-routing.module.ts | 18 +++++++++----
src/app/app.component.ts | 4 +--
src/app/app.module.ts | 4 ++-
.../create-user/create-user.component.html | 1 +
.../create-user/create-user.component.scss | 0
.../create-user/create-user.component.spec.ts | 25 +++++++++++++++++++
.../create-user/create-user.component.ts | 15 +++++++++++
src/app/enums/routes.enum.ts | 4 +++
src/app/services/routing.service.ts | 5 ++--
9 files changed, 65 insertions(+), 11 deletions(-)
create mode 100644 src/app/components/create-user/create-user.component.html
create mode 100644 src/app/components/create-user/create-user.component.scss
create mode 100644 src/app/components/create-user/create-user.component.spec.ts
create mode 100644 src/app/components/create-user/create-user.component.ts
create mode 100644 src/app/enums/routes.enum.ts
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 020667c..f827e00 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,13 +1,21 @@
-import { UsersTableComponent } from './components/users-table/users-table.component';
import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
+import { RouterModule, Routes } from '@angular/router';
+import { CreateUserComponent } from './components/create-user/create-user.component';
+import { UsersTableComponent } from './components/users-table/users-table.component';
+import { ROUTES } from './enums/routes.enum';
const routes: Routes = [
{
- path: 'users',
- component: UsersTableComponent
- }
+ path: ROUTES.USERS,
+ component: UsersTableComponent,
+ },
+ {
+ path: ROUTES.CREATE_USER,
+ component: CreateUserComponent,
+ pathMatch: 'full'
+ },
+ { path: '**', redirectTo: ROUTES.USERS, pathMatch: 'full' }
];
@NgModule({
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index ae8a768..80c2eaf 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,5 +1,4 @@
import { Component } from '@angular/core';
-import { RoutingService } from './services/routing.service';
@Component({
selector: 'exads-root',
@@ -8,7 +7,6 @@ import { RoutingService } from './services/routing.service';
})
export class AppComponent {
- constructor(private routingService: RoutingService){
- this.routingService.navigateToUsersTable();
+ constructor() {
}
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 58f3d01..d2dc07f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -5,11 +5,13 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { UsersTableComponent } from './components/users-table/users-table.component';
+import { CreateUserComponent } from './components/create-user/create-user.component';
@NgModule({
declarations: [
AppComponent,
- UsersTableComponent
+ UsersTableComponent,
+ CreateUserComponent
],
imports: [
BrowserModule,
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
new file mode 100644
index 0000000..cec559f
--- /dev/null
+++ b/src/app/components/create-user/create-user.component.html
@@ -0,0 +1 @@
+create-user works!
diff --git a/src/app/components/create-user/create-user.component.scss b/src/app/components/create-user/create-user.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/create-user/create-user.component.spec.ts b/src/app/components/create-user/create-user.component.spec.ts
new file mode 100644
index 0000000..0489eff
--- /dev/null
+++ b/src/app/components/create-user/create-user.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CreateUserComponent } from './create-user.component';
+
+describe('CreateUserComponent', () => {
+ let component: CreateUserComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ CreateUserComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CreateUserComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
new file mode 100644
index 0000000..3e04481
--- /dev/null
+++ b/src/app/components/create-user/create-user.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'exads-create-user',
+ templateUrl: './create-user.component.html',
+ styleUrls: ['./create-user.component.scss']
+})
+export class CreateUserComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/src/app/enums/routes.enum.ts b/src/app/enums/routes.enum.ts
new file mode 100644
index 0000000..fec9c31
--- /dev/null
+++ b/src/app/enums/routes.enum.ts
@@ -0,0 +1,4 @@
+export enum ROUTES {
+ USERS = 'users',
+ CREATE_USER = 'users/create'
+}
diff --git a/src/app/services/routing.service.ts b/src/app/services/routing.service.ts
index 359b6a0..3bb2cb7 100644
--- a/src/app/services/routing.service.ts
+++ b/src/app/services/routing.service.ts
@@ -1,3 +1,4 @@
+import { ROUTES } from '../enums/routes.enum';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@@ -8,8 +9,8 @@ export class RoutingService {
constructor(private router: Router) { }
- public navigateToUsersTable(): void {
- this.router.navigateByUrl('users');
+ public navigateToCreateUser(): void {
+ this.router.navigateByUrl(ROUTES.USERS);
}
}
From 95c99a8af1fa579738cf5f2fe5581e9b671ec6da Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 00:03:29 +0200
Subject: [PATCH 07/32] updated routing
added enum for app routes and seperate enum for API routes,
---
src/app/app-routing.module.ts | 8 ++++----
src/app/enums/api-routes.enum.ts | 4 ++++
src/app/enums/{routes.enum.ts => app-routes.enum.ts} | 2 +-
3 files changed, 9 insertions(+), 5 deletions(-)
create mode 100644 src/app/enums/api-routes.enum.ts
rename src/app/enums/{routes.enum.ts => app-routes.enum.ts} (67%)
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index f827e00..d606e9a 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -2,20 +2,20 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CreateUserComponent } from './components/create-user/create-user.component';
import { UsersTableComponent } from './components/users-table/users-table.component';
-import { ROUTES } from './enums/routes.enum';
+import { APP_ROUTES } from './enums/app-routes.enum';
const routes: Routes = [
{
- path: ROUTES.USERS,
+ path: APP_ROUTES.USERS,
component: UsersTableComponent,
},
{
- path: ROUTES.CREATE_USER,
+ path: APP_ROUTES.CREATE_USER,
component: CreateUserComponent,
pathMatch: 'full'
},
- { path: '**', redirectTo: ROUTES.USERS, pathMatch: 'full' }
+ { path: '**', redirectTo: APP_ROUTES.USERS, pathMatch: 'full' }
];
@NgModule({
diff --git a/src/app/enums/api-routes.enum.ts b/src/app/enums/api-routes.enum.ts
new file mode 100644
index 0000000..b5cf8fa
--- /dev/null
+++ b/src/app/enums/api-routes.enum.ts
@@ -0,0 +1,4 @@
+export enum API_ROUTES {
+ USERS = 'users',
+ STATUSES = 'statuses'
+}
diff --git a/src/app/enums/routes.enum.ts b/src/app/enums/app-routes.enum.ts
similarity index 67%
rename from src/app/enums/routes.enum.ts
rename to src/app/enums/app-routes.enum.ts
index fec9c31..3e8fd5c 100644
--- a/src/app/enums/routes.enum.ts
+++ b/src/app/enums/app-routes.enum.ts
@@ -1,4 +1,4 @@
-export enum ROUTES {
+export enum APP_ROUTES {
USERS = 'users',
CREATE_USER = 'users/create'
}
From cdfef36570fea558525200703065cb1ef8d25287 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 00:03:37 +0200
Subject: [PATCH 08/32] deleted unused component
---
src/app/users/users.component.html | 1 -
src/app/users/users.component.scss | 0
src/app/users/users.component.spec.ts | 25 -------------------------
3 files changed, 26 deletions(-)
delete mode 100644 src/app/users/users.component.html
delete mode 100644 src/app/users/users.component.scss
delete mode 100644 src/app/users/users.component.spec.ts
diff --git a/src/app/users/users.component.html b/src/app/users/users.component.html
deleted file mode 100644
index 065c5c6..0000000
--- a/src/app/users/users.component.html
+++ /dev/null
@@ -1 +0,0 @@
-users works!
diff --git a/src/app/users/users.component.scss b/src/app/users/users.component.scss
deleted file mode 100644
index e69de29..0000000
diff --git a/src/app/users/users.component.spec.ts b/src/app/users/users.component.spec.ts
deleted file mode 100644
index 909b5ba..0000000
--- a/src/app/users/users.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { UsersComponent } from './users.component';
-
-describe('UsersComponent', () => {
- let component: UsersComponent;
- let fixture: ComponentFixture;
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [ UsersComponent ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(UsersComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
From 7720fa08f4b0d2fd18a348ed5f65b776e4db250b Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 00:04:46 +0200
Subject: [PATCH 09/32] added users service
added generic response interface based off of what's available on the two endpoints and what I've seen on the postman, can be implented by response classes as needed
---
src/app/app.module.ts | 4 +++-
.../users-table/users-table.component.ts | 10 ++++++++-
src/app/interfaces/api-response.interface.ts | 5 +++++
src/app/models/status.model.ts | 3 +++
src/app/models/user.model.ts | 3 +++
src/app/responses/users.response.ts | 6 ++++++
src/app/services/routing.service.ts | 4 ++--
src/app/services/user.service.spec.ts | 12 +++++++++++
src/app/services/user.service.ts | 21 +++++++++++++++++++
9 files changed, 64 insertions(+), 4 deletions(-)
create mode 100644 src/app/interfaces/api-response.interface.ts
create mode 100644 src/app/models/status.model.ts
create mode 100644 src/app/models/user.model.ts
create mode 100644 src/app/responses/users.response.ts
create mode 100644 src/app/services/user.service.spec.ts
create mode 100644 src/app/services/user.service.ts
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index d2dc07f..4ae9501 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,3 +1,4 @@
+import { HttpClient, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
@@ -16,7 +17,8 @@ import { CreateUserComponent } from './components/create-user/create-user.compon
imports: [
BrowserModule,
AppRoutingModule,
- BrowserAnimationsModule
+ BrowserAnimationsModule,
+ HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index b5696be..1f3a069 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,4 +1,6 @@
+import { UserService } from './../../services/user.service';
import { Component, OnInit } from '@angular/core';
+import { User } from 'src/app/models/user.model';
@Component({
selector: 'exads-users-table',
@@ -7,9 +9,15 @@ import { Component, OnInit } from '@angular/core';
})
export class UsersTableComponent implements OnInit {
- constructor() { }
+ public users: User[] = [];
+
+ constructor(private userService: UserService) { }
ngOnInit() {
+ this.userService.getUsers().toPromise().then((users: User[]) => {
+ debugger;
+ this.users = users;
+ }).catch((err) => console.error(err));
}
}
diff --git a/src/app/interfaces/api-response.interface.ts b/src/app/interfaces/api-response.interface.ts
new file mode 100644
index 0000000..8ad58db
--- /dev/null
+++ b/src/app/interfaces/api-response.interface.ts
@@ -0,0 +1,5 @@
+export interface ApiResponse {
+ message?: string;
+ missingParams?: [];
+ data: T | { count?: number};
+}
diff --git a/src/app/models/status.model.ts b/src/app/models/status.model.ts
new file mode 100644
index 0000000..e6d959e
--- /dev/null
+++ b/src/app/models/status.model.ts
@@ -0,0 +1,3 @@
+export class Status {
+
+}
diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts
new file mode 100644
index 0000000..11fb869
--- /dev/null
+++ b/src/app/models/user.model.ts
@@ -0,0 +1,3 @@
+export class User {
+
+}
diff --git a/src/app/responses/users.response.ts b/src/app/responses/users.response.ts
new file mode 100644
index 0000000..26e1e91
--- /dev/null
+++ b/src/app/responses/users.response.ts
@@ -0,0 +1,6 @@
+import { User } from '../models/user.model';
+import { ApiResponse } from './../interfaces/api-response.interface';
+export class UsersResponse implements ApiResponse {
+ data: { count?: number;
+ users: User[] };
+}
diff --git a/src/app/services/routing.service.ts b/src/app/services/routing.service.ts
index 3bb2cb7..6c5ef31 100644
--- a/src/app/services/routing.service.ts
+++ b/src/app/services/routing.service.ts
@@ -1,4 +1,4 @@
-import { ROUTES } from '../enums/routes.enum';
+import { APP_ROUTES } from '../enums/app-routes.enum';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@@ -10,7 +10,7 @@ export class RoutingService {
constructor(private router: Router) { }
public navigateToCreateUser(): void {
- this.router.navigateByUrl(ROUTES.USERS);
+ this.router.navigateByUrl(APP_ROUTES.USERS);
}
}
diff --git a/src/app/services/user.service.spec.ts b/src/app/services/user.service.spec.ts
new file mode 100644
index 0000000..9e7fd1c
--- /dev/null
+++ b/src/app/services/user.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { UserService } from './user.service';
+
+describe('UserService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: UserService = TestBed.get(UserService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
new file mode 100644
index 0000000..e957f4b
--- /dev/null
+++ b/src/app/services/user.service.ts
@@ -0,0 +1,21 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { environment } from 'src/environments/environment';
+import { User } from '../models/user.model';
+import { API_ROUTES } from './../enums/api-routes.enum';
+import { UsersResponse } from './../responses/users.response';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class UserService {
+
+ constructor(private http: HttpClient) { }
+
+ public getUsers(): Observable {
+ return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS)
+ .pipe(map((response: UsersResponse) => {debugger; return response.data.users}));
+ }
+}
From 0716e5377c65fb9f9ebea9941a85d66cc26e816c Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 21:27:47 +0200
Subject: [PATCH 10/32] added in ngx datatable
with columns rows and pagination, material theme and striped
---
src/app/app.module.ts | 4 +-
.../users-table/users-table.component.html | 59 ++++++++++++++++++-
.../users-table/users-table.component.scss | 13 ++++
.../users-table/users-table.component.ts | 16 +++--
src/app/models/user.model.ts | 8 ++-
src/app/services/user.service.ts | 2 +-
src/styles.scss | 2 +-
7 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4ae9501..71ceec9 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -7,6 +7,7 @@ import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { UsersTableComponent } from './components/users-table/users-table.component';
import { CreateUserComponent } from './components/create-user/create-user.component';
+import { NgxDatatableModule } from '@swimlane/ngx-datatable';
@NgModule({
declarations: [
@@ -18,7 +19,8 @@ import { CreateUserComponent } from './components/create-user/create-user.compon
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
- HttpClientModule
+ HttpClientModule,
+ NgxDatatableModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index d55e7ad..1f65f28 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1 +1,58 @@
-users-table works!
+
+
+
+
+ users.table.username
+
+
+ {{row.username}}
+
+
+
+
+
+ USERS.TABLE.FULLNAME
+
+
+ {{row.first_name}} {{row.last_name}}
+
+
+
+
+
+ USERS.TABLE.EMAIL
+
+
+ {{row.email}}
+
+
+
+
+
+ USERS.TABLE.STATUS
+
+
+
+ {{row.id_status == 1 ? 'USERS.ACTIVE' : row.id_status == 3 ? 'USERS.DISABLED' : ''}}
+
+
+
+
+
+
+ USERS.TABLE.CREATED_DATE
+
+
+ {{row.created_date | date:'yyyy-mm-dd'}}
+
+
+
+
+
diff --git a/src/app/components/users-table/users-table.component.scss b/src/app/components/users-table/users-table.component.scss
index e69de29..19f1ef6 100644
--- a/src/app/components/users-table/users-table.component.scss
+++ b/src/app/components/users-table/users-table.component.scss
@@ -0,0 +1,13 @@
+.user-table-container {
+ height: 90vw;
+ width: 100%;
+ max-height: 95vh;
+}
+
+.active {
+ color: green;
+}
+
+.disabled {
+ color: red;
+}
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index 1f3a069..9f649d3 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,6 +1,8 @@
-import { UserService } from './../../services/user.service';
import { Component, OnInit } from '@angular/core';
+import { ColumnMode } from '@swimlane/ngx-datatable';
import { User } from 'src/app/models/user.model';
+import { UserService } from './../../services/user.service';
+
@Component({
selector: 'exads-users-table',
@@ -9,14 +11,18 @@ import { User } from 'src/app/models/user.model';
})
export class UsersTableComponent implements OnInit {
- public users: User[] = [];
-
+ public columnMode = ColumnMode.force;
+ public rows: User[] = [];
+ public messages = {
+ emptyMessage: 'TABLE.NO_DATE',
+ totalMessage: 'TABLE.TOTAL',
+ selectedMessage: 'TABLE.SELECTED'
+ }
constructor(private userService: UserService) { }
ngOnInit() {
this.userService.getUsers().toPromise().then((users: User[]) => {
- debugger;
- this.users = users;
+ this.rows = users;
}).catch((err) => console.error(err));
}
diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts
index 11fb869..845b39a 100644
--- a/src/app/models/user.model.ts
+++ b/src/app/models/user.model.ts
@@ -1,3 +1,9 @@
export class User {
-
+ public id: number;
+ public first_name: string;
+ public last_name: string;
+ public email: string;
+ public username: string;
+ public created_date: Date;
+ public id_status: string;
}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index e957f4b..3685080 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -16,6 +16,6 @@ export class UserService {
public getUsers(): Observable {
return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS)
- .pipe(map((response: UsersResponse) => {debugger; return response.data.users}));
+ .pipe(map((response: UsersResponse) => {return response.data.users}));
}
}
diff --git a/src/styles.scss b/src/styles.scss
index dda6814..ad56e3e 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -1,3 +1,3 @@
-
+@import '../node_modules/@swimlane/ngx-datatable/src/themes/material.scss';
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
From 567e886900c362238f2afac787e17f4ecb827070 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 21:56:12 +0200
Subject: [PATCH 11/32] replaced ngx table with mat table
because it comes with custom pagination built in
---
src/app/app.module.ts | 5 +-
.../users-table/users-table.component.html | 99 +++++++++----------
.../users-table/users-table.component.ts | 23 +++--
3 files changed, 62 insertions(+), 65 deletions(-)
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 71ceec9..f17b3fc 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -7,7 +7,7 @@ import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { UsersTableComponent } from './components/users-table/users-table.component';
import { CreateUserComponent } from './components/create-user/create-user.component';
-import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { MatPaginatorModule, MatTableModule } from '@angular/material';
@NgModule({
declarations: [
@@ -20,7 +20,8 @@ import { NgxDatatableModule } from '@swimlane/ngx-datatable';
AppRoutingModule,
BrowserAnimationsModule,
HttpClientModule,
- NgxDatatableModule
+ MatTableModule,
+ MatPaginatorModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index 1f65f28..27f938b 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1,58 +1,55 @@
-
-
-
- users.table.username
-
-
- {{row.username}}
-
-
+
+
+ USERS.TABLE.USERNAME
+
+ {{element.username}}
+
+
-
-
- USERS.TABLE.FULLNAME
-
-
- {{row.first_name}} {{row.last_name}}
-
-
+
+ USERS.TABLE.FULLNAME
+
+ {{element.first_name}} {{element.last_name}}
+
+
-
-
- USERS.TABLE.EMAIL
-
-
- {{row.email}}
-
-
+
+
+ USERS.TABLE.EMAIL
+
+
+ {{element.email}}
+
+
-
-
- USERS.TABLE.STATUS
-
-
-
- {{row.id_status == 1 ? 'USERS.ACTIVE' : row.id_status == 3 ? 'USERS.DISABLED' : ''}}
-
-
-
+
+
+ USERS.TABLE.STATUS
+
+
+
+ {{element.id_status == 1 ? 'USERS.ACTIVE' : element.id_status == 3 ? 'USERS.DISABLED' : ''}}
+
+
+
-
-
- USERS.TABLE.CREATED_DATE
-
-
- {{row.created_date | date:'yyyy-mm-dd'}}
-
-
+
+
+ USERS.TABLE.CREATED_DATE
+
+
+ {{element.created_date | date:'yyyy-mm-dd'}}
+
+
-
+
+
+
+
+
+
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index 9f649d3..c1947ec 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,28 +1,27 @@
-import { Component, OnInit } from '@angular/core';
-import { ColumnMode } from '@swimlane/ngx-datatable';
+import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { User } from 'src/app/models/user.model';
import { UserService } from './../../services/user.service';
-
+import {MatPaginator, MatTableDataSource} from '@angular/material';
@Component({
selector: 'exads-users-table',
templateUrl: './users-table.component.html',
styleUrls: ['./users-table.component.scss']
})
-export class UsersTableComponent implements OnInit {
+export class UsersTableComponent implements OnInit, AfterViewInit {
- public columnMode = ColumnMode.force;
- public rows: User[] = [];
- public messages = {
- emptyMessage: 'TABLE.NO_DATE',
- totalMessage: 'TABLE.TOTAL',
- selectedMessage: 'TABLE.SELECTED'
- }
+ public readonly displayedColumns = ['username', 'fullname', 'email', 'status', 'created'];
+ public dataSource = new MatTableDataSource();
+ @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
constructor(private userService: UserService) { }
+ ngAfterViewInit(): void {
+ this.dataSource.paginator = this.paginator;
+ }
+
ngOnInit() {
this.userService.getUsers().toPromise().then((users: User[]) => {
- this.rows = users;
+ this.dataSource.data = users;
}).catch((err) => console.error(err));
}
From d352cb2221e17460f3eaad7e649b681035026e9c Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Tue, 29 Mar 2022 22:08:01 +0200
Subject: [PATCH 12/32] striped and resized rows
---
src/app/components/users-table/users-table.component.html | 2 +-
src/app/components/users-table/users-table.component.scss | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index 27f938b..dc0e555 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -45,7 +45,7 @@
-
+
Date: Thu, 31 Mar 2022 23:11:41 +0200
Subject: [PATCH 13/32] blocked out and styled create user component
imported required angular modules, created post method in service, added in some global styling files, made form responsive
---
src/app/app.module.ts | 11 +++++-
.../create-user/create-user.component.html | 30 ++++++++++++++-
.../create-user/create-user.component.scss | 37 +++++++++++++++++++
.../create-user/create-user.component.ts | 26 ++++++++++++-
.../users-table/users-table.component.html | 5 ++-
.../users-table/users-table.component.scss | 6 ++-
.../users-table/users-table.component.ts | 8 +++-
src/app/services/routing.service.ts | 2 +-
src/app/services/user.service.ts | 4 ++
src/global-styling/flex.scss | 24 ++++++++++++
src/global-styling/variables.scss | 2 +
src/styles.scss | 6 +++
12 files changed, 153 insertions(+), 8 deletions(-)
create mode 100644 src/global-styling/flex.scss
create mode 100644 src/global-styling/variables.scss
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index f17b3fc..2db2ee8 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -7,7 +7,9 @@ import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { UsersTableComponent } from './components/users-table/users-table.component';
import { CreateUserComponent } from './components/create-user/create-user.component';
-import { MatPaginatorModule, MatTableModule } from '@angular/material';
+import { MatFormFieldModule, MatInput, MatInputModule, MatPaginatorModule, MatSelect, MatSelectModule, MatTableModule } from '@angular/material';
+import { MatButtonModule } from '@angular/material/button';
+import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
@@ -21,7 +23,12 @@ import { MatPaginatorModule, MatTableModule } from '@angular/material';
BrowserAnimationsModule,
HttpClientModule,
MatTableModule,
- MatPaginatorModule
+ MatPaginatorModule,
+ MatButtonModule,
+ MatFormFieldModule,
+ MatInputModule,
+ MatSelectModule,
+ ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
index cec559f..c0092ec 100644
--- a/src/app/components/create-user/create-user.component.html
+++ b/src/app/components/create-user/create-user.component.html
@@ -1 +1,29 @@
-create-user works!
+
+
CREATE_USER.TITLE
+
+
+
+
+
+
+
diff --git a/src/app/components/create-user/create-user.component.scss b/src/app/components/create-user/create-user.component.scss
index e69de29..a1db228 100644
--- a/src/app/components/create-user/create-user.component.scss
+++ b/src/app/components/create-user/create-user.component.scss
@@ -0,0 +1,37 @@
+h2 {
+ margin-top: 50px;
+ margin-left: 30px;
+ text-transform: capitalize;
+}
+.main-container {
+ background-color: rgb(231, 231, 231);
+ height: 100vh;
+
+ .container-inner {
+ margin-left: 30px;
+ margin-right: 30px;
+ padding: 20px;
+ background-color: white;
+ }
+}
+.inputs {
+ flex-grow: 1;
+}
+
+.buttons {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+mat-form-field {
+ padding-left: 10px;
+ padding-right: 10px;
+ width: 100%;
+}
+
+::ng-deep label.mat-form-field-label {
+
+ span {
+ text-transform: capitalize !important;
+ }
+}
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index 3e04481..e5af060 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { User } from 'src/app/models/user.model';
+import { UserService } from './../../services/user.service';
@Component({
selector: 'exads-create-user',
@@ -7,9 +10,30 @@ import { Component, OnInit } from '@angular/core';
})
export class CreateUserComponent implements OnInit {
- constructor() { }
+ public newUser: User;
+ public newUserForm: FormGroup = new FormGroup({
+ firstName: new FormControl('firstName'),
+ lastName: new FormControl('lastName'),
+ userName: new FormControl('userName'),
+ email: new FormControl('email')
+}); ;
+
+ email = new FormControl('', [Validators.required, Validators.email]);
+ constructor(private userService: UserService) { }
ngOnInit() {
}
+ public cancel(): void {
+ // navigate back
+ }
+
+ public addNewUser(): void {
+ this.userService.postUser(this.newUser).toPromise().then((success)=>{
+ // display toast
+ },
+ (error)=>{
+ // display toast
+ });
+ }
}
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index dc0e555..fdd0374 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1,5 +1,6 @@
-
+
+
USERS.TABLE.USERNAME
@@ -47,9 +48,11 @@
+
+
diff --git a/src/app/components/users-table/users-table.component.scss b/src/app/components/users-table/users-table.component.scss
index a02fe5a..59cec08 100644
--- a/src/app/components/users-table/users-table.component.scss
+++ b/src/app/components/users-table/users-table.component.scss
@@ -13,8 +13,12 @@
}
.mat-row {
- min-height: 10px;
+ min-height: 20px;
}
.mat-row:nth-child(even) {
background-color: #f1f1f1;
}
+
+// .mat-column-created {
+// flex: 0 0 35% !important;
+// }
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index c1947ec..b5d8e8f 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,3 +1,4 @@
+import { RoutingService } from './../../services/routing.service';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { User } from 'src/app/models/user.model';
import { UserService } from './../../services/user.service';
@@ -13,7 +14,8 @@ export class UsersTableComponent implements OnInit, AfterViewInit {
public readonly displayedColumns = ['username', 'fullname', 'email', 'status', 'created'];
public dataSource = new MatTableDataSource();
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
- constructor(private userService: UserService) { }
+ constructor(private userService: UserService,
+ private routingService: RoutingService) { }
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
@@ -25,4 +27,8 @@ export class UsersTableComponent implements OnInit, AfterViewInit {
}).catch((err) => console.error(err));
}
+ public navigateToCreateUser(): void {
+ this.routingService.navigateToCreateUser();
+ }
+
}
diff --git a/src/app/services/routing.service.ts b/src/app/services/routing.service.ts
index 6c5ef31..38c11c1 100644
--- a/src/app/services/routing.service.ts
+++ b/src/app/services/routing.service.ts
@@ -10,7 +10,7 @@ export class RoutingService {
constructor(private router: Router) { }
public navigateToCreateUser(): void {
- this.router.navigateByUrl(APP_ROUTES.USERS);
+ this.router.navigateByUrl(APP_ROUTES.CREATE_USER);
}
}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index 3685080..2ed277a 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -18,4 +18,8 @@ export class UserService {
return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS)
.pipe(map((response: UsersResponse) => {return response.data.users}));
}
+
+ public postUser(newUser: User): Observable {
+ return this.http.post(environment.apiBaseUrl + '/' + API_ROUTES.USERS, newUser);
+ }
}
diff --git a/src/global-styling/flex.scss b/src/global-styling/flex.scss
new file mode 100644
index 0000000..a1f632f
--- /dev/null
+++ b/src/global-styling/flex.scss
@@ -0,0 +1,24 @@
+
+.flex {
+ display: flex;
+
+ &.column {
+ flex-direction: column;
+ }
+
+ &.space-between {
+ justify-content: space-between;
+ }
+ // style overrides for "sm" breakpoint
+ .sm {
+ // breakpont
+ @media only screen and (max-width: $small) {
+ &-column {
+ flex-direction: column;
+ }
+ }
+
+ }
+}
+
+
diff --git a/src/global-styling/variables.scss b/src/global-styling/variables.scss
new file mode 100644
index 0000000..8cad78f
--- /dev/null
+++ b/src/global-styling/variables.scss
@@ -0,0 +1,2 @@
+// sttyling breakpoints
+$small: 600px;
diff --git a/src/styles.scss b/src/styles.scss
index ad56e3e..cb6e519 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -1,3 +1,9 @@
+// angular material theming
@import '../node_modules/@swimlane/ngx-datatable/src/themes/material.scss';
+@import "~@angular/material/prebuilt-themes/indigo-pink.css";
+// project specific global stylings
+@import "global-styling/variables.scss";
+@import "global-styling/flex.scss";
+
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
From 698a48fa21399562cb3ecc820c6319f5c882ee24 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 18:47:14 +0200
Subject: [PATCH 14/32] added validation to fields
added username validation and email validation, required validation, navigation back to previous page
---
.../create-user/create-user.component.html | 23 +++++++----
.../create-user/create-user.component.scss | 8 +++-
.../create-user/create-user.component.ts | 38 +++++++++++++------
src/app/services/routing.service.ts | 6 ++-
src/app/validators/user-name-validator.ts | 11 ++++++
5 files changed, 64 insertions(+), 22 deletions(-)
create mode 100644 src/app/validators/user-name-validator.ts
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
index c0092ec..575617e 100644
--- a/src/app/components/create-user/create-user.component.html
+++ b/src/app/components/create-user/create-user.component.html
@@ -2,28 +2,35 @@
CREATE_USER.TITLE
-
+
diff --git a/src/app/components/create-user/create-user.component.scss b/src/app/components/create-user/create-user.component.scss
index a1db228..afa2d77 100644
--- a/src/app/components/create-user/create-user.component.scss
+++ b/src/app/components/create-user/create-user.component.scss
@@ -12,8 +12,14 @@ h2 {
margin-right: 30px;
padding: 20px;
background-color: white;
+ border: 1px solid #808080a6;
}
}
+
+#first-name {
+ margin-right: 20px;
+ }
+
.inputs {
flex-grow: 1;
}
@@ -24,8 +30,6 @@ h2 {
}
mat-form-field {
- padding-left: 10px;
- padding-right: 10px;
width: 100%;
}
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index e5af060..856e81e 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,7 +1,9 @@
+import { RoutingService } from './../../services/routing.service';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from 'src/app/models/user.model';
import { UserService } from './../../services/user.service';
+import { userNameValidator } from 'src/app/validators/user-name-validator';
@Component({
selector: 'exads-create-user',
@@ -12,28 +14,42 @@ export class CreateUserComponent implements OnInit {
public newUser: User;
public newUserForm: FormGroup = new FormGroup({
- firstName: new FormControl('firstName'),
- lastName: new FormControl('lastName'),
- userName: new FormControl('userName'),
- email: new FormControl('email')
-}); ;
+ firstName: new FormControl('', [Validators.required]),
+ lastName: new FormControl('', []),
+ userName: new FormControl('', [Validators.required, Validators.maxLength(20), Validators.minLength(3), userNameValidator()]),
+ email: new FormControl('', [Validators.required, Validators.email,])
+ });;
email = new FormControl('', [Validators.required, Validators.email]);
- constructor(private userService: UserService) { }
+ constructor(private userService: UserService, private routingService: RoutingService) { }
ngOnInit() {
+ console.log(this.newUserForm)
}
public cancel(): void {
- // navigate back
+ this.routingService.navigateToUsersTable();
}
public addNewUser(): void {
- this.userService.postUser(this.newUser).toPromise().then((success)=>{
+ this.userService.postUser(this.newUser).toPromise().then((success) => {
// display toast
},
- (error)=>{
- // display toast
- });
+ (error) => {
+ // display toast
+ });
+ }
+
+ public invalidData(): boolean {
+ return true;
+ }
+
+ public checkForError(controlName: string, errorName: string): boolean {
+ return this.newUserForm.controls[controlName].hasError(errorName);
+ }
+
+ public getErrors(controlName: string): void {
+ console.log("errors for: ", controlName);
+ console.log(this.newUserForm.controls[controlName].errors);
}
}
diff --git a/src/app/services/routing.service.ts b/src/app/services/routing.service.ts
index 38c11c1..e257124 100644
--- a/src/app/services/routing.service.ts
+++ b/src/app/services/routing.service.ts
@@ -10,7 +10,11 @@ export class RoutingService {
constructor(private router: Router) { }
public navigateToCreateUser(): void {
- this.router.navigateByUrl(APP_ROUTES.CREATE_USER);
+ this.router.navigateByUrl(APP_ROUTES.CREATE_USER);
+ }
+
+ public navigateToUsersTable(): void {
+ this.router.navigateByUrl(APP_ROUTES.USERS);
}
}
diff --git a/src/app/validators/user-name-validator.ts b/src/app/validators/user-name-validator.ts
new file mode 100644
index 0000000..9b1a375
--- /dev/null
+++ b/src/app/validators/user-name-validator.ts
@@ -0,0 +1,11 @@
+import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
+
+export function userNameValidator(): ValidatorFn {
+ return (control: AbstractControl): ValidationErrors | null => {
+ const userName = control.value;
+ if (!userName) {
+ return null;
+ }
+ return /[(){}".![\]]+/.test(userName) ? { invalidCharacter: true } : null;
+ }
+}
From b503f082ed132db8c259b47e7688c9eff57be599 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 18:56:56 +0200
Subject: [PATCH 15/32] updated disabled logic for create button
---
.../create-user/create-user.component.html | 6 +++---
.../components/create-user/create-user.component.ts | 9 +++++----
src/app/services/user.service.ts | 12 ++++++++++--
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
index 575617e..a3eb61b 100644
--- a/src/app/components/create-user/create-user.component.html
+++ b/src/app/components/create-user/create-user.component.html
@@ -2,9 +2,9 @@
CREATE_USER.TITLE
-
-
+
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index 856e81e..a8bf2b2 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,3 +1,4 @@
+import { Observable } from 'rxjs';
import { RoutingService } from './../../services/routing.service';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@@ -40,10 +41,6 @@ export class CreateUserComponent implements OnInit {
});
}
- public invalidData(): boolean {
- return true;
- }
-
public checkForError(controlName: string, errorName: string): boolean {
return this.newUserForm.controls[controlName].hasError(errorName);
}
@@ -52,4 +49,8 @@ export class CreateUserComponent implements OnInit {
console.log("errors for: ", controlName);
console.log(this.newUserForm.controls[controlName].errors);
}
+
+ public checkIfUsernameExists(userName: string): Observable {
+ return this.userService.getByUsername(userName);
+ }
}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index 2ed277a..cbbbbdd 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -1,4 +1,4 @@
-import { HttpClient } from '@angular/common/http';
+import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -16,10 +16,18 @@ export class UserService {
public getUsers(): Observable {
return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS)
- .pipe(map((response: UsersResponse) => {return response.data.users}));
+ .pipe(map((response: UsersResponse) => { return response.data.users }));
}
public postUser(newUser: User): Observable {
return this.http.post(environment.apiBaseUrl + '/' + API_ROUTES.USERS, newUser);
}
+
+ public getByUsername(username: string): Observable {
+ let queryParams = new HttpParams();
+ queryParams = queryParams.append("username", username);
+ return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS,{params:queryParams})
+
+ }
}
+
From ea54ede2a9b2ed62d50db14e3ef2a3c134f13f64 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 19:09:30 +0200
Subject: [PATCH 16/32] added in test for existing user
---
.../create-user/create-user.component.ts | 28 +++++++++++++------
src/app/responses/users.response.ts | 6 ++--
src/app/services/user.service.ts | 5 ++--
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index a8bf2b2..8a027a3 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,3 +1,4 @@
+import { UsersResponse } from './../../responses/users.response';
import { Observable } from 'rxjs';
import { RoutingService } from './../../services/routing.service';
import { Component, OnInit } from '@angular/core';
@@ -33,6 +34,24 @@ export class CreateUserComponent implements OnInit {
}
public addNewUser(): void {
+ const userForPost = {
+ firstName: this.newUserForm.get("firstName").value,
+ lastName: this.newUserForm.get("lastName").value,
+ userName: this.newUserForm.get("userName").value,
+ email: this.newUserForm.get("email").value
+ }
+ this.userService.getByUsername(userForPost.userName).toPromise().then((result: UsersResponse) => {
+ if (result && result.data && result.data.count > 0) {
+ // abort, with user exists warning
+ } else {
+ this.postUser(userForPost);
+ }
+ }).catch((err) => {
+ // show error toast
+ });
+ }
+
+ private postUser(userForPost: { firstName: any; lastName: any; userName: any; email: any; }) {
this.userService.postUser(this.newUser).toPromise().then((success) => {
// display toast
},
@@ -44,13 +63,4 @@ export class CreateUserComponent implements OnInit {
public checkForError(controlName: string, errorName: string): boolean {
return this.newUserForm.controls[controlName].hasError(errorName);
}
-
- public getErrors(controlName: string): void {
- console.log("errors for: ", controlName);
- console.log(this.newUserForm.controls[controlName].errors);
- }
-
- public checkIfUsernameExists(userName: string): Observable {
- return this.userService.getByUsername(userName);
- }
}
diff --git a/src/app/responses/users.response.ts b/src/app/responses/users.response.ts
index 26e1e91..355fb25 100644
--- a/src/app/responses/users.response.ts
+++ b/src/app/responses/users.response.ts
@@ -1,6 +1,8 @@
import { User } from '../models/user.model';
import { ApiResponse } from './../interfaces/api-response.interface';
export class UsersResponse implements ApiResponse {
- data: { count?: number;
- users: User[] };
+ public data: {
+ count: number;
+ users: User[];
+ };
}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index cbbbbdd..0cc6295 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -23,10 +23,11 @@ export class UserService {
return this.http.post(environment.apiBaseUrl + '/' + API_ROUTES.USERS, newUser);
}
- public getByUsername(username: string): Observable {
+ public getByUsername(username: string): Observable {
+ //?username = {{ username }
let queryParams = new HttpParams();
queryParams = queryParams.append("username", username);
- return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS,{params:queryParams})
+ return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS,{params:queryParams})
}
}
From 72ebcf7c824301a9c7d0f31e43e5ef01d7c186da Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 19:24:16 +0200
Subject: [PATCH 17/32] post user works, checking if user exists works
---
.../create-user/create-user.component.ts | 38 +++++++++----------
src/app/interfaces/user.interface.ts | 7 ++++
src/app/models/user.model.ts | 3 +-
src/app/requests/user.request.ts | 7 ++++
src/app/services/user.service.ts | 5 ++-
5 files changed, 37 insertions(+), 23 deletions(-)
create mode 100644 src/app/interfaces/user.interface.ts
create mode 100644 src/app/requests/user.request.ts
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index 8a027a3..a72ab04 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,20 +1,19 @@
+import { Component } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { userNameValidator } from 'src/app/validators/user-name-validator';
+import { UserRequest } from './../../requests/user.request';
import { UsersResponse } from './../../responses/users.response';
-import { Observable } from 'rxjs';
import { RoutingService } from './../../services/routing.service';
-import { Component, OnInit } from '@angular/core';
-import { FormControl, FormGroup, Validators } from '@angular/forms';
-import { User } from 'src/app/models/user.model';
import { UserService } from './../../services/user.service';
-import { userNameValidator } from 'src/app/validators/user-name-validator';
@Component({
selector: 'exads-create-user',
templateUrl: './create-user.component.html',
styleUrls: ['./create-user.component.scss']
})
-export class CreateUserComponent implements OnInit {
+export class CreateUserComponent {
- public newUser: User;
+ public newUser: UserRequest = new UserRequest();
public newUserForm: FormGroup = new FormGroup({
firstName: new FormControl('', [Validators.required]),
lastName: new FormControl('', []),
@@ -25,33 +24,32 @@ export class CreateUserComponent implements OnInit {
email = new FormControl('', [Validators.required, Validators.email]);
constructor(private userService: UserService, private routingService: RoutingService) { }
- ngOnInit() {
- console.log(this.newUserForm)
- }
-
public cancel(): void {
this.routingService.navigateToUsersTable();
}
public addNewUser(): void {
- const userForPost = {
- firstName: this.newUserForm.get("firstName").value,
- lastName: this.newUserForm.get("lastName").value,
- userName: this.newUserForm.get("userName").value,
- email: this.newUserForm.get("email").value
- }
- this.userService.getByUsername(userForPost.userName).toPromise().then((result: UsersResponse) => {
+ this.userService.getByUsername(this.newUserForm.get("userName").value).toPromise().then((result: UsersResponse) => {
+ debugger;
if (result && result.data && result.data.count > 0) {
// abort, with user exists warning
} else {
- this.postUser(userForPost);
+ this.assignDataToNewUser();
+ this.postUser();
}
}).catch((err) => {
// show error toast
});
}
+ public assignDataToNewUser(): void {
+ this.newUser.first_name = this.newUserForm.get("firstName").value;
+ this.newUser.last_name = this.newUserForm.get("lastName").value;
+ this.newUser.username = this.newUserForm.get("userName").value;
+ this.newUser.email = this.newUserForm.get("email").value;
+ this.newUser.id_status = 1;
+ }
- private postUser(userForPost: { firstName: any; lastName: any; userName: any; email: any; }) {
+ private postUser() {
this.userService.postUser(this.newUser).toPromise().then((success) => {
// display toast
},
diff --git a/src/app/interfaces/user.interface.ts b/src/app/interfaces/user.interface.ts
new file mode 100644
index 0000000..f2fd4a7
--- /dev/null
+++ b/src/app/interfaces/user.interface.ts
@@ -0,0 +1,7 @@
+export interface IUser {
+ first_name: string;
+ last_name: string;
+ email: string;
+ username: string;
+ id_status: string;
+}
diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts
index 845b39a..e1010b1 100644
--- a/src/app/models/user.model.ts
+++ b/src/app/models/user.model.ts
@@ -1,4 +1,5 @@
-export class User {
+import { IUser } from 'src/app/interfaces/user.interface';
+export class User implements IUser {
public id: number;
public first_name: string;
public last_name: string;
diff --git a/src/app/requests/user.request.ts b/src/app/requests/user.request.ts
new file mode 100644
index 0000000..f7f8d6e
--- /dev/null
+++ b/src/app/requests/user.request.ts
@@ -0,0 +1,7 @@
+export class UserRequest {
+ public first_name: string;
+ public last_name: string;
+ public email: string;
+ public username: string;
+ public id_status: number;
+}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index 0cc6295..4744ce9 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -1,3 +1,4 @@
+import { UserRequest } from './../requests/user.request';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@@ -19,8 +20,8 @@ export class UserService {
.pipe(map((response: UsersResponse) => { return response.data.users }));
}
- public postUser(newUser: User): Observable {
- return this.http.post(environment.apiBaseUrl + '/' + API_ROUTES.USERS, newUser);
+ public postUser(newUser: UserRequest): Observable {
+ return this.http.post(environment.apiBaseUrl + '/' + API_ROUTES.USERS, {user: newUser});
}
public getByUsername(username: string): Observable {
From b8b29a25f0a4b21a304252d1d954c9fe6ae7fcf3 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 19:39:48 +0200
Subject: [PATCH 18/32] made table responsive
---
.../users-table/users-table.component.html | 4 ++--
.../users-table/users-table.component.ts | 18 ++++++++++++------
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index fdd0374..12cf660 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -45,8 +45,8 @@
-
-
+
+
();
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
constructor(private userService: UserService,
@@ -21,12 +23,16 @@ export class UsersTableComponent implements OnInit, AfterViewInit {
this.dataSource.paginator = this.paginator;
}
- ngOnInit() {
+ ngOnInit(): void {
this.userService.getUsers().toPromise().then((users: User[]) => {
this.dataSource.data = users;
}).catch((err) => console.error(err));
}
+ ngAfterContentChecked(): void {
+ this.isMobile = window.innerWidth <= 600;
+ }
+
public navigateToCreateUser(): void {
this.routingService.navigateToCreateUser();
}
From f800fb2f898b789e9403b9bd1dc0e28866be69d8 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 20:03:05 +0200
Subject: [PATCH 19/32] created loading service with http interceptor
---
src/app/app.component.html | 4 ++-
src/app/app.component.ts | 3 ++-
src/app/app.module.ts | 27 ++++++++++++---------
src/app/interceptors/loading.interceptor.ts | 25 +++++++++++++++++++
src/app/services/loading.service.spec.ts | 12 +++++++++
src/app/services/loading.service.ts | 20 +++++++++++++++
6 files changed, 78 insertions(+), 13 deletions(-)
create mode 100644 src/app/interceptors/loading.interceptor.ts
create mode 100644 src/app/services/loading.service.spec.ts
create mode 100644 src/app/services/loading.service.ts
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 90c6b64..6e9e90f 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1 +1,3 @@
-
\ No newline at end of file
+{{'APP.TITLE'}}
+
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 80c2eaf..34855c9 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,3 +1,4 @@
+import { LoadingService } from './services/loading.service';
import { Component } from '@angular/core';
@Component({
@@ -7,6 +8,6 @@ import { Component } from '@angular/core';
})
export class AppComponent {
- constructor() {
+ constructor(public loadingService: LoadingService) {
}
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2db2ee8..cbf5fcf 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,22 +1,23 @@
-import { HttpClient, HttpClientModule } from '@angular/common/http';
-import { BrowserModule } from '@angular/platform-browser';
+import { LoadingInterceptor } from './interceptors/loading.interceptor';
+import { HttpClientModule, HTTP_INTERCEPTORS, HttpInterceptor } from '@angular/common/http';
import { NgModule } from '@angular/core';
-
+import { ReactiveFormsModule } from '@angular/forms';
+import { MatFormFieldModule, MatInputModule, MatPaginatorModule, MatProgressBarModule, MatSelectModule, MatTableModule, MatToolbarModule } from '@angular/material';
+import { MatButtonModule } from '@angular/material/button';
+import { BrowserModule } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { UsersTableComponent } from './components/users-table/users-table.component';
import { CreateUserComponent } from './components/create-user/create-user.component';
-import { MatFormFieldModule, MatInput, MatInputModule, MatPaginatorModule, MatSelect, MatSelectModule, MatTableModule } from '@angular/material';
-import { MatButtonModule } from '@angular/material/button';
-import { ReactiveFormsModule } from '@angular/forms';
+import { UsersTableComponent } from './components/users-table/users-table.component';
+
@NgModule({
declarations: [
AppComponent,
UsersTableComponent,
CreateUserComponent
- ],
+ ],
imports: [
BrowserModule,
AppRoutingModule,
@@ -28,9 +29,13 @@ import { ReactiveFormsModule } from '@angular/forms';
MatFormFieldModule,
MatInputModule,
MatSelectModule,
- ReactiveFormsModule
+ ReactiveFormsModule,
+ MatToolbarModule,
+ MatProgressBarModule
+ ],
+ providers: [
+ { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true }
],
- providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
diff --git a/src/app/interceptors/loading.interceptor.ts b/src/app/interceptors/loading.interceptor.ts
new file mode 100644
index 0000000..ae5f5c7
--- /dev/null
+++ b/src/app/interceptors/loading.interceptor.ts
@@ -0,0 +1,25 @@
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { tap } from 'rxjs/operators';
+import { LoadingService } from './../services/loading.service';
+
+
+@Injectable()
+export class LoadingInterceptor implements HttpInterceptor {
+
+ constructor(private loadingService: LoadingService) { }
+
+ intercept(req: HttpRequest, next: HttpHandler): Observable> {
+ debugger;
+ this.loadingService.setLoading(true);
+ return next.handle(req)
+ .pipe(
+ tap(event => {
+ debugger;
+ this.loadingService.setLoading(false);
+ })
+ );
+
+ }
+}
diff --git a/src/app/services/loading.service.spec.ts b/src/app/services/loading.service.spec.ts
new file mode 100644
index 0000000..b6518ad
--- /dev/null
+++ b/src/app/services/loading.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { LoadingService } from './loading.service';
+
+describe('LoadingService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: LoadingService = TestBed.get(LoadingService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/services/loading.service.ts b/src/app/services/loading.service.ts
new file mode 100644
index 0000000..1585dfc
--- /dev/null
+++ b/src/app/services/loading.service.ts
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import { BehaviorSubject, Subject } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LoadingService {
+
+ private _isLoading: BehaviorSubject = new BehaviorSubject(false);
+
+ constructor() { }
+
+ public isLoading(): boolean {
+ return this._isLoading.getValue();
+ }
+
+ public setLoading(loading: boolean){
+ this._isLoading.next(loading);
+ }
+}
From f27b5492f9d26556cb706f4baef0b5b20065ebb0 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 20:16:41 +0200
Subject: [PATCH 20/32] only show progress bar on laod
and also don't display pagination on mobile
---
src/app/app.component.ts | 2 +-
.../users-table/users-table.component.html | 2 +-
src/app/interceptors/loading.interceptor.ts | 12 +++++++-----
src/app/services/loading.service.ts | 2 +-
4 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 34855c9..66d0170 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,5 +1,5 @@
-import { LoadingService } from './services/loading.service';
import { Component } from '@angular/core';
+import { LoadingService } from './services/loading.service';
@Component({
selector: 'exads-root',
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index 12cf660..cb29537 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -49,7 +49,7 @@
-
diff --git a/src/app/interceptors/loading.interceptor.ts b/src/app/interceptors/loading.interceptor.ts
index ae5f5c7..6e2f420 100644
--- a/src/app/interceptors/loading.interceptor.ts
+++ b/src/app/interceptors/loading.interceptor.ts
@@ -1,7 +1,7 @@
-import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
-import { tap } from 'rxjs/operators';
+import { tap, map } from 'rxjs/operators';
import { LoadingService } from './../services/loading.service';
@@ -15,9 +15,11 @@ export class LoadingInterceptor implements HttpInterceptor {
this.loadingService.setLoading(true);
return next.handle(req)
.pipe(
- tap(event => {
- debugger;
- this.loadingService.setLoading(false);
+ map((event) => {
+ if(event && event.hasOwnProperty('url')){
+ this.loadingService.setLoading(false);
+ }
+ return event;
})
);
diff --git a/src/app/services/loading.service.ts b/src/app/services/loading.service.ts
index 1585dfc..007f86d 100644
--- a/src/app/services/loading.service.ts
+++ b/src/app/services/loading.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { BehaviorSubject, Subject } from 'rxjs';
+import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
From b2c4165ede742613819f848a95f36912eb380b5a Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 20:43:46 +0200
Subject: [PATCH 21/32] Fixed expressionChanged error for loading
added custom translation keys to mat paginator
placed paginator on top of table
---
src/app/app.component.html | 2 +-
src/app/app.component.ts | 24 +++++++++++++++++--
src/app/app.module.ts | 6 +++--
.../create-user/create-user.component.html | 2 +-
.../create-user/create-user.component.ts | 4 ++--
.../users-table/users-table.component.html | 12 +++++-----
src/app/interceptors/loading.interceptor.ts | 2 +-
src/app/mat-helpers/custom-mat-pager-intl.ts | 14 +++++++++++
src/app/services/loading.service.ts | 6 ++++-
src/app/validators/email.validator.ts | 8 +++++++
10 files changed, 64 insertions(+), 16 deletions(-)
create mode 100644 src/app/mat-helpers/custom-mat-pager-intl.ts
create mode 100644 src/app/validators/email.validator.ts
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 6e9e90f..b2d0dfa 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,3 +1,3 @@
{{'APP.TITLE'}}
-
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 66d0170..e701d0b 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,4 +1,5 @@
-import { Component } from '@angular/core';
+import { AfterViewInit, Component, OnDestroy } from '@angular/core';
+import { Subscription } from 'rxjs';
import { LoadingService } from './services/loading.service';
@Component({
@@ -6,8 +7,27 @@ import { LoadingService } from './services/loading.service';
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
-export class AppComponent {
+export class AppComponent implements AfterViewInit, OnDestroy {
+ private subscriptions: Subscription[] = [];
+ public isLoading: boolean = false;
constructor(public loadingService: LoadingService) {
}
+ ngAfterViewInit(): void {
+ // short timeout to prevent ExpressionChanged errors
+ setTimeout(() => {
+ this.subscriptions.push(
+ this.loadingService.loading().subscribe((loading) => {
+ debugger;
+ this.isLoading = loading;
+ })
+ );
+ }, 100)
+ }
+
+ ngOnDestroy(): void {
+ this.subscriptions.forEach(sub => {
+ sub.unsubscribe();
+ });
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index cbf5fcf..2b2dbc2 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -2,7 +2,7 @@ import { LoadingInterceptor } from './interceptors/loading.interceptor';
import { HttpClientModule, HTTP_INTERCEPTORS, HttpInterceptor } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
-import { MatFormFieldModule, MatInputModule, MatPaginatorModule, MatProgressBarModule, MatSelectModule, MatTableModule, MatToolbarModule } from '@angular/material';
+import { MatFormFieldModule, MatInputModule, MatPaginatorIntl, MatPaginatorModule, MatProgressBarModule, MatSelectModule, MatTableModule, MatToolbarModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@@ -10,6 +10,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CreateUserComponent } from './components/create-user/create-user.component';
import { UsersTableComponent } from './components/users-table/users-table.component';
+import { CustomMatPagerIntl } from './mat-helpers/custom-mat-pager-intl';
@NgModule({
@@ -34,7 +35,8 @@ import { UsersTableComponent } from './components/users-table/users-table.compon
MatProgressBarModule
],
providers: [
- { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true }
+ { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true },
+ { provide: MatPaginatorIntl, useClass: CustomMatPagerIntl}
],
bootstrap: [AppComponent]
})
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
index a3eb61b..78d3869 100644
--- a/src/app/components/create-user/create-user.component.html
+++ b/src/app/components/create-user/create-user.component.html
@@ -21,7 +21,7 @@ CREATE_USER.TITLE
- {{'FORM.USER.INVALID_INPUT'}}
+ {{'FORM.USER.INVALID_INPUT'}}
{{'INPUT.VALIDATION.EMAIL_REQUIRED'}}
{{'INPUT.VALIDATION.TOO_LONG'}}
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index a72ab04..0736c79 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { emailValidator } from 'src/app/validators/email.validator';
import { userNameValidator } from 'src/app/validators/user-name-validator';
import { UserRequest } from './../../requests/user.request';
import { UsersResponse } from './../../responses/users.response';
@@ -18,10 +19,9 @@ export class CreateUserComponent {
firstName: new FormControl('', [Validators.required]),
lastName: new FormControl('', []),
userName: new FormControl('', [Validators.required, Validators.maxLength(20), Validators.minLength(3), userNameValidator()]),
- email: new FormControl('', [Validators.required, Validators.email,])
+ email: new FormControl('', [Validators.required, emailValidator()])
});;
- email = new FormControl('', [Validators.required, Validators.email]);
constructor(private userService: UserService, private routingService: RoutingService) { }
public cancel(): void {
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index cb29537..6b724cb 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1,5 +1,11 @@
+
+
USERS.TABLE.USERNAME
@@ -49,10 +55,4 @@
-
-
-
diff --git a/src/app/interceptors/loading.interceptor.ts b/src/app/interceptors/loading.interceptor.ts
index 6e2f420..574f5c5 100644
--- a/src/app/interceptors/loading.interceptor.ts
+++ b/src/app/interceptors/loading.interceptor.ts
@@ -17,7 +17,7 @@ export class LoadingInterceptor implements HttpInterceptor {
.pipe(
map((event) => {
if(event && event.hasOwnProperty('url')){
- this.loadingService.setLoading(false);
+ this.loadingService.setLoading(false)
}
return event;
})
diff --git a/src/app/mat-helpers/custom-mat-pager-intl.ts b/src/app/mat-helpers/custom-mat-pager-intl.ts
new file mode 100644
index 0000000..c29dca0
--- /dev/null
+++ b/src/app/mat-helpers/custom-mat-pager-intl.ts
@@ -0,0 +1,14 @@
+import { Injectable } from "@angular/core";
+import { MatPaginatorIntl } from "@angular/material";
+
+@Injectable()
+export class CustomMatPagerIntl extends MatPaginatorIntl {
+ itemsPerPageLabel = 'MAT.PAGINATOR.ITEMS_PER_PAGE';
+ nextPageLabel = 'MAT.PAGINATOR.NEXT';
+ previousPageLabel = 'MAT.PAGINATOR.PREV';
+ ofLabel = 'MAT.PAGINATOR.PREV';
+
+ getRangeLabel = (page: number, pageSize: number, length: number) => {
+ return page + " - " + pageSize + " " + this.ofLabel + " - " + length;
+ };
+}
diff --git a/src/app/services/loading.service.ts b/src/app/services/loading.service.ts
index 007f86d..aca9e0c 100644
--- a/src/app/services/loading.service.ts
+++ b/src/app/services/loading.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { BehaviorSubject } from 'rxjs';
+import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
@@ -17,4 +17,8 @@ export class LoadingService {
public setLoading(loading: boolean){
this._isLoading.next(loading);
}
+
+ public loading(): Observable {
+ return this._isLoading.asObservable();
+ }
}
diff --git a/src/app/validators/email.validator.ts b/src/app/validators/email.validator.ts
new file mode 100644
index 0000000..d9e4dcc
--- /dev/null
+++ b/src/app/validators/email.validator.ts
@@ -0,0 +1,8 @@
+import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
+
+export function emailValidator(): ValidatorFn {
+ return (control: AbstractControl): ValidationErrors | null => {
+ const email = control.value;
+ return !email || /\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b/.test(email) ? null: { invalidEmail: true };
+ }
+}
From 739dbdef9dab34ba32b42fab83a74d978d283e81 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Fri, 1 Apr 2022 21:43:47 +0200
Subject: [PATCH 22/32] finished styling paginator
---
src/app/app.component.html | 2 +-
src/app/app.component.ts | 1 -
.../create-user/create-user.component.ts | 1 -
.../users-table/users-table.component.html | 13 ++++----
.../users-table/users-table.component.scss | 28 +++++++++++------
.../users-table/users-table.component.ts | 31 +++++++++++++++++--
src/app/interceptors/loading.interceptor.ts | 5 ++-
src/app/mat-helpers/custom-mat-pager-intl.ts | 6 ++--
8 files changed, 61 insertions(+), 26 deletions(-)
diff --git a/src/app/app.component.html b/src/app/app.component.html
index b2d0dfa..f9cec35 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,3 +1,3 @@
-{{'APP.TITLE'}}
+{{'APP.TITLE'}}
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index e701d0b..296dcb7 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -18,7 +18,6 @@ export class AppComponent implements AfterViewInit, OnDestroy {
setTimeout(() => {
this.subscriptions.push(
this.loadingService.loading().subscribe((loading) => {
- debugger;
this.isLoading = loading;
})
);
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index 0736c79..61fd20c 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -30,7 +30,6 @@ export class CreateUserComponent {
public addNewUser(): void {
this.userService.getByUsername(this.newUserForm.get("userName").value).toPromise().then((result: UsersResponse) => {
- debugger;
if (result && result.data && result.data.count > 0) {
// abort, with user exists warning
} else {
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index 6b724cb..be46cb2 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1,11 +1,13 @@
-
+
-
+[pageSizeOptions]="pageSizes"
+[showFirstLastButtons]="true"
+[hidePageSize]="false"
+(page)="handlePageEvent($event)">
+
USERS.TABLE.USERNAME
@@ -54,5 +56,4 @@
-
diff --git a/src/app/components/users-table/users-table.component.scss b/src/app/components/users-table/users-table.component.scss
index 59cec08..83731c3 100644
--- a/src/app/components/users-table/users-table.component.scss
+++ b/src/app/components/users-table/users-table.component.scss
@@ -1,9 +1,3 @@
-.user-table-container {
- height: 90vw;
- width: 100%;
- max-height: 95vh;
-}
-
.active {
color: green;
}
@@ -19,6 +13,22 @@
background-color: #f1f1f1;
}
-// .mat-column-created {
-// flex: 0 0 35% !important;
-// }
+::ng-deep #top-paginator {
+
+ .mat-paginator-page-size {
+ display: flex;
+ flex-direction: row-reverse;
+ }
+
+ .mat-paginator-range-actions {
+ position: absolute;
+ bottom: calc(100vh - 713px);
+ width: 100%;
+
+ .mat-paginator-range-label {
+ text-align: left;
+ width: 100%;
+ }
+ }
+}
+
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index 9e3d8dc..0d76883 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,5 +1,5 @@
-import { AfterContentChecked, AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
-import { MatPaginator, MatTableDataSource } from '@angular/material';
+import { AfterContentChecked, AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { MatPaginator, MatTableDataSource, PageEvent } from '@angular/material';
import { User } from 'src/app/models/user.model';
import { RoutingService } from './../../services/routing.service';
import { UserService } from './../../services/user.service';
@@ -13,9 +13,13 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
public readonly fullScreenColumns = ['username', 'fullname', 'email', 'status', 'created'];
public readonly mobileColumns = ['username', 'fullname'];
+ public readonly pageSizes = [5, 10, 20];
public isMobile: boolean;
public dataSource = new MatTableDataSource
();
- @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
+ @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
+
+ @ViewChild('appToolbar', { static: false }) appToolbar: any;
+ @ViewChild('userTableContainer', { static: false }) userTableContainer: ElementRef;
constructor(private userService: UserService,
private routingService: RoutingService) { }
@@ -37,4 +41,25 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
this.routingService.navigateToCreateUser();
}
+ public handlePageEvent(event: PageEvent) {
+ if (event && !!event.pageSize) {
+ setTimeout(()=>{
+ const matPaginatorBottom: Element = document.querySelector('.mat-paginator-range-actions');
+ //@ts-ignore
+ matPaginatorBottom.style.bottom = this.calculateNewBottom(event.pageSize);
+ },60)
+
+ }
+ }
+
+ private calculateNewBottom(pageSize: number) {
+ // if (pageSize == 20)
+ // return (window.innerHeight - 713) + 'px';
+ // else if (pageSize == 10)
+ // return (window.innerHeight - 503) + 'px';
+ // else if (pageSize == 5)
+ // return (window.innerHeight - 398) + 'px';
+ //windows innerHeight - height of component + mat-toolbar height + paginator height
+ return (window.innerHeight - (this.userTableContainer.nativeElement.offsetHeight + 64 + 40)) + 'px'
+ }
}
diff --git a/src/app/interceptors/loading.interceptor.ts b/src/app/interceptors/loading.interceptor.ts
index 574f5c5..acab858 100644
--- a/src/app/interceptors/loading.interceptor.ts
+++ b/src/app/interceptors/loading.interceptor.ts
@@ -1,7 +1,7 @@
-import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
-import { tap, map } from 'rxjs/operators';
+import { map } from 'rxjs/operators';
import { LoadingService } from './../services/loading.service';
@@ -11,7 +11,6 @@ export class LoadingInterceptor implements HttpInterceptor {
constructor(private loadingService: LoadingService) { }
intercept(req: HttpRequest, next: HttpHandler): Observable> {
- debugger;
this.loadingService.setLoading(true);
return next.handle(req)
.pipe(
diff --git a/src/app/mat-helpers/custom-mat-pager-intl.ts b/src/app/mat-helpers/custom-mat-pager-intl.ts
index c29dca0..6b93522 100644
--- a/src/app/mat-helpers/custom-mat-pager-intl.ts
+++ b/src/app/mat-helpers/custom-mat-pager-intl.ts
@@ -6,9 +6,11 @@ export class CustomMatPagerIntl extends MatPaginatorIntl {
itemsPerPageLabel = 'MAT.PAGINATOR.ITEMS_PER_PAGE';
nextPageLabel = 'MAT.PAGINATOR.NEXT';
previousPageLabel = 'MAT.PAGINATOR.PREV';
- ofLabel = 'MAT.PAGINATOR.PREV';
+ showingLabel = 'MAT.PAGINATOR.SHOWING';
+ entriesLabel = 'MAT.PAGINATOR.SHOWING';
getRangeLabel = (page: number, pageSize: number, length: number) => {
- return page + " - " + pageSize + " " + this.ofLabel + " - " + length;
+ // showing 1 - 16 / 16 entires
+ return this.showingLabel.concat(" ", page.toString(), " - ", pageSize.toString(), "/", length.toString(), " ", this.entriesLabel);
};
}
From d5b7a2660ddd125a4da6747639cc25c8b3603f92 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 10:49:26 +0200
Subject: [PATCH 23/32] refactor and added snackbars
colored the snacbars also
---
src/app/app.component.html | 2 +-
src/app/app.component.ts | 22 +++++++++-------
src/app/app.module.ts | 5 ++--
.../create-user/create-user.component.ts | 20 ++++++++------
.../users-table/users-table.component.ts | 26 +++++++------------
src/global-styling/snackbar.scss | 13 ++++++++++
src/styles.scss | 1 +
7 files changed, 52 insertions(+), 37 deletions(-)
create mode 100644 src/global-styling/snackbar.scss
diff --git a/src/app/app.component.html b/src/app/app.component.html
index f9cec35..b2d0dfa 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,3 +1,3 @@
-{{'APP.TITLE'}}
+{{'APP.TITLE'}}
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 296dcb7..8523603 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { AfterViewInit, Component, OnDestroy } from '@angular/core';
+import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { LoadingService } from './services/loading.service';
@@ -7,21 +7,23 @@ import { LoadingService } from './services/loading.service';
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
-export class AppComponent implements AfterViewInit, OnDestroy {
+export class AppComponent implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
public isLoading: boolean = false;
constructor(public loadingService: LoadingService) {
}
- ngAfterViewInit(): void {
- // short timeout to prevent ExpressionChanged errors
- setTimeout(() => {
- this.subscriptions.push(
- this.loadingService.loading().subscribe((loading) => {
+ ngOnInit(): void {
+ this.subscriptions.push(
+ this.loadingService.loading().subscribe((loading) => {
+ // use short timeout to prevent ExpressionChangedAfterItHasBeenCheckedError
+ setTimeout(() => {
this.isLoading = loading;
- })
- );
- }, 100)
+ }, 100)
+ })
+ );
+ }
+ ngAfterViewInit(): void {
}
ngOnDestroy(): void {
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2b2dbc2..223d00f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -2,7 +2,7 @@ import { LoadingInterceptor } from './interceptors/loading.interceptor';
import { HttpClientModule, HTTP_INTERCEPTORS, HttpInterceptor } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
-import { MatFormFieldModule, MatInputModule, MatPaginatorIntl, MatPaginatorModule, MatProgressBarModule, MatSelectModule, MatTableModule, MatToolbarModule } from '@angular/material';
+import { MatFormFieldModule, MatInputModule, MatPaginatorIntl, MatPaginatorModule, MatProgressBarModule, MatSelectModule, MatSnackBarModule, MatTableModule, MatToolbarModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@@ -32,7 +32,8 @@ import { CustomMatPagerIntl } from './mat-helpers/custom-mat-pager-intl';
MatSelectModule,
ReactiveFormsModule,
MatToolbarModule,
- MatProgressBarModule
+ MatProgressBarModule,
+ MatSnackBarModule
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true },
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index 61fd20c..b00200c 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -1,3 +1,4 @@
+import { MatSnackBar } from '@angular/material';
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { emailValidator } from 'src/app/validators/email.validator';
@@ -22,7 +23,8 @@ export class CreateUserComponent {
email: new FormControl('', [Validators.required, emailValidator()])
});;
- constructor(private userService: UserService, private routingService: RoutingService) { }
+ constructor(private userService: UserService, private routingService: RoutingService,
+ private snackBar: MatSnackBar) { }
public cancel(): void {
this.routingService.navigateToUsersTable();
@@ -31,13 +33,14 @@ export class CreateUserComponent {
public addNewUser(): void {
this.userService.getByUsername(this.newUserForm.get("userName").value).toPromise().then((result: UsersResponse) => {
if (result && result.data && result.data.count > 0) {
- // abort, with user exists warning
+ this.snackBar.open("TOAST.ERROR.USERNAME_TAKEN", '', { duration: 10000 , panelClass: 'warn'});
} else {
this.assignDataToNewUser();
this.postUser();
}
- }).catch((err) => {
- // show error toast
+ }).catch((err: Error) => {
+ console.error(err)
+ this.snackBar.open(err.message, '', { duration: 10000, panelClass: 'error' });
});
}
public assignDataToNewUser(): void {
@@ -49,11 +52,12 @@ export class CreateUserComponent {
}
private postUser() {
- this.userService.postUser(this.newUser).toPromise().then((success) => {
- // display toast
+ this.userService.postUser(this.newUser).toPromise().then(() => {
+ this.snackBar.open("TOAST.SUCCESS.USER_CREATED", '', { duration: 10000 , panelClass: 'success'});
},
- (error) => {
- // display toast
+ (err: Error) => {
+ console.error(err);
+ this.snackBar.open("TOAST.ERROR.REQUEST_FAILED", '', { duration: 10000, panelClass: 'error' });
});
}
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index 0d76883..b2f3565 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -1,5 +1,5 @@
-import { AfterContentChecked, AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
-import { MatPaginator, MatTableDataSource, PageEvent } from '@angular/material';
+import { AfterContentChecked, AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { MatPaginator, MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
import { User } from 'src/app/models/user.model';
import { RoutingService } from './../../services/routing.service';
import { UserService } from './../../services/user.service';
@@ -18,10 +18,9 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
public dataSource = new MatTableDataSource();
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
- @ViewChild('appToolbar', { static: false }) appToolbar: any;
@ViewChild('userTableContainer', { static: false }) userTableContainer: ElementRef;
constructor(private userService: UserService,
- private routingService: RoutingService) { }
+ private routingService: RoutingService, private snackBar: MatSnackBar) { }
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
@@ -30,7 +29,10 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
ngOnInit(): void {
this.userService.getUsers().toPromise().then((users: User[]) => {
this.dataSource.data = users;
- }).catch((err) => console.error(err));
+ }).catch((err: Error) => {
+ this.snackBar.open(err.message, '', { duration: 10000, panelClass: 'error' });
+ console.error(err);
+ });
}
ngAfterContentChecked(): void {
@@ -43,23 +45,15 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
public handlePageEvent(event: PageEvent) {
if (event && !!event.pageSize) {
- setTimeout(()=>{
+ setTimeout(() => {
const matPaginatorBottom: Element = document.querySelector('.mat-paginator-range-actions');
//@ts-ignore
matPaginatorBottom.style.bottom = this.calculateNewBottom(event.pageSize);
- },60)
-
+ }, 60)
}
}
- private calculateNewBottom(pageSize: number) {
- // if (pageSize == 20)
- // return (window.innerHeight - 713) + 'px';
- // else if (pageSize == 10)
- // return (window.innerHeight - 503) + 'px';
- // else if (pageSize == 5)
- // return (window.innerHeight - 398) + 'px';
- //windows innerHeight - height of component + mat-toolbar height + paginator height
+ private calculateNewBottom() {
return (window.innerHeight - (this.userTableContainer.nativeElement.offsetHeight + 64 + 40)) + 'px'
}
}
diff --git a/src/global-styling/snackbar.scss b/src/global-styling/snackbar.scss
new file mode 100644
index 0000000..32a7eeb
--- /dev/null
+++ b/src/global-styling/snackbar.scss
@@ -0,0 +1,13 @@
+snack-bar-container {
+ &.success{
+ color: #35f817;
+ }
+
+ &.warn {
+ color: #f27500;
+ }
+
+ &.error {
+ background-color: #f32c1e;
+ }
+}
diff --git a/src/styles.scss b/src/styles.scss
index cb6e519..4318327 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -4,6 +4,7 @@
// project specific global stylings
@import "global-styling/variables.scss";
@import "global-styling/flex.scss";
+@import "global-styling/snackbar.scss";
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
From b39eee4e869651159178bbb7912f1ce93d13db11 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 11:35:17 +0200
Subject: [PATCH 24/32] Updated to run test files
added all missing imports to make the basic specs run, added firefox as browser
---
karma.conf.js | 8 +-
package-lock.json | 89 +++++++++++++++++++
package.json | 1 +
src/app/app.component.spec.ts | 11 ++-
.../create-user/create-user.component.spec.ts | 20 ++++-
.../users-table/users-table.component.spec.ts | 15 +++-
src/app/services/routing.service.spec.ts | 5 +-
src/app/services/user.service.spec.ts | 5 +-
8 files changed, 147 insertions(+), 7 deletions(-)
diff --git a/karma.conf.js b/karma.conf.js
index ecf8659..920fc5f 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -8,12 +8,16 @@ module.exports = function (config) {
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
+ require('karma-firefox-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
- clearContext: false // leave Jasmine Spec Runner output visible in browser
+ clearContext: false, // leave Jasmine Spec Runner output visible in browser
+ jasmine: {
+ random: false
+ }
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/fe-test-app'),
@@ -25,7 +29,7 @@ module.exports = function (config) {
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
- browsers: ['Chrome'],
+ browsers: ['Chrome', 'Firefox'],
singleRun: false,
restartOnFileChange: true
});
diff --git a/package-lock.json b/package-lock.json
index e65ff26..8c7f895 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,6 +44,7 @@
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
+ "karma-firefox-launcher": "^2.1.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.6.0",
"path-browserify": "^1.0.1",
@@ -6641,6 +6642,21 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -7442,6 +7458,43 @@
"minimatch": "^3.0.4"
}
},
+ "node_modules/karma-firefox-launcher": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz",
+ "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==",
+ "dev": true,
+ "dependencies": {
+ "is-wsl": "^2.2.0",
+ "which": "^2.0.1"
+ }
+ },
+ "node_modules/karma-firefox-launcher/node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/karma-firefox-launcher/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/karma-jasmine": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.3.1.tgz",
@@ -20538,6 +20591,12 @@
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
"dev": true
},
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true
+ },
"is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -21465,6 +21524,36 @@
"minimatch": "^3.0.4"
}
},
+ "karma-firefox-launcher": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz",
+ "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^2.2.0",
+ "which": "^2.0.1"
+ },
+ "dependencies": {
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
"karma-jasmine": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.3.1.tgz",
diff --git a/package.json b/package.json
index 1d24dcd..292e0ff 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
+ "karma-firefox-launcher": "^2.1.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.6.0",
"path-browserify": "^1.0.1",
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index caa6302..e36122f 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -1,3 +1,4 @@
+import { MatToolbarModule, MatProgressBarModule } from '@angular/material';
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
@@ -6,7 +7,9 @@ describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
- RouterTestingModule
+ RouterTestingModule,
+ MatToolbarModule,
+ MatProgressBarModule
],
declarations: [
AppComponent
@@ -19,4 +22,10 @@ describe('AppComponent', () => {
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
+
+ it('should subscribe to loading events', () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ fixture.detectChanges();
+ });
});
diff --git a/src/app/components/create-user/create-user.component.spec.ts b/src/app/components/create-user/create-user.component.spec.ts
index 0489eff..97e870d 100644
--- a/src/app/components/create-user/create-user.component.spec.ts
+++ b/src/app/components/create-user/create-user.component.spec.ts
@@ -1,6 +1,12 @@
+import { UserService } from './../../services/user.service';
+import { RouterTestingModule } from '@angular/router/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { MatTableModule, MatPaginatorModule, MatFormFieldModule, MatSnackBarModule, MatInputModule, MatButtonModule, MatProgressBarModule, MatSelectModule, MatToolbarModule } from '@angular/material';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
import { CreateUserComponent } from './create-user.component';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
describe('CreateUserComponent', () => {
let component: CreateUserComponent;
@@ -8,7 +14,19 @@ describe('CreateUserComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- declarations: [ CreateUserComponent ]
+ imports: [
+ ReactiveFormsModule,
+ MatTableModule,
+ MatPaginatorModule,
+ MatFormFieldModule,
+ RouterTestingModule,
+ HttpClientModule,
+ MatSnackBarModule,
+ MatInputModule,
+ BrowserAnimationsModule
+ ],
+ declarations: [ CreateUserComponent ],
+ providers: [UserService]
})
.compileComponents();
}));
diff --git a/src/app/components/users-table/users-table.component.spec.ts b/src/app/components/users-table/users-table.component.spec.ts
index 5b29b69..a159c5d 100644
--- a/src/app/components/users-table/users-table.component.spec.ts
+++ b/src/app/components/users-table/users-table.component.spec.ts
@@ -1,3 +1,9 @@
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { MatButtonModule } from '@angular/material/button';
+import { MatInputModule, MatPaginatorModule, MatTableModule, MatSnackBarModule } from '@angular/material';
+import { UserService } from './../../services/user.service';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UsersTableComponent } from './users-table.component';
@@ -8,7 +14,14 @@ describe('UsersTableComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- declarations: [ UsersTableComponent ]
+ imports: [
+ BrowserAnimationsModule,
+ HttpClientModule,
+ RouterTestingModule,
+ MatSnackBarModule,
+ MatInputModule, MatPaginatorModule, MatTableModule, MatButtonModule],
+ declarations: [ UsersTableComponent ],
+ providers: [UserService]
})
.compileComponents();
}));
diff --git a/src/app/services/routing.service.spec.ts b/src/app/services/routing.service.spec.ts
index 43fe84f..34d8633 100644
--- a/src/app/services/routing.service.spec.ts
+++ b/src/app/services/routing.service.spec.ts
@@ -1,9 +1,12 @@
+import { RouterTestingModule } from '@angular/router/testing';
import { TestBed } from '@angular/core/testing';
import { RoutingService } from './routing.service';
describe('RoutingService', () => {
- beforeEach(() => TestBed.configureTestingModule({}));
+ beforeEach(() => TestBed.configureTestingModule({
+ imports: [RouterTestingModule]
+ }));
it('should be created', () => {
const service: RoutingService = TestBed.get(RoutingService);
diff --git a/src/app/services/user.service.spec.ts b/src/app/services/user.service.spec.ts
index 9e7fd1c..e0bce59 100644
--- a/src/app/services/user.service.spec.ts
+++ b/src/app/services/user.service.spec.ts
@@ -1,9 +1,12 @@
+import { HttpClientModule } from '@angular/common/http';
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
- beforeEach(() => TestBed.configureTestingModule({}));
+ beforeEach(() => TestBed.configureTestingModule({
+ imports: [HttpClientModule]
+ }));
it('should be created', () => {
const service: UserService = TestBed.get(UserService);
From 1e05512612a54effec3702129857a9b1c067a84e Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 13:47:17 +0200
Subject: [PATCH 25/32] added unit tests
---
karma.conf.js | 2 +-
src/app/app.component.spec.ts | 49 +++++++++-
src/app/app.component.ts | 4 +-
.../users-table/users-table.component.spec.ts | 97 +++++++++++++++++--
.../users-table/users-table.component.ts | 6 ++
src/app/services/user.service.ts | 2 -
6 files changed, 142 insertions(+), 18 deletions(-)
diff --git a/karma.conf.js b/karma.conf.js
index 920fc5f..f390a6d 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -29,7 +29,7 @@ module.exports = function (config) {
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
- browsers: ['Chrome', 'Firefox'],
+ browsers: ['Firefox'],
singleRun: false,
restartOnFileChange: true
});
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index e36122f..0f9b65b 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -1,10 +1,27 @@
-import { MatToolbarModule, MatProgressBarModule } from '@angular/material';
-import { TestBed, async } from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
+import { MatProgressBarModule, MatToolbarModule } from '@angular/material';
import { RouterTestingModule } from '@angular/router/testing';
+import { of, BehaviorSubject } from 'rxjs';
import { AppComponent } from './app.component';
+import { LoadingService } from './services/loading.service';
describe('AppComponent', () => {
+
+ let _loading = new BehaviorSubject(false);
beforeEach(async(() => {
+ const mockLoadingService = jasmine.createSpyObj('LoadingService', ['isLoading', 'setLoading', 'loading']);
+
+ mockLoadingService.isLoading.and.callFake(function(){
+ return _loading;
+ });
+ mockLoadingService.setLoading.and.callFake(function(loading:boolean){
+ //
+ _loading.next(loading);
+ });
+ mockLoadingService.loading.and.callFake(function(){
+ return _loading.asObservable();
+ });
+
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
@@ -14,6 +31,7 @@ describe('AppComponent', () => {
declarations: [
AppComponent
],
+ providers: [{ provide: LoadingService, useValue: mockLoadingService }]
}).compileComponents();
}));
@@ -26,6 +44,31 @@ describe('AppComponent', () => {
it('should subscribe to loading events', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
- fixture.detectChanges();
+ app.ngOnInit();
+
+ expect(app.subscriptions).toBeTruthy();
+ expect(app.subscriptions.length).toBeGreaterThan(0);
+ expect(app.subscriptions[0].closed).toBeFalsy();
+ });
+
+ it('it should update loading value', () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ const service = fixture.debugElement.injector.get(LoadingService);
+ app.ngOnInit();
+
+ expect(app.isLoading).toBe(false);
+ service.setLoading(true);
+ setTimeout(()=> expect(app.isLoading).toBe(true), 150)
+ });
+
+ it('it should unsubscribe on destroy', () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ app.ngOnInit();
+
+ expect(app.subscriptions).toBeTruthy();
+ app.ngOnDestroy();
+ expect(app.subscriptions[0].closed).toBeTruthy();
});
});
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 8523603..29cc348 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -7,7 +7,7 @@ import { LoadingService } from './services/loading.service';
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
-export class AppComponent implements OnInit, OnDestroy {
+export class AppComponent implements OnInit {
private subscriptions: Subscription[] = [];
public isLoading: boolean = false;
@@ -23,8 +23,6 @@ export class AppComponent implements OnInit, OnDestroy {
})
);
}
- ngAfterViewInit(): void {
- }
ngOnDestroy(): void {
this.subscriptions.forEach(sub => {
diff --git a/src/app/components/users-table/users-table.component.spec.ts b/src/app/components/users-table/users-table.component.spec.ts
index a159c5d..93a394b 100644
--- a/src/app/components/users-table/users-table.component.spec.ts
+++ b/src/app/components/users-table/users-table.component.spec.ts
@@ -1,38 +1,117 @@
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http';
+import { async, ComponentFixture, TestBed, getTestBed } from '@angular/core/testing';
+import { MatInputModule, MatPaginatorModule, MatSnackBar, MatSnackBarModule, MatTableModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
-import { MatInputModule, MatPaginatorModule, MatTableModule, MatSnackBarModule } from '@angular/material';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+import { of, Observable, throwError, Subscription } from 'rxjs';
+import { User } from 'src/app/models/user.model';
+import { UsersResponse } from 'src/app/responses/users.response';
+import { UserRequest } from './../../requests/user.request';
import { UserService } from './../../services/user.service';
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
import { UsersTableComponent } from './users-table.component';
+import {
+ HttpClientTestingModule,
+ HttpTestingController
+} from '@angular/common/http/testing';
+
describe('UsersTableComponent', () => {
let component: UsersTableComponent;
let fixture: ComponentFixture;
+ let app: UsersTableComponent;
+ let mockUserService: jasmine.SpyObj = jasmine.createSpyObj('UserService', ['getUsers', 'postUser', 'getByUsername'])
+ let mockUserData: User[] = [];
+ let mockUserDataByUsername: UsersResponse;
+
+ const dummyMatSnackBar = {
+ open(message: string, action: string, options: { duration: number, panelClass: string }) {
+ }
+ }
+
+ beforeEach(() => {
+ mockUserService.getUsers.and.callFake(function () {
+ return of(mockUserData)
+ });
+ mockUserService.postUser.and.callFake(function (newUser: UserRequest) {
+ //
+ return of(undefined)
+ });
+ mockUserService.getByUsername.and.callFake(function (userName: string) {
+ return of(mockUserDataByUsername)
+ });
+ });
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
- HttpClientModule,
+ HttpClientTestingModule,
RouterTestingModule,
MatSnackBarModule,
MatInputModule, MatPaginatorModule, MatTableModule, MatButtonModule],
- declarations: [ UsersTableComponent ],
- providers: [UserService]
+ declarations: [UsersTableComponent],
+ providers: [{ provide: UserService, useValue: mockUserService }]
})
- .compileComponents();
+ .compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UsersTableComponent);
component = fixture.componentInstance;
+ app = fixture.debugElement.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
+
+ it('it should assign a paginator', () => {
+ app.ngOnInit();
+ app.ngAfterViewInit();
+ expect(app.dataSource.paginator).toEqual(app.paginator);
+ });
+
+ it('it should retrieve users', async () => {
+ mockUserData = [
+ new User(),
+ new User(),
+ new User()
+ ];
+ mockUserData.forEach((user: User) => {
+ user.first_name = 'DUMMY_first_name'
+ user.last_name = 'DUMMY_last_name'
+ user.username = 'DUMMY_username'
+ user.email = 'DUMMY_email'
+ user.id = 123
+ user.id_status = 'DUMMY_id_status'
+ user.created_date = new Date(Date.now());
+ })
+ app.ngOnInit();
+ expect(mockUserService.getUsers).toHaveBeenCalled();
+ await mockUserService.getUsers().toPromise().then(() => {
+ expect(app.dataSource.data).toEqual(mockUserData);
+ expect(app.subSucceeded).toEqual(true);
+ })
+ });
+
+ it('it should set isMobile', () => {
+ app.ngOnInit();
+ app.ngAfterViewInit();
+ expect(app.isMobile).toEqual(window.innerWidth <= 600);
+ });
+
+ // it('it should show error on getUsers failure', async () => {
+ // mockUserService.getUsers.and.callFake(function () {
+ // return throwError({status: 500});
+ // });
+ // app.ngOnInit();
+ // expect(mockUserService.getUsers).toHaveBeenCalled();
+ // await mockUserService.getUsers().subscribe(()=>{}, ()=>{
+ // expect(app.dataSource.data).toEqual([]);
+ // expect(app.subFailed).toEqual(true);
+ // })
+ // });
+
});
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index b2f3565..91f5d57 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -15,6 +15,8 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
public readonly mobileColumns = ['username', 'fullname'];
public readonly pageSizes = [5, 10, 20];
public isMobile: boolean;
+ public subFailed = false;
+ public subSucceeded = false;
public dataSource = new MatTableDataSource();
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
@@ -29,8 +31,12 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
ngOnInit(): void {
this.userService.getUsers().toPromise().then((users: User[]) => {
this.dataSource.data = users;
+ this.subFailed = false;
+ this.subSucceeded = true;
}).catch((err: Error) => {
this.snackBar.open(err.message, '', { duration: 10000, panelClass: 'error' });
+ this.subFailed = true;
+ this.subSucceeded = false;
console.error(err);
});
}
diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts
index 4744ce9..4c38a85 100644
--- a/src/app/services/user.service.ts
+++ b/src/app/services/user.service.ts
@@ -25,11 +25,9 @@ export class UserService {
}
public getByUsername(username: string): Observable {
- //?username = {{ username }
let queryParams = new HttpParams();
queryParams = queryParams.append("username", username);
return this.http.get(environment.apiBaseUrl + '/' + API_ROUTES.USERS,{params:queryParams})
-
}
}
From a9d3296e89bc2e263f27f47e4640d66c9f71e823 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 14:17:24 +0200
Subject: [PATCH 26/32] added matSnackBar test
---
.../users-table/users-table.component.spec.ts | 32 +++++++++----------
.../users-table/users-table.component.ts | 6 ----
2 files changed, 16 insertions(+), 22 deletions(-)
diff --git a/src/app/components/users-table/users-table.component.spec.ts b/src/app/components/users-table/users-table.component.spec.ts
index 93a394b..8889a6d 100644
--- a/src/app/components/users-table/users-table.component.spec.ts
+++ b/src/app/components/users-table/users-table.component.spec.ts
@@ -10,6 +10,7 @@ import { UsersResponse } from 'src/app/responses/users.response';
import { UserRequest } from './../../requests/user.request';
import { UserService } from './../../services/user.service';
import { UsersTableComponent } from './users-table.component';
+import {asyncScheduler} from "rxjs"
import {
HttpClientTestingModule,
HttpTestingController
@@ -23,6 +24,7 @@ describe('UsersTableComponent', () => {
let mockUserService: jasmine.SpyObj = jasmine.createSpyObj('UserService', ['getUsers', 'postUser', 'getByUsername'])
let mockUserData: User[] = [];
let mockUserDataByUsername: UsersResponse;
+ const mockSnackbarMock = jasmine.createSpyObj(['open']);
const dummyMatSnackBar = {
open(message: string, action: string, options: { duration: number, panelClass: string }) {
@@ -31,14 +33,13 @@ describe('UsersTableComponent', () => {
beforeEach(() => {
mockUserService.getUsers.and.callFake(function () {
- return of(mockUserData)
+ return of(mockUserData, asyncScheduler)
});
mockUserService.postUser.and.callFake(function (newUser: UserRequest) {
- //
return of(undefined)
});
mockUserService.getByUsername.and.callFake(function (userName: string) {
- return of(mockUserDataByUsername)
+ return of(mockUserDataByUsername, asyncScheduler)
});
});
@@ -51,7 +52,7 @@ describe('UsersTableComponent', () => {
MatSnackBarModule,
MatInputModule, MatPaginatorModule, MatTableModule, MatButtonModule],
declarations: [UsersTableComponent],
- providers: [{ provide: UserService, useValue: mockUserService }]
+ providers: [{ provide: UserService, useValue: mockUserService }, {provide: MatSnackBar, useValue: mockSnackbarMock}]
})
.compileComponents();
}));
@@ -92,7 +93,6 @@ describe('UsersTableComponent', () => {
expect(mockUserService.getUsers).toHaveBeenCalled();
await mockUserService.getUsers().toPromise().then(() => {
expect(app.dataSource.data).toEqual(mockUserData);
- expect(app.subSucceeded).toEqual(true);
})
});
@@ -102,16 +102,16 @@ describe('UsersTableComponent', () => {
expect(app.isMobile).toEqual(window.innerWidth <= 600);
});
- // it('it should show error on getUsers failure', async () => {
- // mockUserService.getUsers.and.callFake(function () {
- // return throwError({status: 500});
- // });
- // app.ngOnInit();
- // expect(mockUserService.getUsers).toHaveBeenCalled();
- // await mockUserService.getUsers().subscribe(()=>{}, ()=>{
- // expect(app.dataSource.data).toEqual([]);
- // expect(app.subFailed).toEqual(true);
- // })
- // });
+ it('it should show error on getUsers failure', async () => {
+ mockUserService.getUsers.and.callFake(function () {
+ return throwError(new Error('error'), asyncScheduler);
+ });
+ app.ngOnInit();
+ expect(mockUserService.getUsers).toHaveBeenCalled();
+ await mockUserService.getUsers().subscribe(()=>{}, ()=>{
+ expect(app.dataSource.data).toEqual([]);
+ expect(mockSnackbarMock.open).toHaveBeenCalledWith('error', '', { duration: 10000, panelClass: 'error' });
+ })
+ });
});
diff --git a/src/app/components/users-table/users-table.component.ts b/src/app/components/users-table/users-table.component.ts
index 91f5d57..b2f3565 100644
--- a/src/app/components/users-table/users-table.component.ts
+++ b/src/app/components/users-table/users-table.component.ts
@@ -15,8 +15,6 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
public readonly mobileColumns = ['username', 'fullname'];
public readonly pageSizes = [5, 10, 20];
public isMobile: boolean;
- public subFailed = false;
- public subSucceeded = false;
public dataSource = new MatTableDataSource();
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
@@ -31,12 +29,8 @@ export class UsersTableComponent implements OnInit, AfterViewInit, AfterContentC
ngOnInit(): void {
this.userService.getUsers().toPromise().then((users: User[]) => {
this.dataSource.data = users;
- this.subFailed = false;
- this.subSucceeded = true;
}).catch((err: Error) => {
this.snackBar.open(err.message, '', { duration: 10000, panelClass: 'error' });
- this.subFailed = true;
- this.subSucceeded = false;
console.error(err);
});
}
From f629870a3a3390e532ead4d9d66aa90ffdf08715 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 14:49:47 +0200
Subject: [PATCH 27/32] added more tests
---
.../users-table/users-table.component.html | 2 +-
.../users-table/users-table.component.spec.ts | 52 +++++++++++++------
2 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/src/app/components/users-table/users-table.component.html b/src/app/components/users-table/users-table.component.html
index be46cb2..a4d077f 100644
--- a/src/app/components/users-table/users-table.component.html
+++ b/src/app/components/users-table/users-table.component.html
@@ -1,5 +1,5 @@
-
+
{
@@ -25,11 +25,7 @@ describe('UsersTableComponent', () => {
let mockUserData: User[] = [];
let mockUserDataByUsername: UsersResponse;
const mockSnackbarMock = jasmine.createSpyObj(['open']);
-
- const dummyMatSnackBar = {
- open(message: string, action: string, options: { duration: number, panelClass: string }) {
- }
- }
+ const mockRoutingService = jasmine.createSpyObj(['navigateToCreateUser']);
beforeEach(() => {
mockUserService.getUsers.and.callFake(function () {
@@ -48,11 +44,11 @@ describe('UsersTableComponent', () => {
imports: [
BrowserAnimationsModule,
HttpClientTestingModule,
- RouterTestingModule,
MatSnackBarModule,
MatInputModule, MatPaginatorModule, MatTableModule, MatButtonModule],
declarations: [UsersTableComponent],
- providers: [{ provide: UserService, useValue: mockUserService }, {provide: MatSnackBar, useValue: mockSnackbarMock}]
+ providers: [{ provide: UserService, useValue: mockUserService }, { provide: MatSnackBar, useValue: mockSnackbarMock },
+ { provide: RoutingService, useValue: mockRoutingService }]
})
.compileComponents();
}));
@@ -108,10 +104,32 @@ describe('UsersTableComponent', () => {
});
app.ngOnInit();
expect(mockUserService.getUsers).toHaveBeenCalled();
- await mockUserService.getUsers().subscribe(()=>{}, ()=>{
+ await mockUserService.getUsers().subscribe(() => { }, () => {
expect(app.dataSource.data).toEqual([]);
expect(mockSnackbarMock.open).toHaveBeenCalledWith('error', '', { duration: 10000, panelClass: 'error' });
})
});
+ it('it should navigate to create user page', async () => {
+ const navigateButton = fixture.debugElement.query(By.css('#btn-nav-create-user'));
+ spyOn(app, 'navigateToCreateUser').and.callThrough();
+ navigateButton.triggerEventHandler('click', null);
+ expect(app.navigateToCreateUser).toHaveBeenCalled();
+ expect(mockRoutingService.navigateToCreateUser).toHaveBeenCalled();
+ });
+
+
+ it('it should adjust paginator position on page event', () => {
+ spyOn(app, 'handlePageEvent').and.callThrough();
+ var calculateFunction = spyOn(app, 'calculateNewBottom').and.callThrough();
+ const pageEvent = new PageEvent();
+ pageEvent.pageSize = 10;
+ app.paginator.page.emit(pageEvent);
+ expect(app.handlePageEvent).toHaveBeenCalled();
+ setTimeout(() => {
+ expect(calculateFunction).toHaveBeenCalled();
+ expect(calculateFunction).toEqual((app.userTableContainer.nativeElement.offsetHeight + 64 + 40) + 'px')
+ }, 100)
+ });
+
});
From 0d5ea2a92136c883d04298047f680261c1cabfc8 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 15:11:01 +0200
Subject: [PATCH 28/32] Update users-table.component.spec.ts
---
.../users-table/users-table.component.spec.ts | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/app/components/users-table/users-table.component.spec.ts b/src/app/components/users-table/users-table.component.spec.ts
index 3da8b7d..0d73b17 100644
--- a/src/app/components/users-table/users-table.component.spec.ts
+++ b/src/app/components/users-table/users-table.component.spec.ts
@@ -15,6 +15,7 @@ import { UsersResponse } from 'src/app/responses/users.response';
import { UserRequest } from './../../requests/user.request';
import { UserService } from './../../services/user.service';
import { UsersTableComponent } from './users-table.component';
+import { fakeAsync, tick, discardPeriodicTasks } from '@angular/core/testing';
describe('UsersTableComponent', () => {
@@ -48,7 +49,7 @@ describe('UsersTableComponent', () => {
MatInputModule, MatPaginatorModule, MatTableModule, MatButtonModule],
declarations: [UsersTableComponent],
providers: [{ provide: UserService, useValue: mockUserService }, { provide: MatSnackBar, useValue: mockSnackbarMock },
- { provide: RoutingService, useValue: mockRoutingService }]
+ { provide: RoutingService, useValue: mockRoutingService }]
})
.compileComponents();
}));
@@ -119,17 +120,17 @@ describe('UsersTableComponent', () => {
});
- it('it should adjust paginator position on page event', () => {
+ it('it should adjust paginator position on page event', fakeAsync(() => {
spyOn(app, 'handlePageEvent').and.callThrough();
var calculateFunction = spyOn(app, 'calculateNewBottom').and.callThrough();
const pageEvent = new PageEvent();
pageEvent.pageSize = 10;
app.paginator.page.emit(pageEvent);
expect(app.handlePageEvent).toHaveBeenCalled();
- setTimeout(() => {
- expect(calculateFunction).toHaveBeenCalled();
- expect(calculateFunction).toEqual((app.userTableContainer.nativeElement.offsetHeight + 64 + 40) + 'px')
- }, 100)
- });
+ tick(100);
+ expect(calculateFunction).toHaveBeenCalled();
+ const rangeActions = fixture.debugElement.query(By.css('.mat-paginator-range-actions'))
+ expect(rangeActions.nativeElement.style.bottom).toEqual((window.innerHeight - (app.userTableContainer.nativeElement.offsetHeight + 64 + 40)) + 'px');
+ }));
});
From f5d988fca0c32a7077bdc489c1c9c780d60ce36d Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 16:17:01 +0200
Subject: [PATCH 29/32] updated with more tests
---
.../create-user/create-user.component.html | 2 +-
.../create-user/create-user.component.spec.ts | 119 ++++++++++++++++--
.../create-user/create-user.component.ts | 7 +-
src/app/responses/users.response.ts | 7 ++
4 files changed, 124 insertions(+), 11 deletions(-)
diff --git a/src/app/components/create-user/create-user.component.html b/src/app/components/create-user/create-user.component.html
index 78d3869..f2be7a3 100644
--- a/src/app/components/create-user/create-user.component.html
+++ b/src/app/components/create-user/create-user.component.html
@@ -30,7 +30,7 @@ CREATE_USER.TITLE
-
+
diff --git a/src/app/components/create-user/create-user.component.spec.ts b/src/app/components/create-user/create-user.component.spec.ts
index 97e870d..825c94d 100644
--- a/src/app/components/create-user/create-user.component.spec.ts
+++ b/src/app/components/create-user/create-user.component.spec.ts
@@ -1,17 +1,46 @@
-import { UserService } from './../../services/user.service';
-import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http';
-import { MatTableModule, MatPaginatorModule, MatFormFieldModule, MatSnackBarModule, MatInputModule, MatButtonModule, MatProgressBarModule, MatSelectModule, MatToolbarModule } from '@angular/material';
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
-
-import { CreateUserComponent } from './create-user.component';
+import { MatFormFieldModule, MatInputModule, MatPaginatorModule, MatSnackBar, MatSnackBarModule, MatTableModule } from '@angular/material';
+import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouterTestingModule } from '@angular/router/testing';
+import { asyncScheduler, of } from 'rxjs';
+import { User } from 'src/app/models/user.model';
+import { UserRequest } from 'src/app/requests/user.request';
+import { UsersResponse } from 'src/app/responses/users.response';
+import { RoutingService } from 'src/app/services/routing.service';
+import { ApiResponse } from './../../interfaces/api-response.interface';
+import { UserService } from './../../services/user.service';
+import { CreateUserComponent } from './create-user.component';
+
describe('CreateUserComponent', () => {
let component: CreateUserComponent;
let fixture: ComponentFixture;
+ let mockUserService: jasmine.SpyObj = jasmine.createSpyObj('UserService', ['getUsers', 'postUser', 'getByUsername'])
+ let mockUserData: User[] = [];
+ let mockUserDataByUsername: UsersResponse;
+ const mockSnackbarMock = jasmine.createSpyObj(['open']);
+ const mockRoutingService = jasmine.createSpyObj(['navigateToCreateUser']);
+ const mockNewUser = new UserRequest();
+ const userCreatedResponse: ApiResponse = {
+ data: new User
+ };
+
+ beforeEach(() => {
+ mockUserService.getUsers.and.callFake(function () {
+ return of(mockUserData, asyncScheduler)
+ });
+ mockUserService.postUser.and.callFake(function (newUser: UserRequest) {
+ return of(userCreatedResponse)
+ });
+ mockUserService.getByUsername.and.callFake(function (userName: string) {
+ return of(mockUserDataByUsername, asyncScheduler)
+ });
+ });
+
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
@@ -25,10 +54,11 @@ describe('CreateUserComponent', () => {
MatInputModule,
BrowserAnimationsModule
],
- declarations: [ CreateUserComponent ],
- providers: [UserService]
+ declarations: [CreateUserComponent],
+ providers: [{ provide: UserService, useValue: mockUserService }, { provide: MatSnackBar, useValue: mockSnackbarMock },
+ { provide: RoutingService, useValue: mockRoutingService }]
})
- .compileComponents();
+ .compileComponents();
}));
beforeEach(() => {
@@ -40,4 +70,75 @@ describe('CreateUserComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
+
+
+ it('it should add new user, display success toast', (fakeAsync(() => {
+ const addUserButton = fixture.debugElement.query(By.css('#btn-add-user'));
+ spyOn(component, 'addNewUser').and.callThrough();
+ spyOn(component, 'assignDataToNewUser').and.callFake(() => {
+ mockNewUser.first_name = 'DUMMY_first_name';
+ mockNewUser.last_name = 'DUMMY_last_name';
+ mockNewUser.username = 'DUMMY_username';
+ mockNewUser.email = 'DUMMY_email';
+ mockNewUser.id_status = 1;
+ component.newUser = mockNewUser;
+ });
+ mockUserDataByUsername = new UsersResponse();
+ mockUserService.getByUsername.and.returnValue(of(mockUserDataByUsername, asyncScheduler));
+ addUserButton.triggerEventHandler('click', null);
+ expect(component.addNewUser).toHaveBeenCalled();
+ tick(100);
+ expect(mockUserService.getByUsername).toHaveBeenCalled();
+ expect(component.assignDataToNewUser).toHaveBeenCalled();
+ expect(mockUserService.postUser).toHaveBeenCalledWith(component.newUser);
+ expect(component.newUser).toEqual(mockNewUser);
+ expect(mockSnackbarMock.open).toHaveBeenCalledWith("TOAST.SUCCESS.USER_CREATED", '', { duration: 10000, panelClass: 'success' });
+ }
+ )));
+
+ it('if user present, it should NOT add new user, display error toas', (fakeAsync(() => {
+ const addUserButton = fixture.debugElement.query(By.css('#btn-add-user'));
+ spyOn(component, 'addNewUser').and.callThrough();
+ spyOn(component, 'assignDataToNewUser');
+ mockUserDataByUsername = new UsersResponse();
+ mockUserDataByUsername.data.count = 1;
+ mockUserService.getByUsername.and.returnValue(of(mockUserDataByUsername, asyncScheduler));
+ addUserButton.triggerEventHandler('click', null);
+ expect(component.addNewUser).toHaveBeenCalled();
+ tick(100);
+ expect(mockUserService.getByUsername).toHaveBeenCalled();
+ expect(component.assignDataToNewUser).not.toHaveBeenCalled();
+ expect(component.newUser).toEqual(new UserRequest());
+ expect(mockSnackbarMock.open).toHaveBeenCalledWith("TOAST.ERROR.USERNAME_TAKEN", '', { duration: 10000, panelClass: 'warn' });
+ }
+ )));
+
+ it('it should assign data from form fields to user object', (fakeAsync(() => {
+ const userToSet = new UserRequest();
+ userToSet.first_name = 'DUMMY_firstName';
+ userToSet.last_name = 'DUMMY_lastName';
+ userToSet.username = 'DUMMY_userName';
+ userToSet.email = 'DUMMY_email@email.com';
+ userToSet.id_status = 1;
+
+ component.newUserForm.setValue({
+ firstName: userToSet.first_name,
+ lastName: userToSet.last_name,
+ userName: userToSet.username,
+ email: userToSet.email,
+ });
+ spyOn(component, 'addNewUser').and.callThrough();
+ spyOn(component, 'assignDataToNewUser').and.callThrough();
+ mockUserDataByUsername = new UsersResponse();
+ mockUserService.getByUsername.and.returnValue(of(mockUserDataByUsername, asyncScheduler));
+ const addUserButton = fixture.debugElement.query(By.css('#btn-add-user'));
+ addUserButton.triggerEventHandler('click', null);
+ expect(component.addNewUser).toHaveBeenCalled();
+ tick(100);
+ expect(mockUserService.getByUsername).toHaveBeenCalled();
+ expect(component.assignDataToNewUser).toHaveBeenCalled();
+ expect(component.newUser).toEqual(userToSet);
+ }
+ )));
+
});
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index b00200c..c4b6ca6 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -34,16 +34,21 @@ export class CreateUserComponent {
this.userService.getByUsername(this.newUserForm.get("userName").value).toPromise().then((result: UsersResponse) => {
if (result && result.data && result.data.count > 0) {
this.snackBar.open("TOAST.ERROR.USERNAME_TAKEN", '', { duration: 10000 , panelClass: 'warn'});
- } else {
+ } else if(result && result.data && result.data.count === 0) {
this.assignDataToNewUser();
this.postUser();
+ } else {
+ this.snackBar.open('TOAST.ERROR.UNKOWN', '', { duration: 10000, panelClass: 'error' });
+ console.error("something went wrong");
}
}).catch((err: Error) => {
console.error(err)
this.snackBar.open(err.message, '', { duration: 10000, panelClass: 'error' });
});
}
+
public assignDataToNewUser(): void {
+ debugger;
this.newUser.first_name = this.newUserForm.get("firstName").value;
this.newUser.last_name = this.newUserForm.get("lastName").value;
this.newUser.username = this.newUserForm.get("userName").value;
diff --git a/src/app/responses/users.response.ts b/src/app/responses/users.response.ts
index 355fb25..43feda9 100644
--- a/src/app/responses/users.response.ts
+++ b/src/app/responses/users.response.ts
@@ -1,6 +1,13 @@
import { User } from '../models/user.model';
import { ApiResponse } from './../interfaces/api-response.interface';
export class UsersResponse implements ApiResponse {
+
+ constructor(){
+ this.data = {
+ count: 0,
+ users: []
+ }
+ }
public data: {
count: number;
users: User[];
From 2f635be28a3327443b94fcd84bfaf72834ba3192 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 16:18:51 +0200
Subject: [PATCH 30/32] made progress bar absolute
---
src/app/app.component.scss | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index e69de29..e679d90 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -0,0 +1,3 @@
+mat-progress-bar {
+ position: absolute;
+}
From 9f7227aeec10cc1b9d1803947bc40f7c91e71425 Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 16:26:59 +0200
Subject: [PATCH 31/32] removed debugger
---
src/app/components/create-user/create-user.component.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/app/components/create-user/create-user.component.ts b/src/app/components/create-user/create-user.component.ts
index c4b6ca6..f0c36ab 100644
--- a/src/app/components/create-user/create-user.component.ts
+++ b/src/app/components/create-user/create-user.component.ts
@@ -48,7 +48,6 @@ export class CreateUserComponent {
}
public assignDataToNewUser(): void {
- debugger;
this.newUser.first_name = this.newUserForm.get("firstName").value;
this.newUser.last_name = this.newUserForm.get("lastName").value;
this.newUser.username = this.newUserForm.get("userName").value;
From 0c75327d2400af303c6a7904b17589a91756cf2d Mon Sep 17 00:00:00 2001
From: Wario <37343942+IfreannMedia@users.noreply.github.com>
Date: Sat, 2 Apr 2022 16:29:37 +0200
Subject: [PATCH 32/32] convert settimout to fakeAsync
---
src/app/app.component.spec.ts | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index 0f9b65b..1c2d85a 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -1,4 +1,4 @@
-import { async, TestBed } from '@angular/core/testing';
+import { async, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { MatProgressBarModule, MatToolbarModule } from '@angular/material';
import { RouterTestingModule } from '@angular/router/testing';
import { of, BehaviorSubject } from 'rxjs';
@@ -15,7 +15,6 @@ describe('AppComponent', () => {
return _loading;
});
mockLoadingService.setLoading.and.callFake(function(loading:boolean){
- //
_loading.next(loading);
});
mockLoadingService.loading.and.callFake(function(){
@@ -51,7 +50,7 @@ describe('AppComponent', () => {
expect(app.subscriptions[0].closed).toBeFalsy();
});
- it('it should update loading value', () => {
+ it('it should update loading value', (fakeAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
const service = fixture.debugElement.injector.get(LoadingService);
@@ -59,8 +58,9 @@ describe('AppComponent', () => {
expect(app.isLoading).toBe(false);
service.setLoading(true);
- setTimeout(()=> expect(app.isLoading).toBe(true), 150)
- });
+ tick(150);
+ expect(app.isLoading).toBe(true);
+ })));
it('it should unsubscribe on destroy', () => {
const fixture = TestBed.createComponent(AppComponent);