Skip to content

Commit 6c96a98

Browse files
committed
Change Project.isMember to be only active memberships by default. Optionally include inactive.
1 parent ea430a5 commit 6c96a98

File tree

4 files changed

+49
-5
lines changed

4 files changed

+49
-5
lines changed

src/components/project/dto/project.dto.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,11 @@ class Project extends Interfaces {
177177

178178
readonly rootDirectory: Secured<LinkTo<'Directory'> | null>;
179179

180-
@Field({
181-
description: 'Is the requesting user a member of this project?',
182-
})
183-
readonly isMember: boolean;
180+
/** The current user's membership, if any. */
181+
readonly membership:
182+
| (LinkTo<'ProjectMember'> &
183+
Pick<UnsecuredDto<ProjectMember>, 'roles' | 'inactiveAt'>)
184+
| null;
184185

185186
@Field({
186187
description: stripIndent`

src/components/project/project.gel.repository.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ const hydrate = e.shape(e.Project, (project) => ({
3838
__typename: project.__type__.name.slice(9, null),
3939

4040
rootDirectory: true,
41+
membership: {
42+
id: true,
43+
roles: true,
44+
inactiveAt: true,
45+
},
4146
primaryPartnership: e
4247
.select(project.partnerships, (p) => ({
4348
filter: e.op(p.primary, '=', true),

src/components/project/project.repository.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ import { CommonRepository, OnIndex, UniquenessError } from '~/core/database';
1515
import { type ChangesOf, getChanges } from '~/core/database/changes';
1616
import {
1717
ACTIVE,
18+
collect,
1819
createNode,
1920
createRelationships,
21+
currentUser,
2022
defineSorters,
2123
FullTextIndex,
2224
matchChangesetAndChangedProps,
2325
matchProjectSens,
26+
matchProps,
2427
matchPropsAndProjectSensAndScopedRoles,
2528
merge,
2629
paginate,
@@ -89,6 +92,19 @@ export class ProjectRepository extends CommonRepository {
8992
relation('out', '', 'rootDirectory', ACTIVE),
9093
node('rootDirectory', 'Directory'),
9194
])
95+
.subQuery('node', (sub) =>
96+
sub
97+
.match([
98+
node('node'),
99+
relation('out', '', 'member', ACTIVE),
100+
node('membership'),
101+
relation('out', '', 'user'),
102+
currentUser,
103+
])
104+
.apply(matchProps({ nodeName: 'membership', outputVar: 'dto' }))
105+
.with(collect('dto').as('dtos'))
106+
.return('dtos[0] as membership'),
107+
)
92108
.optionalMatch([
93109
node('node'),
94110
relation('out', '', 'partnership', ACTIVE),
@@ -134,7 +150,7 @@ export class ProjectRepository extends CommonRepository {
134150
merge('props', 'changedProps', {
135151
type: 'node.type',
136152
pinned,
137-
isMember: '"member:true" in props.scope',
153+
membership: 'membership',
138154
rootDirectory: 'rootDirectory { .id }',
139155
primaryPartnership: 'primaryPartnership { .id }',
140156
primaryLocation: 'primaryLocation { .id }',

src/components/project/project.resolver.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
ListArg,
1919
mapSecuredValue,
2020
NotFoundException,
21+
OptionalField,
2122
SecuredDateRange,
2223
} from '~/common';
2324
import { Loader, type LoaderOf } from '~/core';
@@ -83,6 +84,14 @@ class ModifyOtherLocationArgs {
8384
locationId: ID;
8485
}
8586

87+
@ArgsType()
88+
class IsMemberArgs {
89+
@OptionalField({
90+
description: 'Consider inactive memberships as well',
91+
})
92+
includeInactive?: boolean;
93+
}
94+
8695
@Resolver(IProject)
8796
export class ProjectResolver {
8897
constructor(private readonly projectService: ProjectService) {}
@@ -148,6 +157,19 @@ export class ProjectResolver {
148157
return list;
149158
}
150159

160+
@ResolveField(() => Boolean, {
161+
description: 'Is the requesting user a member of this project?',
162+
})
163+
isMember(
164+
@Parent() project: Project,
165+
@Args() { includeInactive }: IsMemberArgs,
166+
): boolean {
167+
return (
168+
!!project.membership &&
169+
(includeInactive ? true : !project.membership.inactiveAt)
170+
);
171+
}
172+
151173
@ResolveField(() => String, { nullable: true })
152174
avatarLetters(@Parent() project: Project): string | undefined {
153175
return project.name.canRead && project.name.value

0 commit comments

Comments
 (0)