Skip to content

Commit 7406ab8

Browse files
committed
Expose FieldRegion.projects relationship in GraphQL API
1 parent d61a667 commit 7406ab8

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

src/components/field-region/dto/field-region.dto.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,26 @@ import {
33
DbUnique,
44
NameField,
55
Resource,
6+
type ResourceRelationsShape,
67
type Secured,
78
SecuredProperty,
89
SecuredPropertyList,
910
SecuredString,
1011
} from '~/common';
1112
import { e } from '~/core/gel';
1213
import { type LinkTo, RegisterResource } from '~/core/resources';
14+
import { IProject } from '../../project/dto';
1315

1416
@RegisterResource({ db: e.FieldRegion })
1517
@ObjectType({
1618
implements: [Resource],
1719
})
1820
export class FieldRegion extends Resource {
21+
static readonly Relations = () =>
22+
({
23+
projects: [IProject],
24+
} satisfies ResourceRelationsShape);
25+
1926
@NameField()
2027
@DbUnique()
2128
readonly name: SecuredString;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
2+
import { ListArg } from '~/common';
3+
import { Loader, type LoaderOf } from '~/core';
4+
import { ProjectListInput, SecuredProjectList } from '../project/dto';
5+
import { ProjectLoader } from '../project/project.loader';
6+
import { FieldRegion } from './dto';
7+
import { FieldRegionService } from './field-region.service';
8+
9+
@Resolver(FieldRegion)
10+
export class FieldRegionProjectsResolver {
11+
constructor(private readonly fieldRegionService: FieldRegionService) {}
12+
13+
@ResolveField(() => SecuredProjectList, {
14+
description: 'The list of projects in this field region',
15+
})
16+
async projects(
17+
@Parent() fieldRegion: FieldRegion,
18+
@ListArg(ProjectListInput) input: ProjectListInput,
19+
@Loader(ProjectLoader) projects: LoaderOf<ProjectLoader>,
20+
): Promise<SecuredProjectList> {
21+
const list = await this.fieldRegionService.listProjects(fieldRegion, input);
22+
projects.primeAll(list.items);
23+
return list;
24+
}
25+
}

src/components/field-region/field-region.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { forwardRef, Module } from '@nestjs/common';
22
import { splitDb } from '~/core';
33
import { AuthorizationModule } from '../authorization/authorization.module';
44
import { FieldZoneModule } from '../field-zone/field-zone.module';
5+
import { ProjectModule } from '../project/project.module';
56
import { UserModule } from '../user/user.module';
7+
import { FieldRegionProjectsResolver } from './field-region-projects.resolver';
68
import { FieldRegionGelRepository } from './field-region.gel.repository';
79
import { FieldRegionLoader } from './field-region.loader';
810
import { FieldRegionRepository } from './field-region.repository';
@@ -14,10 +16,12 @@ import { RestrictRegionDirectorRemovalHandler } from './handlers/restrict-region
1416
imports: [
1517
forwardRef(() => AuthorizationModule),
1618
FieldZoneModule,
19+
forwardRef(() => ProjectModule),
1720
forwardRef(() => UserModule),
1821
],
1922
providers: [
2023
FieldRegionResolver,
24+
FieldRegionProjectsResolver,
2125
FieldRegionService,
2226
splitDb(FieldRegionRepository, FieldRegionGelRepository),
2327
FieldRegionLoader,

src/components/field-region/field-region.service.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import {
1010
import { HandleIdLookup } from '~/core';
1111
import { IEventBus } from '~/core/events';
1212
import { Privileges } from '../authorization';
13+
import {
14+
IProject,
15+
type ProjectListInput,
16+
type SecuredProjectList,
17+
} from '../project/dto';
18+
import { ProjectService } from '../project/project.service';
1319
import { UserService } from '../user';
1420
import {
1521
type CreateFieldRegion,
@@ -28,6 +34,7 @@ export class FieldRegionService {
2834
private readonly events: IEventBus,
2935
private readonly users: UserService,
3036
private readonly repo: FieldRegionRepository,
37+
private readonly projectService: ProjectService,
3138
) {}
3239

3340
async create(input: CreateFieldRegion): Promise<FieldRegion> {
@@ -115,4 +122,26 @@ export class FieldRegionService {
115122
items: results.items.map((dto) => this.secure(dto)),
116123
};
117124
}
125+
126+
async listProjects(
127+
fieldRegion: FieldRegion,
128+
input: ProjectListInput,
129+
): Promise<SecuredProjectList> {
130+
const projectListOutput = await this.projectService.list({
131+
...input,
132+
filter: {
133+
...input.filter,
134+
fieldRegion: {
135+
...(input.filter?.fieldRegion ?? {}),
136+
id: fieldRegion.id,
137+
},
138+
},
139+
});
140+
141+
return {
142+
...projectListOutput,
143+
canRead: true,
144+
canCreate: this.privileges.for(IProject).can('create'),
145+
};
146+
}
118147
}

src/components/project/field-region-project-connection.resolver.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)