Add support for creating items, add boolean support in list

Also added subject controller
This commit is contained in:
Norbi Peti 2022-01-30 19:40:33 +01:00
parent 512cbb9af6
commit 3fe37ac6e0
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
9 changed files with 203 additions and 22 deletions

View file

@ -6,3 +6,4 @@ export * from './course-user.controller';
export * from './user-course.controller';
export * from './course-requirement.controller';
export * from './course-requirement.controller';
export * from './subject.controller';

View file

@ -0,0 +1,151 @@
import {
Count,
CountSchema,
Filter,
FilterExcludingWhere,
repository,
Where,
} from '@loopback/repository';
import {
post,
param,
get,
getModelSchemaRef,
patch,
put,
del,
requestBody,
response,
} from '@loopback/rest';
import { Subject } from '../models';
import { SubjectRepository } from '../repositories';
export class SubjectController {
constructor(
@repository(SubjectRepository)
public subjectRepository: SubjectRepository,
) {
}
@post('/subjects')
@response(200, {
description: 'Subject model instance',
content: {'application/json': {schema: getModelSchemaRef(Subject)}},
})
async create(
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Subject, {
title: 'NewSubject',
exclude: ['id'],
}),
},
},
})
subject: Omit<Subject, 'id'>,
): Promise<Subject> {
return this.subjectRepository.create(subject);
}
@get('/subjects/count')
@response(200, {
description: 'Subject model count',
content: {'application/json': {schema: CountSchema}},
})
async count(
@param.where(Subject) where?: Where<Subject>,
): Promise<Count> {
return this.subjectRepository.count(where);
}
@get('/subjects')
@response(200, {
description: 'Array of Subject model instances',
content: {
'application/json': {
schema: {
type: 'array',
items: getModelSchemaRef(Subject, {includeRelations: true}),
},
},
},
})
async find(
@param.filter(Subject) filter?: Filter<Subject>,
): Promise<Subject[]> {
return this.subjectRepository.find(filter);
}
@patch('/subjects')
@response(200, {
description: 'Subject PATCH success count',
content: {'application/json': {schema: CountSchema}},
})
async updateAll(
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Subject, {partial: true}),
},
},
})
subject: Subject,
@param.where(Subject) where?: Where<Subject>,
): Promise<Count> {
return this.subjectRepository.updateAll(subject, where);
}
@get('/subjects/{id}')
@response(200, {
description: 'Subject model instance',
content: {
'application/json': {
schema: getModelSchemaRef(Subject, {includeRelations: true}),
},
},
})
async findById(
@param.path.number('id') id: number,
@param.filter(Subject, {exclude: 'where'}) filter?: FilterExcludingWhere<Subject>
): Promise<Subject> {
return this.subjectRepository.findById(id, filter);
}
@patch('/subjects/{id}')
@response(204, {
description: 'Subject PATCH success',
})
async updateById(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Subject, {partial: true}),
},
},
})
subject: Subject,
): Promise<void> {
await this.subjectRepository.updateById(id, subject);
}
@put('/subjects/{id}')
@response(204, {
description: 'Subject PUT success',
})
async replaceById(
@param.path.number('id') id: number,
@requestBody() subject: Subject,
): Promise<void> {
await this.subjectRepository.replaceById(id, subject);
}
@del('/subjects/{id}')
@response(204, {
description: 'Subject DELETE success',
})
async deleteById(@param.path.number('id') id: number): Promise<void> {
await this.subjectRepository.deleteById(id);
}
}

View file

@ -1,4 +1,4 @@
<div *ngIf="item; else loading">
<div *ngIf="!isLoading; else loading">
<form [formGroup]="formGroup">
<mat-form-field *ngFor="let field of fields">
<mat-label>{{ field.title }}</mat-label>

View file

