List and Read on frontend, fullecrud on back
This commit is contained in:
@@ -23,7 +23,7 @@ export function TranslateHttpLoaderFactory(http: HttpClient) {
|
||||
}
|
||||
|
||||
import { LoginService } from '@core/authentication/login.service';
|
||||
import { FakeLoginService } from './fake-login.service';
|
||||
import { ChtloginService } from '@core/../custom/chtlogin.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
@NgModule({
|
||||
@@ -49,7 +49,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
],
|
||||
providers: [
|
||||
{ provide: BASE_URL, useValue: environment.baseUrl },
|
||||
{ provide: LoginService, useClass: FakeLoginService }, // <= Remove it in the real APP
|
||||
{ provide: LoginService, useClass: ChtloginService }, // <= Remove it in the real APP
|
||||
httpInterceptorProviders,
|
||||
appInitializerProviders,
|
||||
],
|
||||
|
||||
41
front/app/src/app/custom/chtlogin.service.ts
Normal file
41
front/app/src/app/custom/chtlogin.service.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Token, User } from '../core/authentication/interface';
|
||||
import { Menu } from '@core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { LoginService } from '../core/authentication/login.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ChtloginService extends LoginService {
|
||||
|
||||
login(username: string, password: string, rememberMe = false) {
|
||||
const body = new HttpParams()
|
||||
.set('username', username)
|
||||
.set('password', password);
|
||||
|
||||
return this.http.post<Token>('/api/v1/auth/login', body.toString(), {
|
||||
headers: new HttpHeaders()
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
});
|
||||
}
|
||||
|
||||
refresh(params: Record<string, any>) {
|
||||
return this.http.post<Token>('/api/v1/auth/refresh', params);
|
||||
}
|
||||
|
||||
logout() {
|
||||
return this.http.post<any>('/api/v1/auth/logout', {});
|
||||
}
|
||||
|
||||
me() {
|
||||
return this.http.get<User>('/api/v1/users/me');
|
||||
}
|
||||
|
||||
menu() {
|
||||
return this.http
|
||||
.get<{ menu: Menu[] }>('assets/data/menu.json?_t=' + Date.now())
|
||||
.pipe(map(res => res.menu));
|
||||
}
|
||||
}
|
||||
28
front/app/src/app/routes/clients/card/card.component.html
Normal file
28
front/app/src/app/routes/clients/card/card.component.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<page-header></page-header>
|
||||
<button routerLink="../../list" mat-fab extended>
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Back
|
||||
</button>
|
||||
|
||||
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()">
|
||||
<mat-form-field appearance="fill" formControlName="name">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput [value]="this.item.name">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" formControlName="address">
|
||||
<mat-label>Address</mat-label>
|
||||
<input matInput [value]="this.item.address">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" formControlName="type">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select [value]="this.item.type">
|
||||
<mat-option value="individual">Particulier</mat-option>
|
||||
<mat-option value="corporation">Entreprise</mat-option>
|
||||
<mat-option value="institution">Institution</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<button class="button" type="submit">Modifier</button>
|
||||
</form>
|
||||
25
front/app/src/app/routes/clients/card/card.component.spec.ts
Normal file
25
front/app/src/app/routes/clients/card/card.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ClientsCardComponent } from './card.component';
|
||||
|
||||
describe('ClientsCardComponent', () => {
|
||||
let component: ClientsCardComponent;
|
||||
let fixture: ComponentFixture<ClientsCardComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ClientsCardComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ClientsCardComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
48
front/app/src/app/routes/clients/card/card.component.ts
Normal file
48
front/app/src/app/routes/clients/card/card.component.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { ClientsService } from '../clients.service'
|
||||
|
||||
export interface Client {
|
||||
_id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-clients-card',
|
||||
templateUrl: './card.component.html',
|
||||
styleUrls: ['./card.component.css']
|
||||
})
|
||||
export class ClientsCardComponent implements OnInit {
|
||||
@Input() id: string = "";
|
||||
|
||||
item: Client = {_id: '', name: '', address: '', type: ''};
|
||||
|
||||
cardForm = this.formBuilder.group({
|
||||
name: '',
|
||||
address: '',
|
||||
type: ''
|
||||
});
|
||||
|
||||
constructor(private formBuilder: FormBuilder, private clientsService: ClientsService) {
|
||||
if (this.id == "") {
|
||||
const url_parts = window.location.href.split('/')
|
||||
this.id = url_parts[url_parts.length - 1];
|
||||
}
|
||||
this.item = {_id: '', name: '', address: '', type: ''}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
private getData() {
|
||||
this.clientsService.get(this.id).subscribe((data: any) => {
|
||||
this.item = data;
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
}
|
||||
}
|
||||
14
front/app/src/app/routes/clients/clients-routing.module.ts
Normal file
14
front/app/src/app/routes/clients/clients-routing.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { ClientsListComponent } from './list/list.component';
|
||||
import { ClientsCardComponent } from './card/card.component';
|
||||
|
||||
const routes: Routes = [{ path: 'list', component: ClientsListComponent },
|
||||
{ path: 'card/:id', component: ClientsCardComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ClientsRoutingModule { }
|
||||
20
front/app/src/app/routes/clients/clients.module.ts
Normal file
20
front/app/src/app/routes/clients/clients.module.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { ClientsRoutingModule } from './clients-routing.module';
|
||||
import { ClientsListComponent } from './list/list.component';
|
||||
import { ClientsCardComponent } from './card/card.component';
|
||||
|
||||
const COMPONENTS: any[] = [ClientsListComponent, ClientsCardComponent];
|
||||
const COMPONENTS_DYNAMIC: any[] = [];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
ClientsRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
...COMPONENTS,
|
||||
...COMPONENTS_DYNAMIC
|
||||
]
|
||||
})
|
||||
export class ClientsModule { }
|
||||
23
front/app/src/app/routes/clients/clients.service.ts
Normal file
23
front/app/src/app/routes/clients/clients.service.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {Client} from "./list/list.component";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ClientsService {
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
public getList(page: number, size: number, sortColumn: string, sortDirection: string) {
|
||||
return this.http.get<{ menu: Client[] }>(
|
||||
`/api/v1/entity/?size=${size}&page=${page + 1}&sort_by=${sortDirection}(${sortColumn})`
|
||||
);
|
||||
}
|
||||
|
||||
public get(id: string) {
|
||||
return this.http.get<{ menu: Client[] }>(
|
||||
`/api/v1/entity/${id}`
|
||||
);
|
||||
}
|
||||
}
|
||||
43
front/app/src/app/routes/clients/list/list.component.html
Normal file
43
front/app/src/app/routes/clients/list/list.component.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<page-header></page-header>
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Filter</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Mia" #input>
|
||||
</mat-form-field>
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 items" matSort (matSortChange)="handleSortChange($event)">
|
||||
<ng-container matColumnDef="_id">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
|
||||
<td mat-cell *matCellDef="let item"> {{item._id}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Nom </th>
|
||||
<td mat-cell *matCellDef="let item"> {{item.name}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Type </th>
|
||||
<td mat-cell *matCellDef="let item"> {{item.type}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="address">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Adresse </th>
|
||||
<td mat-cell *matCellDef="let item"> {{item.address}} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row
|
||||
routerLink="../card/{{row._id}}"
|
||||
*matRowDef="let row; columns: displayedColumns;"
|
||||
></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator (page)="handlePageEvent($event)"
|
||||
[pageSizeOptions]="[5, 10, 15, 25, 50]"
|
||||
[pageSize]="pageSize"
|
||||
[length]="length"
|
||||
showFirstLastButtons
|
||||
aria-label="Select page">
|
||||
</mat-paginator>
|
||||
25
front/app/src/app/routes/clients/list/list.component.spec.ts
Normal file
25
front/app/src/app/routes/clients/list/list.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ClientsListComponent } from './list.component';
|
||||
|
||||
describe('ClientsListComponent', () => {
|
||||
let component: ClientsListComponent;
|
||||
let fixture: ComponentFixture<ClientsListComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ClientsListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ClientsListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
84
front/app/src/app/routes/clients/list/list.component.ts
Normal file
84
front/app/src/app/routes/clients/list/list.component.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||
import { MatSort, Sort} from '@angular/material/sort';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Menu } from "@core";
|
||||
import { BehaviorSubject, forkJoin, fromEvent, Observable } from "rxjs";
|
||||
import { map, take } from "rxjs/operators";
|
||||
import { ClientsService } from '../clients.service'
|
||||
import {Location} from '@angular/common';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
export interface Client {
|
||||
_id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-clients-list',
|
||||
templateUrl: './list.component.html',
|
||||
styleUrls: ['./list.component.css']
|
||||
})
|
||||
export class ClientsListComponent implements OnInit {
|
||||
|
||||
displayedColumns: string[] = ['type', 'name', 'address', '_id',];
|
||||
dataSource: Client[] = [];
|
||||
|
||||
length: number = 0;
|
||||
pageIndex: number = 0;
|
||||
pageSize: number = 15;
|
||||
|
||||
sortColumn: string = "name";
|
||||
sortDirection: string = "asc";
|
||||
|
||||
//@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
constructor(private location: Location, private clientsService: ClientsService, private router: Router) { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
handlePageEvent(e: PageEvent) {
|
||||
this.length = e.length;
|
||||
this.pageSize = e.pageSize;
|
||||
this.pageIndex = e.pageIndex;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
handleSortChange(s: Sort) {
|
||||
this.sortColumn = s.active;
|
||||
this.sortDirection = s.direction;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
handleClickRow(row: any) {
|
||||
window.location.href=window.location.href.replace('list', `card/${row._id}`)
|
||||
this.router.navigateByUrl("card");
|
||||
}
|
||||
|
||||
private getData() {
|
||||
this.clientsService.getList(this.pageIndex, this.pageSize, this.sortColumn, this.sortDirection).subscribe((data: any) => {
|
||||
this.dataSource = data.items;
|
||||
this.length = data.total;
|
||||
this.pageSize = data.size;
|
||||
this.pageIndex = data.page - 1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
applyFilter(event: Event) {
|
||||
// const filterValue = (event.target as HTMLInputElement).value;
|
||||
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
//
|
||||
// if (this.dataSource.paginator) {
|
||||
// this.dataSource.paginator.firstPage();
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ const routes: Routes = [
|
||||
{ path: '403', component: Error403Component },
|
||||
{ path: '404', component: Error404Component },
|
||||
{ path: '500', component: Error500Component },
|
||||
{ path: 'clients', loadChildren: () => import('./clients/clients.module').then(m => m.ClientsModule) },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{
|
||||
"menu": [
|
||||
{
|
||||
"route": "clients/list",
|
||||
"name": "clients",
|
||||
"type": "link",
|
||||
"icon": "group"
|
||||
},
|
||||
{
|
||||
"route": "dashboard",
|
||||
"name": "dashboard",
|
||||
|
||||
Reference in New Issue
Block a user