item list, paginated
This commit is contained in:
parent
45e3a2aa7f
commit
b369daa4af
|
@ -1,4 +1,5 @@
|
||||||
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
||||||
|
import { Paginated } from '../paginated.output';
|
||||||
|
|
||||||
@ObjectType('Item', {
|
@ObjectType('Item', {
|
||||||
description: 'Either the inventored thing or a box containing them',
|
description: 'Either the inventored thing or a box containing them',
|
||||||
|
@ -28,3 +29,6 @@ export class ItemModel {
|
||||||
@Field((type) => [ItemModel])
|
@Field((type) => [ItemModel])
|
||||||
descendants: ItemModel[];
|
descendants: ItemModel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export class PaginatedItems extends Paginated(ItemModel) {}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
} from '@nestjs/graphql';
|
} from '@nestjs/graphql';
|
||||||
import { NewItemInput } from './dto/new-item.input';
|
import { NewItemInput } from './dto/new-item.input';
|
||||||
import { EANService } from './ean/ean.service';
|
import { EANService } from './ean/ean.service';
|
||||||
import { ItemModel } from './items.model';
|
import { ItemModel, PaginatedItems } from './items.model';
|
||||||
import { ItemsService } from './items.service';
|
import { ItemsService } from './items.service';
|
||||||
|
|
||||||
@Resolver((of) => ItemModel)
|
@Resolver((of) => ItemModel)
|
||||||
|
@ -21,6 +21,13 @@ export class ItemsResolver {
|
||||||
return this.itemsService.getItem(id);
|
return this.itemsService.getItem(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query((returns) => PaginatedItems)
|
||||||
|
async itemList(
|
||||||
|
@Args('cursor', { type: () => ID, nullable: true }) cursor?: string,
|
||||||
|
) {
|
||||||
|
return this.itemsService.getItemList(cursor ? parseInt(cursor, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
@ResolveField()
|
@ResolveField()
|
||||||
ean13(@Parent() item: ItemModel) {
|
ean13(@Parent() item: ItemModel) {
|
||||||
return this.eans.fromID(item.id);
|
return this.eans.fromID(item.id);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { EntityManager, Repository, TreeRepository } from 'typeorm';
|
||||||
import { NewItemInput } from './dto/new-item.input';
|
import { NewItemInput } from './dto/new-item.input';
|
||||||
import { EANService } from './ean/ean.service';
|
import { EANService } from './ean/ean.service';
|
||||||
import { Item } from './items.entity';
|
import { Item } from './items.entity';
|
||||||
import { ItemModel } from './items.model';
|
import { ItemModel, PaginatedItems } from './items.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ItemsService {
|
export class ItemsService {
|
||||||
|
@ -63,6 +63,19 @@ export class ItemsService {
|
||||||
return (await this.treeRepository.findDescendants(parentItem)).slice(1);
|
return (await this.treeRepository.findDescendants(parentItem)).slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getItemList(cursor: number = 0): Promise<PaginatedItems> {
|
||||||
|
const [items, count] = await this.itemRepository.findAndCount({
|
||||||
|
take: 25,
|
||||||
|
skip: cursor,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
nodes: items,
|
||||||
|
cursor: cursor + items.length,
|
||||||
|
totalCount: count,
|
||||||
|
hasNextPage: count > cursor + items.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async createItem(input: NewItemInput): Promise<Item> {
|
async createItem(input: NewItemInput): Promise<Item> {
|
||||||
// must use Repository.save() for the closure table to work,
|
// must use Repository.save() for the closure table to work,
|
||||||
// so we have to check whether the provided ID exists in the first place
|
// so we have to check whether the provided ID exists in the first place
|
||||||
|
|
20
src/paginated.output.ts
Normal file
20
src/paginated.output.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Field, ObjectType, Int, ID } from '@nestjs/graphql';
|
||||||
|
import { Type } from '@nestjs/common';
|
||||||
|
|
||||||
|
export function Paginated<T>(classRef: Type<T>): any {
|
||||||
|
@ObjectType({ isAbstract: true })
|
||||||
|
abstract class PaginatedType {
|
||||||
|
@Field((type) => [classRef])
|
||||||
|
nodes: T[];
|
||||||
|
|
||||||
|
@Field((type) => ID, { nullable: true })
|
||||||
|
cursor?: number;
|
||||||
|
|
||||||
|
@Field((type) => Int)
|
||||||
|
totalCount: number;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
hasNextPage: boolean;
|
||||||
|
}
|
||||||
|
return PaginatedType;
|
||||||
|
}
|
Loading…
Reference in a new issue