Skip to content

Commit

Permalink
feat: enable editors in timeline for multi user timeline (#931)
Browse files Browse the repository at this point in the history
* feat: multi-user timeline

* Update user-experience.service.ts

* Update experience.controller.ts

* format fix
  • Loading branch information
RiXelanya authored Nov 15, 2023
1 parent 0af8ef3 commit bdf2167
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/__tests__/helpers/database.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
UnlockableContentRepository,
ContentPriceRepository,
TimelineConfigRepository,
ExperienceEditorRepository,
} from '../../repositories';
import {
ActivityLogService,
Expand Down Expand Up @@ -145,10 +146,13 @@ export async function givenRepositories(testdb: any) {
async () => userRepository,
async () => experienceUserRepository,
async () => experiencePostRepository,
async () => experienceEditorRepository,
async () => postRepository,
);
const experienceUserRepository: ExperienceUserRepository =
new ExperienceUserRepository(testdb);
const experienceEditorRepository: ExperienceUserRepository =
new ExperienceEditorRepository(testdb);
const experiencePostRepository: ExperiencePostRepository =
new ExperiencePostRepository(testdb);
const commentRepository: CommentRepository = new CommentRepository(
Expand Down
9 changes: 7 additions & 2 deletions src/controllers/user/experience.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ export class UserExperienceController {
@post('/user/experiences')
@response(200, {
description: 'CREATE user experience',
content: {'application/json': {schema: getModelSchemaRef(Experience)}},
content: {
'application/json': {
schema: getModelSchemaRef(Experience, {includeRelations: true}),
},
},
})
async create(
@requestBody({
Expand All @@ -106,8 +110,9 @@ export class UserExperienceController {
})
experience: Omit<Experience, 'id'>,
@param.query.string('experienceId') experienceId?: string,
@param.array('editors', 'query', {type: 'string'}) editors?: string[],
): Promise<Experience> {
return this.userService.createExperience(experience, experienceId);
return this.userService.createExperience(experience, experienceId, editors);
}

@patch('/user/experiences/{id}')
Expand Down
55 changes: 55 additions & 0 deletions src/models/experience-editor.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {Entity, model, property} from '@loopback/repository';

@model({
settings: {
strictObjectIDCoercion: true,
mongodb: {
collection: 'ExperienceEditors',
},
indexes: {
uniqueUserExperienceIndex: {
keys: {
userId: 1,
experienceId: 1,
},
options: {
unique: true,
},
},
},
},
})
export class ExperienceEditor extends Entity {
@property({
type: 'string',
id: true,
generated: true,
mongodb: {
dataType: 'ObjectId',
},
})
id?: string;

@property({
type: 'string',
required: false,
})
experienceId: string;

@property({
type: 'string',
required: false,
})
userId: string;

constructor(data?: Partial<ExperienceEditor>) {
super(data);
}
}

export interface ExperienceEditorRelations {
// describe navigational properties here
}

export type ExperienceEditorWithRelations = ExperienceEditor &
ExperienceEditorRelations;
4 changes: 4 additions & 0 deletions src/models/experience.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import {People} from './people.model';
import {User} from './user.model';
import {ExperienceUser} from './experience-user.model';
import {ExperienceEditor} from './experience-editor.model';
import {UserWithRelations} from './user.model';
import {Post} from './post.model';
import {ExperiencePost} from './experience-post.model';
Expand Down Expand Up @@ -157,6 +158,9 @@ export class Experience extends Entity {
@hasMany(() => User, {through: {model: () => ExperienceUser}})
users?: User[];

@hasMany(() => User, {through: {model: () => ExperienceEditor}})
editors?: User[];

constructor(data?: Partial<Experience>) {
super(data);
}
Expand Down
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './embedded-url.model';
export * from './exchange-rate.model';
export * from './experience-post.model';
export * from './experience-user.model';
export * from './experience-editor.model';
export * from './experience.model';
export * from './friend.model';
export * from './identity.model';
Expand Down
15 changes: 15 additions & 0 deletions src/repositories/experience-editor.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {bind, BindingScope, inject} from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository';
import {MongoDataSource} from '../datasources';
import {ExperienceEditor, ExperienceEditorRelations} from '../models';

@bind({scope: BindingScope.SINGLETON})
export class ExperienceEditorRepository extends DefaultCrudRepository<
ExperienceEditor,
typeof ExperienceEditor.prototype.id,
ExperienceEditorRelations
> {
constructor(@inject('datasources.mongo') dataSource: MongoDataSource) {
super(ExperienceEditor, dataSource);
}
}
17 changes: 17 additions & 0 deletions src/repositories/experience.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import {
ExperiencePost,
ExperienceRelations,
ExperienceUser,
ExperienceEditor,
Post,
User,
} from '../models';
import {ExperiencePostRepository} from './experience-post.repository';
import {ExperienceUserRepository} from './experience-user.repository';
import {ExperienceEditorRepository} from './experience-editor.repository';
import {PostRepository} from './post.repository';
import {UserRepository} from './user.repository';

Expand All @@ -34,6 +36,13 @@ export class ExperienceRepository extends DefaultCrudRepository<
typeof Experience.prototype.id
>;

public readonly editors: HasManyThroughRepositoryFactory<
User,
typeof User.prototype.id,
ExperienceEditor,
typeof Experience.prototype.id
>;

public readonly posts: HasManyThroughRepositoryFactory<
Post,
typeof Post.prototype.id,
Expand All @@ -49,6 +58,8 @@ export class ExperienceRepository extends DefaultCrudRepository<
protected experienceUserRepositoryGetter: Getter<ExperienceUserRepository>,
@repository.getter('ExperiencePostRepository')
protected experiencePostRepositoryGetter: Getter<ExperiencePostRepository>,
@repository.getter('ExperienceEditorRepository')
protected experienceEditorRepositoryGetter: Getter<ExperienceEditorRepository>,
@repository.getter('PostRepository')
protected postRepositoryGetter: Getter<PostRepository>,
) {
Expand All @@ -65,6 +76,12 @@ export class ExperienceRepository extends DefaultCrudRepository<
experienceUserRepositoryGetter,
);
this.registerInclusionResolver('users', this.users.inclusionResolver);
this.editors = this.createHasManyThroughRepositoryFactoryFor(
'editors',
userRepositoryGetter,
experienceEditorRepositoryGetter,
);
this.registerInclusionResolver('editors', this.editors.inclusionResolver);
this.user = this.createBelongsToAccessorFor('user', userRepositoryGetter);
this.registerInclusionResolver('user', this.user.inclusionResolver);
}
Expand Down
1 change: 1 addition & 0 deletions src/repositories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './exchange-rate.repository';
export * from './experience.repository';
export * from './experience-post.repository';
export * from './experience-user.repository';
export * from './experience-editor.repository';
export * from './friend.repository';
export * from './identity.repository';
export * from './language-setting.repository';
Expand Down
19 changes: 18 additions & 1 deletion src/services/user-experience.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export class UserExperienceService {
public async create(
experience: Omit<Experience, 'id'>,
clonedId?: string,
editors?: string[],
): Promise<Experience> {
const userId = experience.createdBy;
const people = this.validateExperienceData(experience);
Expand All @@ -278,7 +279,7 @@ export class UserExperienceService {
return this.userRepository
.experiences(userId)
.create(experience)
.then(async exp => this.afterCreate(exp, people, clonedId));
.then(async exp => this.afterCreate(exp, people, clonedId, editors));
}

public async subscribe(
Expand Down Expand Up @@ -348,6 +349,7 @@ export class UserExperienceService {
experience: Experience,
people: People[],
clonedId?: string,
editors?: string[],
): Promise<Experience> {
const userId = experience.createdBy;
const experienceId = experience?.id ?? '';
Expand Down Expand Up @@ -420,6 +422,21 @@ export class UserExperienceService {
);
}

if (editors) {
editors.map(editor => {
const link = this.experienceRepository
.editors(experienceId)
.link(editor);
const creation = this.userExperienceRepository.create({
userId: editor,
experienceId,
});
promises.push(link);
promises.push(creation);
return editor;
});
}

Promise.allSettled(promises) as Promise<AnyObject>;

return experience;
Expand Down
7 changes: 4 additions & 3 deletions src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,12 +783,13 @@ export class UserService {
}

public async createExperience(
experince: Omit<Experience, 'id'>,
experience: Omit<Experience, 'id'>,
clonedId?: string,
editors?: string[],
): Promise<Experience> {
await this.haveFullAccess(ControllerType.USEREXPERIENCE);
experince.createdBy = this.currentUser[securityId];
return this.userExperienceService.create(experince, clonedId);
experience.createdBy = this.currentUser[securityId];
return this.userExperienceService.create(experience, clonedId, editors);
}

public async subscribeExperience(id: string): Promise<UserExperience> {
Expand Down

0 comments on commit bdf2167

Please sign in to comment.