From 512cbb9af68d66ebca62bbe1d345cc29cbd23ff9 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 30 Jan 2022 18:13:25 +0100 Subject: [PATCH] Add customizable edit page Adding the item being edited to local storage, so it doesn't have to request it again --- frontend/src/app/api.service.ts | 2 +- frontend/src/app/model/model.ts | 3 ++ frontend/src/app/model/user.model.ts | 4 +- .../shared-components/edit/edit.component.css | 0 .../edit/edit.component.html | 12 ++++++ .../edit/edit.component.spec.ts | 25 +++++++++++ .../shared-components/edit/edit.component.ts | 41 +++++++++++++++++++ .../list/list.component.html | 2 +- .../shared-components/list/list.component.ts | 12 ++++-- .../shared-components.module.ts | 28 ++++++++----- .../table/table.component.html | 2 +- .../table/table.component.ts | 1 + .../users/user-edit/user-edit.component.css | 0 .../users/user-edit/user-edit.component.html | 5 +++ .../user-edit/user-edit.component.spec.ts | 25 +++++++++++ .../users/user-edit/user-edit.component.ts | 15 +++++++ frontend/src/app/users/users.module.ts | 6 ++- 17 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 frontend/src/app/model/model.ts create mode 100644 frontend/src/app/shared-components/edit/edit.component.css create mode 100644 frontend/src/app/shared-components/edit/edit.component.html create mode 100644 frontend/src/app/shared-components/edit/edit.component.spec.ts create mode 100644 frontend/src/app/shared-components/edit/edit.component.ts create mode 100644 frontend/src/app/users/user-edit/user-edit.component.css create mode 100644 frontend/src/app/users/user-edit/user-edit.component.html create mode 100644 frontend/src/app/users/user-edit/user-edit.component.spec.ts create mode 100644 frontend/src/app/users/user-edit/user-edit.component.ts diff --git a/frontend/src/app/api.service.ts b/frontend/src/app/api.service.ts index 3e58d3a..9821f22 100644 --- a/frontend/src/app/api.service.ts +++ b/frontend/src/app/api.service.ts @@ -11,7 +11,7 @@ export class ApiService { constructor(private http: HttpClient, private loginService: LoginService) { } - request(method: 'post' | 'get' | 'delete', url: string, body: any): Promise { + request(method: 'post' | 'get' | 'delete' | 'patch', url: string, body: any): Promise { return this.http.request(method, environment.backendUrl + url, { body, headers: {Authorization: 'Bearer ' + this.loginService.token} diff --git a/frontend/src/app/model/model.ts b/frontend/src/app/model/model.ts new file mode 100644 index 0000000..26ef6b8 --- /dev/null +++ b/frontend/src/app/model/model.ts @@ -0,0 +1,3 @@ +export class Model { + id: number; +} diff --git a/frontend/src/app/model/user.model.ts b/frontend/src/app/model/user.model.ts index 161b589..4f5d31c 100644 --- a/frontend/src/app/model/user.model.ts +++ b/frontend/src/app/model/user.model.ts @@ -1,4 +1,6 @@ -export class User { +import { Model } from './model'; + +export class User extends Model { name: string; isAdmin: boolean; } diff --git a/frontend/src/app/shared-components/edit/edit.component.css b/frontend/src/app/shared-components/edit/edit.component.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/shared-components/edit/edit.component.html b/frontend/src/app/shared-components/edit/edit.component.html new file mode 100644 index 0000000..fafa8dc --- /dev/null +++ b/frontend/src/app/shared-components/edit/edit.component.html @@ -0,0 +1,12 @@ +
+
+ + {{ field.title }} + + + +
+
+ + + diff --git a/frontend/src/app/shared-components/edit/edit.component.spec.ts b/frontend/src/app/shared-components/edit/edit.component.spec.ts new file mode 100644 index 0000000..5a24d45 --- /dev/null +++ b/frontend/src/app/shared-components/edit/edit.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditComponent } from './edit.component'; + +describe('EditComponent', () => { + let component: EditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EditComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/shared-components/edit/edit.component.ts b/frontend/src/app/shared-components/edit/edit.component.ts new file mode 100644 index 0000000..bffc5ab --- /dev/null +++ b/frontend/src/app/shared-components/edit/edit.component.ts @@ -0,0 +1,41 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ApiService } from '../../api.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Model } from '../../model/model'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; + +@Component({ + selector: 'app-edit', + templateUrl: './edit.component.html', + styleUrls: ['./edit.component.css'] +}) +export class EditComponent implements OnInit { + + item?: T; + + @Input() apiPath: string; + @Input() fields: { title: string, name: string }[]; + formGroup: FormGroup; + + constructor(private api: ApiService, private router: Router, private fb: FormBuilder, private route: ActivatedRoute) { + } + + async ngOnInit(): Promise { + this.item = JSON.parse(window.localStorage.getItem(this.router.url)); + window.localStorage.removeItem(this.router.url); + if (!this.item) { + this.item = await this.api.request('get', this.apiPath + '/' + this.route.snapshot.url[this.route.snapshot.url.length - 1], {}); + } + this.formGroup = this.fb.group(this.fields.reduce((pv, cv) => Object.assign(pv, {[cv.name]: new FormControl()}), {})); + this.formGroup.patchValue(this.item); + } + + async submit(): Promise { + try { + await this.api.request('patch', this.apiPath + '/' + this.item.id, this.formGroup.value); + } catch (e) { + alert(e); + } + } + +} diff --git a/frontend/src/app/shared-components/list/list.component.html b/frontend/src/app/shared-components/list/list.component.html index cf1ed1d..e70c98b 100644 --- a/frontend/src/app/shared-components/list/list.component.html +++ b/frontend/src/app/shared-components/list/list.component.html @@ -1,4 +1,4 @@ + [loading]="loading" (editItem)="editItem($event)"> diff --git a/frontend/src/app/shared-components/list/list.component.ts b/frontend/src/app/shared-components/list/list.component.ts index 65dfb3c..c512af2 100644 --- a/frontend/src/app/shared-components/list/list.component.ts +++ b/frontend/src/app/shared-components/list/list.component.ts @@ -2,23 +2,25 @@ import { Component, Input, OnInit, Type } from '@angular/core'; import { PageEvent } from '@angular/material/paginator'; import { PaginationData } from '../../utility/pagination-data'; import { ApiService } from '../../api.service'; +import { Model } from '../../model/model'; +import { Router } from '@angular/router'; @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.css'] }) -export class ListComponent implements OnInit { +export class ListComponent implements OnInit { @Input() apiPath: string; @Input() itemType: Type; - @Input() columns: {title: string, prop: keyof T}[]; + @Input() columns: { title: string, prop: keyof T }[]; paginationData: PaginationData = {}; items: T[] = []; loading = false; - constructor(private api: ApiService) { + constructor(private api: ApiService, private router: Router) { } ngOnInit(): void { @@ -42,4 +44,8 @@ export class ListComponent implements OnInit { } } + async editItem(item: T): Promise { + window.localStorage.setItem(this.router.url + '/' + item.id, JSON.stringify(item)); + await this.router.navigate([this.router.url, item.id]); + } } diff --git a/frontend/src/app/shared-components/shared-components.module.ts b/frontend/src/app/shared-components/shared-components.module.ts index 53d355b..707f942 100644 --- a/frontend/src/app/shared-components/shared-components.module.ts +++ b/frontend/src/app/shared-components/shared-components.module.ts @@ -7,22 +7,30 @@ import { MatTableModule } from '@angular/material/table'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { ListComponent } from './list/list.component'; +import { EditComponent } from './edit/edit.component'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; @NgModule({ - declarations: [TableComponent, ListComponent], + declarations: [TableComponent, ListComponent, EditComponent], exports: [ TableComponent, - ListComponent + ListComponent, + EditComponent ], - imports: [ - CommonModule, - MatProgressBarModule, - MatPaginatorModule, - MatTableModule, - MatButtonModule, - MatIconModule - ] + imports: [ + CommonModule, + MatProgressBarModule, + MatPaginatorModule, + MatTableModule, + MatButtonModule, + MatIconModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + MatInputModule + ] }) export class SharedComponentsModule { } diff --git a/frontend/src/app/shared-components/table/table.component.html b/frontend/src/app/shared-components/table/table.component.html index 2368d2d..fa84a88 100644 --- a/frontend/src/app/shared-components/table/table.component.html +++ b/frontend/src/app/shared-components/table/table.component.html @@ -15,7 +15,7 @@ - + diff --git a/frontend/src/app/shared-components/table/table.component.ts b/frontend/src/app/shared-components/table/table.component.ts index 95dbc86..eb6b62b 100644 --- a/frontend/src/app/shared-components/table/table.component.ts +++ b/frontend/src/app/shared-components/table/table.component.ts @@ -16,6 +16,7 @@ export class TableComponent implements OnInit { @Input() paginationData: PaginationData = {page: 1, limit: 10}; @Output() pageChange = new EventEmitter(); + @Output() editItem = new EventEmitter(); constructor() { } diff --git a/frontend/src/app/users/user-edit/user-edit.component.css b/frontend/src/app/users/user-edit/user-edit.component.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/users/user-edit/user-edit.component.html b/frontend/src/app/users/user-edit/user-edit.component.html new file mode 100644 index 0000000..41d922f --- /dev/null +++ b/frontend/src/app/users/user-edit/user-edit.component.html @@ -0,0 +1,5 @@ + diff --git a/frontend/src/app/users/user-edit/user-edit.component.spec.ts b/frontend/src/app/users/user-edit/user-edit.component.spec.ts new file mode 100644 index 0000000..0b9e97f --- /dev/null +++ b/frontend/src/app/users/user-edit/user-edit.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UserEditComponent } from './user-edit.component'; + +describe('UserEditComponent', () => { + let component: UserEditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ UserEditComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(UserEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/users/user-edit/user-edit.component.ts b/frontend/src/app/users/user-edit/user-edit.component.ts new file mode 100644 index 0000000..dfbf03c --- /dev/null +++ b/frontend/src/app/users/user-edit/user-edit.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-user-edit', + templateUrl: './user-edit.component.html', + styleUrls: ['./user-edit.component.css'] +}) +export class UserEditComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/users/users.module.ts b/frontend/src/app/users/users.module.ts index d33c004..e793e09 100644 --- a/frontend/src/app/users/users.module.ts +++ b/frontend/src/app/users/users.module.ts @@ -4,13 +4,15 @@ import { UserListComponent } from './user-list/user-list.component'; import { RouterModule, Routes } from '@angular/router'; import { RouteData } from '../app-routing.module'; import { SharedComponentsModule } from '../shared-components/shared-components.module'; +import { UserEditComponent } from './user-edit/user-edit.component'; const routes: Routes = [ - {path: '', component: UserListComponent, data: {title: 'Felhasználók'} as RouteData} + {path: '', component: UserListComponent, data: {title: 'Felhasználók'} as RouteData}, + {path: ':id', component: UserEditComponent, data: {title: 'Szerkesztés'}} ]; @NgModule({ - declarations: [UserListComponent], + declarations: [UserListComponent, UserEditComponent], imports: [ CommonModule, RouterModule.forChild(routes),