@ -12,6 +12,7 @@ import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
export class EditComponent<T extends Model> implements OnInit {
item?: T;
isLoading = true;
@Input() apiPath: string;
@Input() fields: { title: string, name: string }[];
@ -23,16 +24,24 @@ export class EditComponent<T extends Model> implements OnInit {
async ngOnInit(): Promise<void> {
this.item = JSON.parse(window.localStorage.getItem(this.router.url));
window.localStorage.removeItem(this.router.url);
if (!this.item) {
const url = this.route.snapshot.url;
if (!this.item && url[url.length - 1].path !== 'new') {
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);
if (this.item) {
this.formGroup.patchValue(this.item);
}
this.isLoading = false;
}
async submit(): Promise<void> {
try {
await this.api.request('patch', this.apiPath + '/' + this.item.id, this.formGroup.value);
if (this.item) {
await this.api.request('patch', this.apiPath + '/' + this.item.id, this.formGroup.value);
} else {
await this.api.request('post', this.apiPath, this.formGroup.value);
}
} catch (e) {
alert(e);
}

View file

@ -1,4 +1,6 @@
<div style="width: 100%; text-align: right; padding-bottom: 10px" *ngIf="allowNew">
<button mat-raised-button color="primary" (click)="newItem()">Hozzáadás</button>
</div>
<app-table [items]="items" (pageChange)="handlePageChange($event)" [paginationData]="paginationData" [columns]="columns"
[loading]="loading" (editItem)="editItem($event)">
</app-table>

View file

@ -15,6 +15,7 @@ export class ListComponent<T extends Model> implements OnInit {
@Input() apiPath: string;
@Input() itemType: Type<T>;
@Input() columns: { title: string, prop: keyof T }[];
@Input() allowNew = false;
paginationData: PaginationData = {};
items: T[] = [];
@ -48,4 +49,8 @@ export class ListComponent<T extends Model> implements OnInit {
window.localStorage.setItem(this.router.url + '/' + item.id, JSON.stringify(item));
await this.router.navigate([this.router.url, item.id]);
}
async newItem(): Promise<void> {
await this.router.navigate([this.router.url, 'new']);
}
}

View file

@ -11,7 +11,7 @@ import { EditComponent } from './edit/edit.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ReactiveFormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { MatCheckboxModule } from '@angular/material/checkbox';
@NgModule({
@ -21,16 +21,18 @@ import { MatInputModule } from '@angular/material/input';
ListComponent,
EditComponent
],
imports: [
CommonModule,
MatProgressBarModule,
MatPaginatorModule,
MatTableModule,
MatButtonModule,
MatIconModule,
MatProgressSpinnerModule,
ReactiveFormsModule,
MatInputModule
]
imports: [
CommonModule,
MatProgressBarModule,
MatPaginatorModule,
MatTableModule,
MatButtonModule,
MatIconModule,
MatProgressSpinnerModule,
ReactiveFormsModule,
MatInputModule,
MatCheckboxModule
]
})
export class SharedComponentsModule { }
export class SharedComponentsModule {
}

View file

@ -8,14 +8,21 @@
<mat-progress-bar mode="indeterminate" *ngIf="loading"></mat-progress-bar>
<table mat-table [dataSource]="items">
<ng-container *ngFor="let col of columns" [matColumnDef]="col.prop">
<th mat-header-cell *matHeaderCellDef>{{col.title}}</th>
<td mat-cell *matCellDef="let item">{{ item[col.prop]}}</td>
<th mat-header-cell *matHeaderCellDef>{{ col.title }}</th>
<td mat-cell *matCellDef="let item">
<span [ngSwitch]="getType(item[col.prop])">
<span *ngSwitchCase="'boolean'"><mat-checkbox [checked]="item[col.prop]"></mat-checkbox></span>
<span *ngSwitchDefault>{{ item[col.prop] }}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<th mat-header-cell *matHeaderCellDef style="width: 2rem"></th>
<td mat-cell *matCellDef="let item">
<button mat-icon-button color="primary" (click)="editItem.emit(item)"><mat-icon>edit</mat-icon></button>
<button mat-icon-button color="primary" (click)="editItem.emit(item)">
<mat-icon>edit</mat-icon>
</button>
</td>
<tr mat-header-row *matHeaderRowDef="getPropNames()"></tr>
<tr mat-row *matRowDef="let row; columns: getPropNames()"></tr>

View file

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import { PaginationData } from '../../utility/pagination-data';
import { PageEvent } from '@angular/material/paginator';
@ -27,6 +27,10 @@ export class TableComponent<T> implements OnInit {
getPropNames(): string[] {
return this.columns.map(col => col.prop).concat('actions');
}
getType(itemElement: any): typeof itemElement {
return typeof itemElement;
}
}