Add support for creating items, add boolean support in list
Also added subject controller
This commit is contained in:
parent
512cbb9af6
commit
3fe37ac6e0
9 changed files with 203 additions and 22 deletions
|
@ -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';
|
||||
|
|
151
backend/src/controllers/subject.controller.ts
Normal file
151
backend/src/controllers/subject.controller.ts
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue