Separate create inputs, add fulfillment mode creation on course page
This commit is contained in:
parent
832cf07aa5
commit
744cc29346
26 changed files with 184 additions and 100 deletions
|
@ -3,7 +3,7 @@ import { CourseRepository, SubjectRepository, UserRepository } from '../reposito
|
||||||
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
||||||
import { Course } from '../models';
|
import { Course } from '../models';
|
||||||
import { listResponse, ListResponse } from '../graphql-types/list';
|
import { listResponse, ListResponse } from '../graphql-types/list';
|
||||||
import { CourseList, CourseUpdateInput } from '../graphql-types/course';
|
import { CourseCreateInput, CourseList, CourseUpdateInput } from '../graphql-types/course';
|
||||||
|
|
||||||
@resolver(of => Course)
|
@resolver(of => Course)
|
||||||
export class CourseResolver {
|
export class CourseResolver {
|
||||||
|
@ -36,7 +36,7 @@ export class CourseResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@mutation(returns => Boolean)
|
@mutation(returns => Boolean)
|
||||||
async courseCreate(@arg('course') input: CourseUpdateInput): Promise<boolean> {
|
async courseCreate(@arg('course') input: CourseCreateInput): Promise<boolean> {
|
||||||
await this.courseRepo.create(input);
|
await this.courseRepo.create(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { CourseRepository, FulfillmentModeRepository, UserRepository } from '../
|
||||||
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
||||||
import { FulfillmentMode } from '../models';
|
import { FulfillmentMode } from '../models';
|
||||||
import { listResponse, ListResponse } from '../graphql-types/list';
|
import { listResponse, ListResponse } from '../graphql-types/list';
|
||||||
import { FulfillmentModeList, FulfillmentModeUpdateInput } from '../graphql-types/fulfillment-mode';
|
import { FulfillmentModeCreateInput, FulfillmentModeList, FulfillmentModeUpdateInput } from '../graphql-types/fulfillment-mode';
|
||||||
|
|
||||||
@resolver(of => FulfillmentMode)
|
@resolver(of => FulfillmentMode)
|
||||||
export class FulfillmentModeResolver {
|
export class FulfillmentModeResolver {
|
||||||
|
@ -31,7 +31,7 @@ export class FulfillmentModeResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@mutation(returns => Boolean)
|
@mutation(returns => Boolean)
|
||||||
async fulfillmentModeCreate(@arg('input') input: FulfillmentModeUpdateInput): Promise<boolean> {
|
async fulfillmentModeCreate(@arg('input') input: FulfillmentModeCreateInput): Promise<boolean> {
|
||||||
await this.fulfillmentModeRepo.create(input);
|
await this.fulfillmentModeRepo.create(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { FulfillmentModeRepository, RequirementRepository, UserRepository } from
|
||||||
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
import { arg, ID, Int, mutation, query, resolver } from '@loopback/graphql';
|
||||||
import { Requirement } from '../models';
|
import { Requirement } from '../models';
|
||||||
import { listResponse, ListResponse } from '../graphql-types/list';
|
import { listResponse, ListResponse } from '../graphql-types/list';
|
||||||
import { RequirementList, RequirementUpdateInput } from '../graphql-types/requirement';
|
import { RequirementCreateInput, RequirementList, RequirementUpdateInput } from '../graphql-types/requirement';
|
||||||
|
|
||||||
@resolver(of => Requirement)
|
@resolver(of => Requirement)
|
||||||
export class RequirementResolver {
|
export class RequirementResolver {
|
||||||
|
@ -31,7 +31,7 @@ export class RequirementResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@mutation(returns => Boolean)
|
@mutation(returns => Boolean)
|
||||||
async requirementCreate(@arg('requirement') input: RequirementUpdateInput): Promise<boolean> {
|
async requirementCreate(@arg('requirement') input: RequirementCreateInput): Promise<boolean> {
|
||||||
await this.requirementRepo.create(input);
|
await this.requirementRepo.create(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Subject } from '../models';
|
||||||
import { SubjectRepository } from '../repositories';
|
import { SubjectRepository } from '../repositories';
|
||||||
import { repository } from '@loopback/repository';
|
import { repository } from '@loopback/repository';
|
||||||
import { listResponse, ListResponse } from '../graphql-types/list';
|
import { listResponse, ListResponse } from '../graphql-types/list';
|
||||||
import { SubjectList, SubjectUpdateInput } from '../graphql-types/subject';
|
import { SubjectCreateInput, SubjectList, SubjectUpdateInput } from '../graphql-types/subject';
|
||||||
|
|
||||||
@resolver(of => Subject)
|
@resolver(of => Subject)
|
||||||
export class SubjectResolver {
|
export class SubjectResolver {
|
||||||
|
@ -27,7 +27,7 @@ export class SubjectResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@mutation(returns => Boolean)
|
@mutation(returns => Boolean)
|
||||||
async subjectCreate(@arg('subject') input: SubjectUpdateInput): Promise<boolean> {
|
async subjectCreate(@arg('subject') input: SubjectCreateInput): Promise<boolean> {
|
||||||
await this.subjectRepo.create(input);
|
await this.subjectRepo.create(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@ export class CourseList implements ListResponse<Course> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@inputType()
|
@inputType()
|
||||||
export class CourseUpdateInput implements Pick<DataObject<Course>, 'id' | 'semester' | 'alias' | 'subjectId'> {
|
export class CourseCreateInput implements Pick<DataObject<Course>, 'semester' | 'alias' | 'subjectId'> {
|
||||||
@field(returns => ID)
|
|
||||||
id: number;
|
|
||||||
@field()
|
@field()
|
||||||
semester?: string;
|
semester?: string;
|
||||||
@field()
|
@field()
|
||||||
|
@ -22,3 +20,9 @@ export class CourseUpdateInput implements Pick<DataObject<Course>, 'id' | 'semes
|
||||||
@field()
|
@field()
|
||||||
subjectId?: number;
|
subjectId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inputType()
|
||||||
|
export class CourseUpdateInput extends CourseCreateInput {
|
||||||
|
@field(returns => ID)
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ListResponse } from './list';
|
import { ListResponse } from './list';
|
||||||
import { FulfillmentMode } from '../models';
|
import { FulfillmentMode } from '../models';
|
||||||
import { field, inputType, Int, objectType } from '@loopback/graphql';
|
import { field, ID, inputType, Int, objectType } from '@loopback/graphql';
|
||||||
import { DataObject } from '@loopback/repository';
|
import { DataObject } from '@loopback/repository';
|
||||||
|
|
||||||
@objectType()
|
@objectType()
|
||||||
|
@ -12,9 +12,7 @@ export class FulfillmentModeList implements ListResponse<FulfillmentMode> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@inputType()
|
@inputType()
|
||||||
export class FulfillmentModeUpdateInput implements Omit<DataObject<FulfillmentMode>, 'requirements' | 'courseId'> {
|
export class FulfillmentModeCreateInput implements Omit<DataObject<FulfillmentMode>, 'requirements' | 'courseId'> {
|
||||||
@field(returns => Int)
|
|
||||||
id: number;
|
|
||||||
@field()
|
@field()
|
||||||
name: string;
|
name: string;
|
||||||
@field()
|
@field()
|
||||||
|
@ -25,4 +23,12 @@ export class FulfillmentModeUpdateInput implements Omit<DataObject<FulfillmentMo
|
||||||
threshold4: number;
|
threshold4: number;
|
||||||
@field()
|
@field()
|
||||||
threshold5: number;
|
threshold5: number;
|
||||||
|
@field(returns => ID)
|
||||||
|
courseId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@inputType()
|
||||||
|
export class FulfillmentModeUpdateInput extends FulfillmentModeCreateInput {
|
||||||
|
@field(returns => ID)
|
||||||
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@ export class RequirementList implements ListResponse<Requirement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@inputType()
|
@inputType()
|
||||||
export class RequirementUpdateInput implements Pick<DataObject<Requirement>, 'id' | 'name' | 'description' | 'deadline' | 'minPoints' | 'maxPoints'> {
|
export class RequirementCreateInput implements Pick<DataObject<Requirement>, 'name' | 'description' | 'deadline' | 'minPoints' | 'maxPoints'> {
|
||||||
@field(returns => Int)
|
|
||||||
id: number;
|
|
||||||
@field()
|
@field()
|
||||||
deadline: Date;
|
deadline: Date;
|
||||||
@field()
|
@field()
|
||||||
|
@ -26,3 +24,9 @@ export class RequirementUpdateInput implements Pick<DataObject<Requirement>, 'id
|
||||||
@field()
|
@field()
|
||||||
maxPoints: number;
|
maxPoints: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inputType()
|
||||||
|
export class RequirementUpdateInput extends RequirementCreateInput {
|
||||||
|
@field(returns => Int)
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
|
@ -12,11 +12,15 @@ export class SubjectList implements ListResponse<Subject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@inputType()
|
@inputType()
|
||||||
export class SubjectUpdateInput implements Pick<DataObject<Subject>, 'id' | 'name' | 'description'> {
|
export class SubjectCreateInput implements Pick<DataObject<Subject>, 'name' | 'description'> {
|
||||||
@field(returns => ID)
|
|
||||||
id: number;
|
|
||||||
@field()
|
@field()
|
||||||
name?: string;
|
name?: string;
|
||||||
@field()
|
@field()
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inputType()
|
||||||
|
export class SubjectUpdateInput extends SubjectCreateInput {
|
||||||
|
@field(returns => ID)
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,6 @@ mutation EditCourse($input: CourseUpdateInput!) {
|
||||||
courseUpdate(course: $input)
|
courseUpdate(course: $input)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation CreateCourse($input: CourseUpdateInput!) {
|
mutation CreateCourse($input: CourseCreateInput!) {
|
||||||
courseCreate(course: $input)
|
courseCreate(course: $input)
|
||||||
}
|
}
|
||||||
|
|
31
frontend/src/app/graphql/fulfillment-mode.graphql
Normal file
31
frontend/src/app/graphql/fulfillment-mode.graphql
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
query FulfillmentModeList($course: ID!, $offset: Int!, $limit: Int!) {
|
||||||
|
fulfillmentModes(course: $course, offset: $offset, limit: $limit) {
|
||||||
|
list {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
threshold2
|
||||||
|
threshold3
|
||||||
|
threshold4
|
||||||
|
threshold5
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query FulfillmentMode($id: ID!) {
|
||||||
|
fulfillmentMode(id: $id) {
|
||||||
|
id
|
||||||
|
threshold2
|
||||||
|
threshold3
|
||||||
|
threshold4
|
||||||
|
threshold5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation EditFulfillmentMode($input: FulfillmentModeUpdateInput!) {
|
||||||
|
fulfillmentModeUpdate(input: $input)
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation CreateFulfillmentMode($input: FulfillmentModeCreateInput!) {
|
||||||
|
fulfillmentModeCreate(input: $input)
|
||||||
|
}
|
|
@ -27,6 +27,6 @@ mutation EditRequirement($input: RequirementUpdateInput!) {
|
||||||
requirementUpdate(requirement: $input)
|
requirementUpdate(requirement: $input)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation CreateRequirement($input: RequirementUpdateInput!) {
|
mutation CreateRequirement($input: RequirementCreateInput!) {
|
||||||
requirementCreate(requirement: $input)
|
requirementCreate(requirement: $input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,6 @@ mutation EditSubject($input: SubjectUpdateInput!) {
|
||||||
subjectUpdate(subject: $input)
|
subjectUpdate(subject: $input)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation CreateSubject($input: SubjectUpdateInput!) {
|
mutation CreateSubject($input: SubjectCreateInput!) {
|
||||||
subjectCreate(subject: $input)
|
subjectCreate(subject: $input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<app-list [gql]="listGQL"></app-list>
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { RequirementListComponent } from './requirement-list.component';
|
|
||||||
|
|
||||||
describe('RequirementsListComponent', () => {
|
|
||||||
let component: RequirementListComponent;
|
|
||||||
let fixture: ComponentFixture<RequirementListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [RequirementListComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(RequirementListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { RequirementListGQL } from '../../services/graphql';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-requirement-list',
|
|
||||||
templateUrl: './requirement-list.component.html',
|
|
||||||
styleUrls: ['./requirement-list.component.css']
|
|
||||||
})
|
|
||||||
export class RequirementListComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor(public listGQL: RequirementListGQL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { RequirementListComponent } from './requirement-list/requirement-list.component';
|
|
||||||
import { SharedComponentsModule } from '../shared-components/shared-components.module';
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [RequirementListComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
SharedComponentsModule
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class RequirementsModule {
|
|
||||||
}
|
|
|
@ -10,7 +10,8 @@ import { HasID, MutationInput, QueryResult } from '../../utility/types';
|
||||||
templateUrl: './edit.component.html',
|
templateUrl: './edit.component.html',
|
||||||
styleUrls: ['./edit.component.css']
|
styleUrls: ['./edit.component.css']
|
||||||
})
|
})
|
||||||
export class EditComponent<T extends HasID, QT extends QueryResult<T>, UT extends QueryResult<T>, CT extends QueryResult<T>, MI extends Partial<T>>
|
export class EditComponent<T extends HasID, QT extends QueryResult<T>, UT extends QueryResult<T>, CT extends QueryResult<T>,
|
||||||
|
MIC extends Partial<T>, MIU extends Partial<T>>
|
||||||
implements OnInit {
|
implements OnInit {
|
||||||
|
|
||||||
item?: T;
|
item?: T;
|
||||||
|
@ -18,14 +19,16 @@ export class EditComponent<T extends HasID, QT extends QueryResult<T>, UT extend
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
|
|
||||||
@Input() gql: Query<QT, HasID>;
|
@Input() gql: Query<QT, HasID>;
|
||||||
@Input() updateMutation: Mutation<UT, MutationInput<MI, T>>;
|
@Input() updateMutation: Mutation<UT, MutationInput<MIU, T>>;
|
||||||
@Input() createMutation: Mutation<CT, MutationInput<MI, T>>;
|
@Input() createMutation: Mutation<CT, MutationInput<MIC, T>>;
|
||||||
@Input() fields: { title: string, name: keyof T, readonly?: (item: T) => boolean }[];
|
@Input() fields: { title: string, name: keyof T, readonly?: (item: T) => boolean }[];
|
||||||
@Input() itemType: T;
|
@Input() itemType: T;
|
||||||
/**
|
/**
|
||||||
* Beküldés előtt extra adat hozzáadása
|
* Beküldés előtt extra adat hozzáadása
|
||||||
*/
|
*/
|
||||||
@Input() beforeSubmit: (item: T) => Partial<T>;
|
@Input() beforeSubmit: (item: T) => Partial<T>;
|
||||||
|
@Input() customItem: T;
|
||||||
|
@Input() itemSubmitted: (item: T) => void = this.navigateAfterSubmit;
|
||||||
formGroup: FormGroup;
|
formGroup: FormGroup;
|
||||||
|
|
||||||
private key: string;
|
private key: string;
|
||||||
|
@ -37,8 +40,9 @@ export class EditComponent<T extends HasID, QT extends QueryResult<T>, UT extend
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
window.localStorage.removeItem(this.router.url);
|
window.localStorage.removeItem(this.router.url);
|
||||||
const url = this.route.snapshot.url;
|
const url = this.route.snapshot.url;
|
||||||
this.id = this.route.snapshot.url[this.route.snapshot.url.length - 1] + '';
|
this.item = this.customItem;
|
||||||
if (!this.item && url[url.length - 1].path !== 'new') {
|
this.id = this.item?.id ?? this.gql ? url[url.length - 1].path : 'new';
|
||||||
|
if (!this.item && this.id !== 'new' && this.gql) {
|
||||||
const data = (await this.gql.fetch({id: this.id}).toPromise()).data;
|
const data = (await this.gql.fetch({id: this.id}).toPromise()).data;
|
||||||
this.key = Object.keys(data).filter(k => k !== '__typename')[0];
|
this.key = Object.keys(data).filter(k => k !== '__typename')[0];
|
||||||
this.item = data[this.key];
|
this.item = data[this.key];
|
||||||
|
@ -66,20 +70,23 @@ export class EditComponent<T extends HasID, QT extends QueryResult<T>, UT extend
|
||||||
|
|
||||||
async submit(): Promise<void> {
|
async submit(): Promise<void> {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
const input = Object.assign({}, this.formGroup.value, (this.beforeSubmit ?? noop)(this.item) ?? {}, {id: this.id}) as MI;
|
const input = Object.assign({}, this.formGroup.value, (this.beforeSubmit ?? noop)(this.formGroup.value) ?? {}, this.id === 'new' ? {} : {id: this.id});
|
||||||
try {
|
try {
|
||||||
if (this.item && !this.creating) {
|
if (this.item && !this.creating) {
|
||||||
await this.updateMutation.mutate({input}).toPromise();
|
await this.updateMutation.mutate({input}).toPromise();
|
||||||
} else {
|
} else {
|
||||||
await this.createMutation.mutate({input}).toPromise();
|
await this.createMutation.mutate({input}).toPromise();
|
||||||
}
|
}
|
||||||
await this.router.navigate(['..'], {relativeTo: this.route});
|
this.itemSubmitted(this.item);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e.message);
|
|
||||||
} // TODO: Clear/update cache
|
} // TODO: Clear/update cache
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async navigateAfterSubmit(item: T): Promise<void> {
|
||||||
|
await this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
|
}
|
||||||
|
|
||||||
getType(itemElement: any): typeof itemElement {
|
getType(itemElement: any): typeof itemElement {
|
||||||
return typeof itemElement;
|
return typeof itemElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div style="width: 100%; text-align: right; padding-bottom: 10px" *ngIf="allowNew">
|
<div style="width: 100%; text-align: right; padding-bottom: 10px" *ngIf="allowNew">
|
||||||
<button mat-raised-button color="primary" (click)="newItem()">Hozzáadás</button>
|
<button mat-raised-button color="primary" (click)="createFunction()">Hozzáadás</button>
|
||||||
</div>
|
</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)" [customActions]="customActions"
|
[loading]="loading" (editItem)="editFunction($event)" [customActions]="customActions"
|
||||||
[allowEditing]="allowEditing">
|
[allowEditing]="allowEditing">
|
||||||
</app-table>
|
</app-table>
|
||||||
|
|
|
@ -20,6 +20,8 @@ export class ListComponent<T extends { id: number }, U extends { [entityName: st
|
||||||
@Input() allowNew = false;
|
@Input() allowNew = false;
|
||||||
@Input() customActions: { icon: string, label: string, action: (model: T) => void }[] = [];
|
@Input() customActions: { icon: string, label: string, action: (model: T) => void }[] = [];
|
||||||
@Input() allowEditing = true;
|
@Input() allowEditing = true;
|
||||||
|
@Input() editFunction = this.editItem;
|
||||||
|
@Input() createFunction = this.newItem;
|
||||||
|
|
||||||
paginationData: PaginationData = {};
|
paginationData: PaginationData = {};
|
||||||
items: T[] = [];
|
items: T[] = [];
|
||||||
|
@ -52,7 +54,6 @@ export class ListComponent<T extends { id: number }, U extends { [entityName: st
|
||||||
}
|
}
|
||||||
|
|
||||||
async editItem(item: T): Promise<void> {
|
async editItem(item: T): Promise<void> {
|
||||||
window.localStorage.setItem(this.router.url + '/' + item.id, JSON.stringify(item)); // TODO: Apollo cache
|
|
||||||
await this.router.navigate([this.router.url, item.id]);
|
await this.router.navigate([this.router.url, item.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,31 @@
|
||||||
<app-edit [beforeSubmit]="beforeSubmit" [gql]="itemGQL" [itemType]="itemType" [updateMutation]="editGQL" [fields]="[
|
<app-edit [beforeSubmit]="beforeSubmit" [gql]="itemGQL" [itemType]="itemType" [updateMutation]="editGQL"
|
||||||
|
[createMutation]="createGQL" [fields]="[
|
||||||
{title: 'Félév', name: 'semester'},
|
{title: 'Félév', name: 'semester'},
|
||||||
{title: 'Név', name: 'alias'}
|
{title: 'Név', name: 'alias'}
|
||||||
]"></app-edit>
|
]"></app-edit>
|
||||||
|
<mat-card style="margin-top: 50px">
|
||||||
|
<mat-card-header>
|
||||||
|
<h3>Teljesitési módok</h3>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<app-list [gql]="modeListGQL" [queryVariables]="{course: courseId}" [columns]="[
|
||||||
|
{prop: 'name', title: 'Név'}
|
||||||
|
]" allowEditing="true" allowNew="true" [editFunction]="editFulMode.bind(this)"
|
||||||
|
[createFunction]="createFulMode.bind(this)"></app-list>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
<mat-card *ngIf="editingFulMode">
|
||||||
|
<mat-card-header>
|
||||||
|
{{ editedFulMode?.name || 'Új teljesitési mód' }}
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<app-edit [itemType]="editedFulMode" [createMutation]="modeCreateGQL"
|
||||||
|
[updateMutation]="modeEditGQL" [customItem]="editedFulMode" [fields]="[
|
||||||
|
{name: 'name', title: 'Név'},
|
||||||
|
{name: 'threshold2', title: 'Kettes %'},
|
||||||
|
{name: 'threshold3', title: 'Hármas %'},
|
||||||
|
{name: 'threshold4', title: 'Négyes %'},
|
||||||
|
{name: 'threshold5', title: 'Ötös %'}
|
||||||
|
]" [beforeSubmit]="beforeFulModeSubmit.bind(this)" [itemSubmitted]="submitFulMode.bind(this)"></app-edit>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { CustomTitleComponent } from '../../../../app.component';
|
import { CustomTitleComponent } from '../../../../app.component';
|
||||||
import { Course, CourseGQL, EditCourseGQL, SubjectGQL } from '../../../../services/graphql';
|
import {
|
||||||
|
Course,
|
||||||
|
CourseGQL,
|
||||||
|
CreateCourseGQL,
|
||||||
|
CreateFulfillmentModeGQL,
|
||||||
|
EditCourseGQL,
|
||||||
|
EditFulfillmentModeGQL,
|
||||||
|
FulfillmentMode,
|
||||||
|
FulfillmentModeGQL,
|
||||||
|
FulfillmentModeListGQL,
|
||||||
|
FulfillmentModeUpdateInput,
|
||||||
|
SubjectGQL
|
||||||
|
} from '../../../../services/graphql';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-course-edit',
|
selector: 'app-course-edit',
|
||||||
|
@ -11,10 +23,17 @@ import { Course, CourseGQL, EditCourseGQL, SubjectGQL } from '../../../../servic
|
||||||
export class CourseEditComponent implements OnInit, CustomTitleComponent {
|
export class CourseEditComponent implements OnInit, CustomTitleComponent {
|
||||||
subjectId: string;
|
subjectId: string;
|
||||||
itemType: Course;
|
itemType: Course;
|
||||||
|
courseId: string;
|
||||||
|
editedFulMode: FulfillmentMode;
|
||||||
|
editingFulMode = false;
|
||||||
beforeSubmit = () => ({subjectId: +this.route.snapshot.params.subjectId});
|
beforeSubmit = () => ({subjectId: +this.route.snapshot.params.subjectId});
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, public subjectGQL: SubjectGQL, public itemGQL: CourseGQL, public editGQL: EditCourseGQL) {
|
constructor(private route: ActivatedRoute, public subjectGQL: SubjectGQL,
|
||||||
|
public itemGQL: CourseGQL, public editGQL: EditCourseGQL, public createGQL: CreateCourseGQL,
|
||||||
|
public modeListGQL: FulfillmentModeListGQL, public modeItemGQL: FulfillmentModeGQL, public modeEditGQL: EditFulfillmentModeGQL,
|
||||||
|
public modeCreateGQL: CreateFulfillmentModeGQL) {
|
||||||
this.subjectId = route.snapshot.params.subjectId;
|
this.subjectId = route.snapshot.params.subjectId;
|
||||||
|
this.courseId = route.snapshot.params.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@ -24,4 +43,34 @@ export class CourseEditComponent implements OnInit, CustomTitleComponent {
|
||||||
return this.subjectGQL.fetch({id: this.subjectId}).toPromise().then(subject => ({subjectName: subject.data.subject.name}));
|
return this.subjectGQL.fetch({id: this.subjectId}).toPromise().then(subject => ({subjectName: subject.data.subject.name}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async editFulMode(item: FulfillmentMode): Promise<void> {
|
||||||
|
this.editedFulMode = item;
|
||||||
|
this.editingFulMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async createFulMode(): Promise<void> {
|
||||||
|
this.editedFulMode = null;
|
||||||
|
this.editingFulMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeFulModeSubmit(item: FulfillmentMode): Partial<FulfillmentModeUpdateInput> {
|
||||||
|
function thresh(prop: keyof typeof item): void {
|
||||||
|
let val = item[prop];
|
||||||
|
if (val < 0) {
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
((item[prop]) as number) = val > 1 ? val as number / 100 : +val;
|
||||||
|
}
|
||||||
|
|
||||||
|
thresh('threshold2');
|
||||||
|
thresh('threshold3');
|
||||||
|
thresh('threshold4');
|
||||||
|
thresh('threshold5');
|
||||||
|
return {...item, courseId: this.courseId};
|
||||||
|
}
|
||||||
|
|
||||||
|
submitFulMode(): void {
|
||||||
|
this.editedFulMode = null;
|
||||||
|
this.editingFulMode = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<app-edit [gql]="itemGQL" [itemType]="itemType" [fields]="[
|
<app-edit [gql]="itemGQL" [itemType]="itemType" [fields]="[
|
||||||
{title: 'Név', name: 'name'},
|
{title: 'Név', name: 'name'},
|
||||||
{title: 'Leirás', name: 'description'}
|
{title: 'Leirás', name: 'description'}
|
||||||
]" [updateMutation]="updateGQL"></app-edit>
|
]" [updateMutation]="updateGQL" [createMutation]="createGQL"></app-edit>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { EditSubjectGQL, Subject, SubjectGQL } from '../../services/graphql';
|
import { CreateSubjectGQL, EditSubjectGQL, Subject, SubjectGQL } from '../../services/graphql';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-subject-edit',
|
selector: 'app-subject-edit',
|
||||||
|
@ -9,7 +9,7 @@ import { EditSubjectGQL, Subject, SubjectGQL } from '../../services/graphql';
|
||||||
export class SubjectEditComponent implements OnInit {
|
export class SubjectEditComponent implements OnInit {
|
||||||
itemType: Subject;
|
itemType: Subject;
|
||||||
|
|
||||||
constructor(public itemGQL: SubjectGQL, public updateGQL: EditSubjectGQL) {
|
constructor(public itemGQL: SubjectGQL, public updateGQL: EditSubjectGQL, public createGQL: CreateSubjectGQL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
]" [customActions]="[
|
]" [customActions]="[
|
||||||
{icon: 'chevron_right', label: 'Kurzusok', action: listCourses}
|
{icon: 'chevron_right', label: 'Kurzusok', action: listCourses}
|
||||||
]"></app-list>
|
]"></app-list>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
import { RouteData } from '../app-routing.module';
|
import { RouteData } from '../app-routing.module';
|
||||||
import { CourseListComponent } from './subject-edit/courses/course-list/course-list.component';
|
import { CourseListComponent } from './subject-edit/courses/course-list/course-list.component';
|
||||||
import { CourseEditComponent } from './subject-edit/courses/course-edit/course-edit.component';
|
import { CourseEditComponent } from './subject-edit/courses/course-edit/course-edit.component';
|
||||||
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: '', component: SubjectListComponent, data: {title: ''} as RouteData},
|
{path: '', component: SubjectListComponent, data: {title: ''} as RouteData},
|
||||||
|
@ -24,7 +28,11 @@ const routes: Routes = [
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedComponentsModule,
|
SharedComponentsModule,
|
||||||
RouterModule.forChild(routes)
|
RouterModule.forChild(routes),
|
||||||
|
MatCardModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
ReactiveFormsModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SubjectsModule {
|
export class SubjectsModule {
|
||||||
|
|
Loading…
Reference in a new issue