List and Read on frontend, fullecrud on back

This commit is contained in:
2023-01-10 18:48:47 +01:00
parent 399b52a272
commit 0b8a93b256
32 changed files with 623 additions and 51 deletions

View File

@@ -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,
],

View 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));
}
}

View 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>

View 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();
});
});

View 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 {
}
}

View 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 { }

View 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 { }

View 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}`
);
}
}

View 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>

View 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();
});
});

View 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();
// }
}
}

View File

@@ -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) },
],
},
{

View File

@@ -1,5 +1,11 @@
{
"menu": [
{
"route": "clients/list",
"name": "clients",
"type": "link",
"icon": "group"
},
{
"route": "dashboard",
"name": "dashboard",