mirror of
https://github.com/docmost/docmost.git
synced 2025-11-20 08:11:10 +10:00
Implement Space membership by group
* Add all users to default group * Fixes and updates
This commit is contained in:
45
apps/server/src/core/space/entities/space-group.entity.ts
Normal file
45
apps/server/src/core/space/entities/space-group.entity.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
JoinColumn,
|
||||
Unique,
|
||||
} from 'typeorm';
|
||||
import { Space } from './space.entity';
|
||||
import { Group } from '../../group/entities/group.entity';
|
||||
|
||||
@Entity('space_groups')
|
||||
@Unique(['spaceId', 'groupId'])
|
||||
export class SpaceGroup {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column()
|
||||
groupId: string;
|
||||
|
||||
@ManyToOne(() => Group, (group) => group.spaces, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@JoinColumn({ name: 'groupId' })
|
||||
group: Group;
|
||||
|
||||
@Column()
|
||||
spaceId: string;
|
||||
|
||||
@ManyToOne(() => Space, (space) => space.spaceGroups, {
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
space: Space;
|
||||
|
||||
@Column({ length: 100, nullable: true })
|
||||
role: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
}
|
||||
@ -14,6 +14,7 @@ import { Workspace } from '../../workspace/entities/workspace.entity';
|
||||
import { SpaceUser } from './space-user.entity';
|
||||
import { Page } from '../../page/entities/page.entity';
|
||||
import { SpacePrivacy, SpaceRole } from '../../../helpers/types/permission';
|
||||
import { SpaceGroup } from './space-group.entity';
|
||||
|
||||
@Entity('spaces')
|
||||
@Unique(['slug', 'workspaceId'])
|
||||
@ -42,7 +43,7 @@ export class Space {
|
||||
@Column()
|
||||
creatorId: string;
|
||||
|
||||
@ManyToOne(() => User, (user) => user.spaces)
|
||||
@ManyToOne(() => User)
|
||||
@JoinColumn({ name: 'creatorId' })
|
||||
creator: User;
|
||||
|
||||
@ -58,6 +59,9 @@ export class Space {
|
||||
@OneToMany(() => SpaceUser, (spaceUser) => spaceUser.space)
|
||||
spaceUsers: SpaceUser[];
|
||||
|
||||
@OneToMany(() => SpaceGroup, (spaceGroup) => spaceGroup.space)
|
||||
spaceGroups: SpaceGroup[];
|
||||
|
||||
@OneToMany(() => Page, (page) => page.space)
|
||||
pages: Page[];
|
||||
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, Repository } from 'typeorm';
|
||||
import { SpaceGroup } from '../entities/space-group.entity';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceGroupRepository extends Repository<SpaceGroup> {
|
||||
constructor(private dataSource: DataSource) {
|
||||
super(SpaceGroup, dataSource.createEntityManager());
|
||||
}
|
||||
}
|
||||
@ -57,6 +57,7 @@ export class SpaceController {
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('members')
|
||||
async getSpaceMembers(
|
||||
// todo: accept type? users | groups
|
||||
@Body() spaceIdDto: SpaceIdDto,
|
||||
@Body()
|
||||
pagination: PaginationOptions,
|
||||
|
||||
@ -6,11 +6,18 @@ import { Space } from './entities/space.entity';
|
||||
import { SpaceUser } from './entities/space-user.entity';
|
||||
import { SpaceRepository } from './repositories/space.repository';
|
||||
import { SpaceUserRepository } from './repositories/space-user.repository';
|
||||
import { SpaceGroup } from './entities/space-group.entity';
|
||||
import { SpaceGroupRepository } from './repositories/space-group.repository';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Space, SpaceUser])],
|
||||
imports: [TypeOrmModule.forFeature([Space, SpaceUser, SpaceGroup])],
|
||||
controllers: [SpaceController],
|
||||
providers: [SpaceService, SpaceRepository, SpaceUserRepository],
|
||||
exports: [SpaceService, SpaceRepository, SpaceUserRepository],
|
||||
providers: [
|
||||
SpaceService,
|
||||
SpaceRepository,
|
||||
SpaceUserRepository,
|
||||
SpaceGroupRepository,
|
||||
],
|
||||
exports: [SpaceService],
|
||||
})
|
||||
export class SpaceModule {}
|
||||
|
||||
@ -14,12 +14,16 @@ import { User } from '../user/entities/user.entity';
|
||||
import { PaginationOptions } from '../../helpers/pagination/pagination-options';
|
||||
import { PaginationMetaDto } from '../../helpers/pagination/pagination-meta-dto';
|
||||
import { PaginatedResult } from '../../helpers/pagination/paginated-result';
|
||||
import { SpaceGroupRepository } from './repositories/space-group.repository';
|
||||
import { Group } from '../group/entities/group.entity';
|
||||
import { SpaceGroup } from './entities/space-group.entity';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceService {
|
||||
constructor(
|
||||
private spaceRepository: SpaceRepository,
|
||||
private spaceUserRepository: SpaceUserRepository,
|
||||
private spaceGroupRepository: SpaceGroupRepository,
|
||||
private dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
@ -94,7 +98,7 @@ export class SpaceService {
|
||||
'space.userCount',
|
||||
'space.spaceUsers',
|
||||
'spaceUsers',
|
||||
)
|
||||
) // TODO: add groups to userCount
|
||||
.getOne();
|
||||
|
||||
if (!space) {
|
||||
@ -115,7 +119,7 @@ export class SpaceService {
|
||||
'space.userCount',
|
||||
'space.spaceUsers',
|
||||
'spaceUsers',
|
||||
)
|
||||
) // TODO: add groups to userCount
|
||||
.take(paginationOptions.limit)
|
||||
.skip(paginationOptions.skip)
|
||||
.getManyAndCount();
|
||||
@ -178,4 +182,71 @@ export class SpaceService {
|
||||
const paginationMeta = new PaginationMetaDto({ count, paginationOptions });
|
||||
return new PaginatedResult(users, paginationMeta);
|
||||
}
|
||||
|
||||
async addGroupToSpace(
|
||||
groupId: string,
|
||||
spaceId: string,
|
||||
role: string,
|
||||
workspaceId,
|
||||
manager?: EntityManager,
|
||||
): Promise<SpaceGroup> {
|
||||
return await transactionWrapper(
|
||||
async (manager: EntityManager) => {
|
||||
const groupExists = await manager.exists(Group, {
|
||||
where: { id: groupId, workspaceId },
|
||||
});
|
||||
if (!groupExists) {
|
||||
throw new NotFoundException('Group not found');
|
||||
}
|
||||
|
||||
const existingSpaceGroup = await manager.findOneBy(SpaceGroup, {
|
||||
groupId: groupId,
|
||||
spaceId: spaceId,
|
||||
});
|
||||
|
||||
if (existingSpaceGroup) {
|
||||
throw new BadRequestException('Group already added to this space');
|
||||
}
|
||||
|
||||
const spaceGroup = new SpaceGroup();
|
||||
spaceGroup.groupId = groupId;
|
||||
spaceGroup.spaceId = spaceId;
|
||||
spaceGroup.role = role;
|
||||
await manager.save(spaceGroup);
|
||||
|
||||
return spaceGroup;
|
||||
},
|
||||
this.dataSource,
|
||||
manager,
|
||||
);
|
||||
}
|
||||
|
||||
async getSpaceGroups(
|
||||
spaceId: string,
|
||||
workspaceId: string,
|
||||
paginationOptions: PaginationOptions,
|
||||
) {
|
||||
const [spaceGroups, count] = await this.spaceGroupRepository.findAndCount({
|
||||
relations: ['group'],
|
||||
where: {
|
||||
space: {
|
||||
id: spaceId,
|
||||
workspaceId,
|
||||
},
|
||||
},
|
||||
take: paginationOptions.limit,
|
||||
skip: paginationOptions.skip,
|
||||
});
|
||||
|
||||
// TODO: add group userCount
|
||||
const groups = spaceGroups.map((spaceGroup) => {
|
||||
return {
|
||||
...spaceGroup.group,
|
||||
spaceRole: spaceGroup.role,
|
||||
};
|
||||
});
|
||||
|
||||
const paginationMeta = new PaginationMetaDto({ count, paginationOptions });
|
||||
return new PaginatedResult(groups, paginationMeta);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user