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 './user-course.controller';
|
||||||
export * from './course-requirement.controller';
|
export * from './course-requirement.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">
|
<form [formGroup]="formGroup">
|
||||||
<mat-form-field *ngFor="let field of fields">
|
<mat-form-field *ngFor="let field of fields">
|
||||||
<mat-label>{{ field.title }}</mat-label>
|
<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 {
|
export class EditComponent<T extends Model> implements OnInit {
|
||||||
|
|
||||||
item?: T;
|
item?: T;
|
||||||
|
isLoading = true;
|
||||||
|
|
||||||
@Input() apiPath: string;
|
@Input() apiPath: string;
|
||||||
@Input() fields: { title: string, name: string }[];
|
@Input() fields: { title: string, name: string }[];
|
||||||
|
@ -23,16 +24,24 @@ export class EditComponent<T extends Model> implements OnInit {
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.item = JSON.parse(window.localStorage.getItem(this.router.url));
|
this.item = JSON.parse(window.localStorage.getItem(this.router.url));
|
||||||
window.localStorage.removeItem(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.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 = 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> {
|
async submit(): Promise<void> {
|
||||||
try {
|
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) {
|
} catch (e) {
|
||||||
alert(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"
|
<app-table [items]="items" (pageChange)="handlePageChange($event)" [paginationData]="paginationData" [columns]="columns"
|
||||||
[loading]="loading" (editItem)="editItem($event)">
|
[loading]="loading" (editItem)="editItem($event)">
|
||||||
|
|
||||||
</app-table>
|
</app-table>
|
||||||
|
|
|
@ -15,6 +15,7 @@ export class ListComponent<T extends Model> implements OnInit {
|
||||||
@Input() apiPath: string;
|
@Input() apiPath: string;
|
||||||
@Input() itemType: Type<T>;
|
@Input() itemType: Type<T>;
|
||||||
@Input() columns: { title: string, prop: keyof T }[];
|
@Input() columns: { title: string, prop: keyof T }[];
|
||||||
|
@Input() allowNew = false;
|
||||||
|
|
||||||
paginationData: PaginationData = {};
|
paginationData: PaginationData = {};
|
||||||
items: T[] = [];
|
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));
|
window.localStorage.setItem(this.router.url + '/' + item.id, JSON.stringify(item));
|
||||||
await this.router.navigate([this.router.url, item.id]);
|
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 { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -21,16 +21,18 @@ import { MatInputModule } from '@angular/material/input';
|
||||||
ListComponent,
|
ListComponent,
|
||||||
EditComponent
|
EditComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule
|
MatInputModule,
|
||||||
]
|
MatCheckboxModule
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class SharedComponentsModule { }
|
export class SharedComponentsModule {
|
||||||
|
}
|
||||||
|
|
|
@ -8,14 +8,21 @@
|
||||||
<mat-progress-bar mode="indeterminate" *ngIf="loading"></mat-progress-bar>
|
<mat-progress-bar mode="indeterminate" *ngIf="loading"></mat-progress-bar>
|
||||||
<table mat-table [dataSource]="items">
|
<table mat-table [dataSource]="items">
|
||||||
<ng-container *ngFor="let col of columns" [matColumnDef]="col.prop">
|
<ng-container *ngFor="let col of columns" [matColumnDef]="col.prop">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{col.title}}</th>
|
<th mat-header-cell *matHeaderCellDef>{{ col.title }}</th>
|
||||||
<td mat-cell *matCellDef="let item">{{ item[col.prop]}}</td>
|
<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>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions" stickyEnd>
|
<ng-container matColumnDef="actions" stickyEnd>
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 2rem"></th>
|
<th mat-header-cell *matHeaderCellDef style="width: 2rem"></th>
|
||||||
<td mat-cell *matCellDef="let item">
|
<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>
|
</td>
|
||||||
<tr mat-header-row *matHeaderRowDef="getPropNames()"></tr>
|
<tr mat-header-row *matHeaderRowDef="getPropNames()"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: 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 { PaginationData } from '../../utility/pagination-data';
|
||||||
import { PageEvent } from '@angular/material/paginator';
|
import { PageEvent } from '@angular/material/paginator';
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ export class TableComponent<T> implements OnInit {
|
||||||
getPropNames(): string[] {
|
getPropNames(): string[] {
|
||||||
return this.columns.map(col => col.prop).concat('actions');
|
return this.columns.map(col => col.prop).concat('actions');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getType(itemElement: any): typeof itemElement {
|
||||||
|
return typeof itemElement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue