Skip to content

Commit b7892d4

Browse files
authored
Merge pull request #3503 from SeedCompany/field-region-filters
2 parents 6cdf774 + 98b9c24 commit b7892d4

File tree

7 files changed

+135
-10
lines changed

7 files changed

+135
-10
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@ import { InputType, ObjectType } from '@nestjs/graphql';
22
import {
33
FilterField,
44
type ID,
5+
IdField,
56
PaginatedList,
67
SecuredList,
78
SortablePaginationInput,
89
} from '~/common';
10+
import { FieldZoneFilters } from '../../field-zone/dto';
11+
import { UserFilters } from '../../user/dto';
912
import { FieldRegion } from './field-region.dto';
1013

1114
@InputType()
1215
export abstract class FieldRegionFilters {
13-
readonly fieldZoneId?: ID;
16+
@IdField({ optional: true })
17+
readonly id?: ID<'FieldRegion'>;
18+
19+
@FilterField(() => UserFilters)
20+
readonly director?: UserFilters & {};
21+
22+
@FilterField(() => FieldZoneFilters)
23+
readonly fieldZone?: FieldZoneFilters & {};
1424
}
1525

1626
@InputType()
@@ -19,7 +29,7 @@ export class FieldRegionListInput extends SortablePaginationInput<
1929
>({
2030
defaultSort: 'name',
2131
}) {
22-
@FilterField(() => FieldRegionFilters, { internal: true })
32+
@FilterField(() => FieldRegionFilters)
2333
readonly filter?: FieldRegionFilters;
2434
}
2535

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

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,22 @@ import {
1414
ACTIVE,
1515
createNode,
1616
createRelationships,
17+
defineSorters,
18+
filter,
1719
matchProps,
1820
merge,
1921
paginate,
20-
sorting,
22+
sortWith,
2123
} from '~/core/database/query';
24+
import {
25+
fieldZoneFilters,
26+
fieldZoneSorters,
27+
} from '../field-zone/field-zone.repository';
28+
import { userFilters, userSorters } from '../user/user.repository';
2229
import {
2330
type CreateFieldRegion,
2431
FieldRegion,
32+
FieldRegionFilters,
2533
type FieldRegionListInput,
2634
type UpdateFieldRegion,
2735
} from './dto';
@@ -102,14 +110,15 @@ export class FieldRegionRepository extends DtoRepository(FieldRegion) {
102110
);
103111
}
104112

105-
async list({ filter, ...input }: FieldRegionListInput) {
113+
async list(input: FieldRegionListInput) {
106114
if (!this.privileges.can('read')) {
107115
return SecuredList.Redacted;
108116
}
109117
const result = await this.db
110118
.query()
111119
.match(node('node', 'FieldRegion'))
112-
.apply(sorting(FieldRegion, input))
120+
.apply(fieldRegionFilters(input.filter))
121+
.apply(sortWith(fieldRegionSorters, input))
113122
.apply(paginate(input, this.hydrate()))
114123
.first();
115124
return result!; // result from paginate() will always have 1 row.
@@ -128,3 +137,44 @@ export class FieldRegionRepository extends DtoRepository(FieldRegion) {
128137
.run();
129138
}
130139
}
140+
141+
export const fieldRegionFilters = filter.define(() => FieldRegionFilters, {
142+
id: filter.baseNodeProp(),
143+
director: filter.sub(() => userFilters)((sub) =>
144+
sub.match([
145+
node('outer'),
146+
relation('out', '', 'director', ACTIVE),
147+
node('node', 'User'),
148+
]),
149+
),
150+
fieldZone: filter.sub(() => fieldZoneFilters)((sub) =>
151+
sub.match([
152+
node('outer'),
153+
relation('out', '', 'zone', ACTIVE),
154+
node('node', 'FieldZone'),
155+
]),
156+
),
157+
});
158+
159+
export const fieldRegionSorters = defineSorters(FieldRegion, {
160+
// eslint-disable-next-line @typescript-eslint/naming-convention
161+
'director.*': (query, input) =>
162+
query
163+
.with('node as region')
164+
.match([
165+
node('region'),
166+
relation('out', '', 'director', ACTIVE),
167+
node('node', 'User'),
168+
])
169+
.apply(sortWith(userSorters, input)),
170+
// eslint-disable-next-line @typescript-eslint/naming-convention
171+
'fieldZone.*': (query, input) =>
172+
query
173+
.with('node as region')
174+
.match([
175+
node('region'),
176+
relation('out', '', 'zone', ACTIVE),
177+
node('node', 'FieldZone'),
178+
])
179+
.apply(sortWith(fieldZoneSorters, input)),
180+
});

src/components/field-zone/dto/list-field-zone.dto.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import { InputType, ObjectType } from '@nestjs/graphql';
22
import {
33
FilterField,
44
type ID,
5+
IdField,
56
PaginatedList,
67
SecuredList,
78
SortablePaginationInput,
89
} from '~/common';
10+
import { UserFilters } from '../../user/dto';
911
import { FieldZone } from './field-zone.dto';
1012

1113
@InputType()
1214
export abstract class FieldZoneFilters {
13-
readonly fieldZoneId?: ID;
15+
@IdField({ optional: true })
16+
readonly id?: ID<'FieldZone'>;
17+
18+
@FilterField(() => UserFilters)
19+
readonly director?: UserFilters & {};
1420
}
1521

1622
@InputType()
@@ -19,7 +25,7 @@ export class FieldZoneListInput extends SortablePaginationInput<
1925
>({
2026
defaultSort: 'name',
2127
}) {
22-
@FilterField(() => FieldZoneFilters, { internal: true })
28+
@FilterField(() => FieldZoneFilters)
2329
readonly filter?: FieldZoneFilters;
2430
}
2531

src/components/field-zone/field-zone.repository.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ import {
1515
ACTIVE,
1616
createNode,
1717
createRelationships,
18+
defineSorters,
19+
filter,
1820
matchProps,
1921
merge,
2022
paginate,
21-
sorting,
23+
sortWith,
2224
} from '~/core/database/query';
25+
import { userFilters, userSorters } from '../user/user.repository';
2326
import {
2427
type CreateFieldZone,
2528
FieldZone,
29+
FieldZoneFilters,
2630
type FieldZoneListInput,
2731
type UpdateFieldZone,
2832
} from './dto';
@@ -121,14 +125,15 @@ export class FieldZoneRepository extends DtoRepository(FieldZone) {
121125
await query.run();
122126
}
123127

124-
async list({ filter, ...input }: FieldZoneListInput) {
128+
async list(input: FieldZoneListInput) {
125129
if (!this.privileges.can('read')) {
126130
return SecuredList.Redacted;
127131
}
128132
const result = await this.db
129133
.query()
130134
.match(node('node', 'FieldZone'))
131-
.apply(sorting(FieldZone, input))
135+
.apply(fieldZoneFilters(input.filter))
136+
.apply(sortWith(fieldZoneSorters, input))
132137
.apply(paginate(input, this.hydrate()))
133138
.first();
134139
return result!; // result from paginate() will always have 1 row.
@@ -147,3 +152,27 @@ export class FieldZoneRepository extends DtoRepository(FieldZone) {
147152
.run();
148153
}
149154
}
155+
156+
export const fieldZoneFilters = filter.define(() => FieldZoneFilters, {
157+
id: filter.baseNodeProp(),
158+
director: filter.sub(() => userFilters)((sub) =>
159+
sub.match([
160+
node('outer'),
161+
relation('out', '', 'director', ACTIVE),
162+
node('node', 'User'),
163+
]),
164+
),
165+
});
166+
167+
export const fieldZoneSorters = defineSorters(FieldZone, {
168+
// eslint-disable-next-line @typescript-eslint/naming-convention
169+
'director.*': (query, input) =>
170+
query
171+
.with('node as zone')
172+
.match([
173+
node('zone'),
174+
relation('out', '', 'director', ACTIVE),
175+
node('node', 'User'),
176+
])
177+
.apply(sortWith(userSorters, input)),
178+
});

src/components/project/dto/list-projects.dto.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
SortablePaginationInput,
1717
} from '~/common';
1818
import { Transform } from '~/common/transform.decorator';
19+
import { FieldRegionFilters } from '../../field-region/dto';
1920
import { LocationFilters } from '../../location/dto';
2021
import { PartnershipFilters } from '../../partnership/dto';
2122
import { ProjectMemberFilters } from '../project-member/dto';
@@ -134,6 +135,9 @@ export abstract class ProjectFilters {
134135

135136
@FilterField(() => LocationFilters)
136137
readonly primaryLocation?: LocationFilters & {};
138+
139+
@FilterField(() => FieldRegionFilters)
140+
readonly fieldRegion?: FieldRegionFilters & {};
137141
}
138142

139143
Object.defineProperty(ProjectFilters.prototype, 'mine', {

src/components/project/project-filters.query.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
path,
1414
variable,
1515
} from '~/core/database/query';
16+
import { fieldRegionFilters } from '../field-region/field-region.repository';
1617
import { locationFilters } from '../location/location.repository';
1718
import { partnershipFilters } from '../partnership/partnership.repository';
1819
import { ProjectFilters } from './dto';
@@ -107,6 +108,13 @@ export const projectFilters = filter.define(() => ProjectFilters, {
107108
node('node', 'Location'),
108109
]),
109110
),
111+
fieldRegion: filter.sub(() => fieldRegionFilters)((sub) =>
112+
sub.match([
113+
node('outer'),
114+
relation('out', '', 'fieldRegion', ACTIVE),
115+
node('node', 'FieldRegion'),
116+
]),
117+
),
110118
sensitivity: ({ value, query }) =>
111119
query
112120
.apply(matchProjectSens('node'))

src/components/project/project.repository.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
variable,
3535
} from '~/core/database/query';
3636
import { Privileges } from '../authorization';
37+
import { fieldRegionSorters } from '../field-region/field-region.repository';
3738
import { locationSorters } from '../location/location.repository';
3839
import { partnershipSorters } from '../partnership/partnership.repository';
3940
import {
@@ -456,4 +457,21 @@ export const projectSorters = defineSorters(IProject, {
456457
.where(not(path(getPath(true))))
457458
.return<SortCol>('null as sortValue');
458459
},
460+
// eslint-disable-next-line @typescript-eslint/naming-convention
461+
'fieldRegion.*': (query, input) => {
462+
const getPath = (anon = false) => [
463+
node('project'),
464+
relation('out', '', 'fieldRegion', ACTIVE),
465+
node(anon ? '' : 'node', 'FieldRegion'),
466+
];
467+
return query
468+
.with('node as project')
469+
.match(getPath())
470+
.apply(sortWith(fieldRegionSorters, input))
471+
.union()
472+
.with('node')
473+
.with('node as project')
474+
.where(not(path(getPath(true))))
475+
.return<SortCol>('null as sortValue');
476+
},
459477
});

0 commit comments

Comments
 (0)