Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Organization Project Modules management (FIx module creation && update) #8575

Merged
merged 19 commits into from
Dec 6, 2024

Conversation

samuelmbabhazi
Copy link
Contributor

@samuelmbabhazi samuelmbabhazi commented Dec 5, 2024

PR

Please note: we will close your PR without comment if you do not check the boxes above and provide ALL requested information.


Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced management of organization project modules and associated employees with new methods for adding, updating, and deleting members.
    • Improved handling of project module data in the UI, including separation of managers and non-managers.
  • Bug Fixes

    • Streamlined error handling in various services to provide clearer feedback and maintain consistent state during data loading failures.
  • Documentation

    • Updated method signatures and error handling practices across multiple services to enhance clarity and maintainability.
  • Refactor

    • Simplified data retrieval processes in several components and services to improve performance and readability.

@samuelmbabhazi samuelmbabhazi self-assigned this Dec 5, 2024
Copy link
Contributor

coderabbitai bot commented Dec 5, 2024

Walkthrough

This pull request introduces significant modifications across several files, primarily focusing on the IMemberEntityBased interface and its implications for managing project modules and employees. The IMemberEntityBased interface has been decoupled from its base interface, altering its structure. Additionally, various service classes have been updated to enhance member management, including the introduction of new methods and improved error handling. Changes also extend to data transfer objects (DTOs) and UI components, reflecting a comprehensive update to how project and employee data is handled throughout the application.

Changes

File Change Summary
packages/contracts/src/employee.model.ts Removed inheritance of IMemberEntityBased from IBasePerTenantAndOrganizationEntityModel.
packages/core/src/organization-project-module/dto/create-organization-project-module.dto.ts Updated CreateOrganizationProjectModuleDTO to use IntersectionType instead of OmitType.
packages/core/src/organization-project-module/organization-project-module.service.ts Added methods for managing project module members and improved error handling in create and update methods.
packages/core/src/organization-project/organization-project.service.ts Enhanced update method with explicit relation mapping and refined member management logic.
packages/core/src/organization-sprint/organization-sprint.service.ts Updated update method to specify relations and improved member management logic.
packages/core/src/resource-link/resource-link.service.ts Simplified update method by removing dynamic relation mapping and changing error handling.
packages/core/src/tasks/commands/handlers/automation-task.sync.handler.ts Updated updateTask method to explicitly define relations for task fetching.
packages/core/src/tasks/task.service.ts Refined filtering logic in pagination and findTasksByViewQuery methods.
packages/ui-core/shared/src/lib/project/project-module/add-project-module-dialog/add-project-module-dialog.component.ts Modified updateFormFields method to set managerIds form field directly and streamlined error handling in data loading methods.
packages/ui-core/shared/src/lib/project/project-module/module-table/project-module-table.component.ts Expanded imports and updated methods for managing employee roles within project modules. Added new methods for filtering managers and non-managers.

Possibly related PRs

Suggested labels

hold

Suggested reviewers

  • GloireMutaliko21

🐰 In the code, we hop and play,
With members and projects, we find our way.
Interfaces change, new paths we chart,
Enhancing our code, a true work of art!
So let’s celebrate with a joyful cheer,
For every change brings us closer, my dear! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@rahul-rocket rahul-rocket marked this pull request as ready for review December 6, 2024 05:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (6)
packages/core/src/tasks/task.service.ts (1)

71-84: Consider refactoring the relations object to reduce duplication

The relations object is being explicitly defined here. Since a similar relations object is also defined in automation-task.sync.handler.ts, consider extracting this into a shared constant or utility function to adhere to the DRY principle and improve maintainability.

packages/core/src/tasks/commands/handlers/automation-task.sync.handler.ts (1)

180-193: Consider refactoring the relations object to reduce duplication

The relations object defined here is identical to the one in task.service.ts. To adhere to the DRY principle, consider extracting this common definition into a shared constant or utility function to avoid code duplication and enhance maintainability.

packages/core/src/organization-project/organization-project.service.ts (1)

Line range hint 478-484: Inconsistent use of 'role' and 'roleId' properties

When updating existing members, you use the role property, but when adding new members, you use roleId. This inconsistency may lead to issues in how roles are assigned to members.

Ensure consistent property usage by modifying the update operation:

// In the update of existing members
await this.typeOrmOrganizationProjectEmployeeRepository.update(member.id, {
-    role: newRole,
+    roleId: newRole?.id,
     isManager
});

And when adding new members, ensure the same property is used:

new OrganizationProjectEmployee({
    organizationProjectId,
    employeeId: employee.id,
    tenantId,
    organizationId,
    isManager: managerIds.includes(employee.id),
-   roleId: managerIds.includes(employee.id) ? managerRole.id : null
+   roleId: managerIds.includes(employee.id) ? managerRole?.id : null
})

Also applies to: 492-498

packages/core/src/organization-project-module/organization-project-module.service.ts (1)

150-161: Remove unnecessary console logs

Debugging statements like console.log should be removed from production code to maintain code cleanliness and prevent unintended information disclosure.

Apply this diff to remove the console logs:

- console.log(Array.isArray(memberIds), Array.isArray(managerIds));
packages/core/src/organization-project-module/dto/create-organization-project-module.dto.ts (1)

12-12: Clarify the usage of IntersectionType in DTO definition

The nested IntersectionType usage may lead to complexity in the DTO structure. Consider simplifying the DTO definition for better readability and maintainability.

Refactor the DTO definition as needed to make it more straightforward, possibly by flattening or reorganizing the types.

packages/core/src/resource-link/resource-link.service.ts (1)

83-83: Adjust exception type for resource not found

In the update method, changing the exception from NotFoundException to BadRequestException may not accurately represent the error condition. A NotFoundException is more appropriate when the resource does not exist.

Consider reverting to NotFoundException for clearer semantics:

- throw new BadRequestException('Resource Link not found');
+ throw new NotFoundException('Resource Link not found');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d015d13 and 8272ab2.

📒 Files selected for processing (10)
  • packages/contracts/src/employee.model.ts (1 hunks)
  • packages/core/src/organization-project-module/dto/create-organization-project-module.dto.ts (2 hunks)
  • packages/core/src/organization-project-module/organization-project-module.service.ts (7 hunks)
  • packages/core/src/organization-project/organization-project.service.ts (1 hunks)
  • packages/core/src/organization-sprint/organization-sprint.service.ts (1 hunks)
  • packages/core/src/resource-link/resource-link.service.ts (1 hunks)
  • packages/core/src/tasks/commands/handlers/automation-task.sync.handler.ts (2 hunks)
  • packages/core/src/tasks/task.service.ts (2 hunks)
  • packages/ui-core/shared/src/lib/project/project-module/add-project-module-dialog/add-project-module-dialog.component.ts (1 hunks)
  • packages/ui-core/shared/src/lib/project/project-module/module-table/project-module-table.component.ts (6 hunks)
🧰 Additional context used
📓 Learnings (1)
packages/contracts/src/employee.model.ts (1)
Learnt from: GloireMutaliko21
PR: ever-co/ever-gauzy#8573
File: packages/contracts/src/employee.model.ts:293-296
Timestamp: 2024-12-05T09:19:04.024Z
Learning: In this codebase, it's acceptable for `IMemberEntityBased` to not extend `IBasePerTenantAndOrganizationEntityModel` because the child interfaces already include these properties.
🔇 Additional comments (6)
packages/core/src/tasks/task.service.ts (1)

11-12: Import statements are appropriate

The import of Between and FindOptionsRelations from 'typeorm' is necessary for the subsequent usage in the code.

packages/core/src/tasks/commands/handlers/automation-task.sync.handler.ts (1)

3-3: Import statement is appropriate

The import of FindOptionsRelations is necessary for defining the relations object in the code.

packages/contracts/src/employee.model.ts (1)

293-296: LGTM! Interface decoupling improves separation of concerns.

The decoupling of IMemberEntityBased from IBasePerTenantAndOrganizationEntityModel is a good architectural decision as it promotes better separation of concerns and reduces inheritance complexity. This aligns with the established pattern where child interfaces already include tenant and organization properties.

packages/core/src/organization-sprint/organization-sprint.service.ts (1)

154-154: LGTM! Explicit relations improve code clarity and type safety.

The explicit specification of relations (project, members, modules) is better than dynamic mapping as it:

  1. Provides better clarity about which related entities are being loaded
  2. Ensures type safety
  3. Makes the code more maintainable by making dependencies visible
packages/ui-core/shared/src/lib/project/project-module/add-project-module-dialog/add-project-module-dialog.component.ts (1)

233-235: LGTM! Improved manager validation ensures data integrity.

The explicit setting of filtered managerIds to the form control is a good improvement as it:

  1. Validates that managers exist in the employees list
  2. Prevents invalid manager assignments
  3. Maintains data integrity in the form
packages/core/src/organization-project/organization-project.service.ts (1)

158-160: Ensure all necessary relations are included when fetching the project

In the update method, you fetch the organizationProject with specified relations. Verify that all required relations are included to avoid incomplete data issues during the update.

Run the following script to check for any missing relations:

✅ Verification successful

The current relations configuration is appropriate for the update operation

Based on the entity definition and update method implementation, the current relations being loaded (image, members, organizationContact, tags, teams) are sufficient for the update operation. These relations match the entity's structure and are actively used in the update process, particularly for member management and team associations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for relations used in the project entity that might be missing.

# Search for usages of 'organizationProject' properties that require relations.
rg -A 5 'organizationProject\.' packages/core/src/organization-project/organization-project.service.ts | grep -E '\.(members|tasks|teams|tags|image|organizationContact)\b'

Length of output: 173


Script:

#!/bin/bash
# Let's try a different approach to analyze the relations:

# 1. First, let's see the entity definition to understand all possible relations
echo "=== OrganizationProject Entity Definition ==="
ast-grep --pattern 'class OrganizationProject {
  $$$
}'

# 2. Then, let's check the update method implementation to see how these relations are used
echo -e "\n=== Update Method Implementation ==="
ast-grep --pattern 'async update($$$) {
  $$$
}'

# 3. Finally, let's see all usages of organizationProject in the service
echo -e "\n=== organizationProject Usages ==="
rg "organizationProject\." -B 2 -A 2 packages/core/src/organization-project/organization-project.service.ts

Length of output: 494


Script:

#!/bin/bash
# Let's try a more specific approach to find the entity file and analyze its relations

# 1. Find the entity file
echo "=== Finding OrganizationProject Entity File ==="
fd "organization-project.entity.ts"

# 2. If found, let's examine its content
echo -e "\n=== Entity Relations ==="
rg "@(ManyToOne|OneToMany|ManyToMany|OneToOne)" -B 1 -A 1 $(fd "organization-project.entity.ts")

# 3. Let's also check the update method specifically
echo -e "\n=== Update Method Content ==="
rg "async update" -B 2 -A 10 packages/core/src/organization-project/organization-project.service.ts

Length of output: 2651


Script:

#!/bin/bash
# Let's examine the entity file content to see all relations and their usage

echo "=== Entity File Content ==="
cat packages/core/src/organization-project/organization-project.entity.ts

echo -e "\n=== Update Method Usage of Relations ==="
# Look for any property access after the findOneByIdString call
rg -A 15 "const organizationProject = await super.findOneByIdString" packages/core/src/organization-project/organization-project.service.ts

Length of output: 13838

Comment on lines +168 to +175
managers: {
title: this.getTranslation('ORGANIZATIONS_PAGE.EDIT.TEAMS_PAGE.MANAGERS'),
type: 'custom',
isFilterable: false,
renderComponent: EmployeeWithLinksComponent,
componentInitFunction: (instance: EmployeeWithLinksComponent, cell: Cell) => {
componentInitFunction: (instance: EmployeesMergedTeamsComponent, cell: Cell) => {
instance.rowData = cell.getRow().getData();
instance.value = cell.getRawValue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistent component types in 'managers' column configuration

The renderComponent is set to EmployeeWithLinksComponent, but the componentInitFunction uses EmployeesMergedTeamsComponent. This mismatch could lead to runtime errors or unexpected behavior.

Apply this diff to align the component types:

managers: {
    title: this.getTranslation('ORGANIZATIONS_PAGE.EDIT.TEAMS_PAGE.MANAGERS'),
    type: 'custom',
    isFilterable: false,
-   renderComponent: EmployeeWithLinksComponent,
+   renderComponent: EmployeesMergedTeamsComponent,
    componentInitFunction: (instance: EmployeesMergedTeamsComponent, cell: Cell) => {
        instance.rowData = cell.getRow().getData();
        instance.value = cell.getRawValue();
    }
},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
managers: {
title: this.getTranslation('ORGANIZATIONS_PAGE.EDIT.TEAMS_PAGE.MANAGERS'),
type: 'custom',
isFilterable: false,
renderComponent: EmployeeWithLinksComponent,
componentInitFunction: (instance: EmployeeWithLinksComponent, cell: Cell) => {
componentInitFunction: (instance: EmployeesMergedTeamsComponent, cell: Cell) => {
instance.rowData = cell.getRow().getData();
instance.value = cell.getRawValue();
managers: {
title: this.getTranslation('ORGANIZATIONS_PAGE.EDIT.TEAMS_PAGE.MANAGERS'),
type: 'custom',
isFilterable: false,
renderComponent: EmployeesMergedTeamsComponent,
componentInitFunction: (instance: EmployeesMergedTeamsComponent, cell: Cell) => {
instance.rowData = cell.getRow().getData();
instance.value = cell.getRawValue();

Comment on lines +281 to +287
getNonManagerEmployees(projectModule: IOrganizationProjectModule): IEmployee[][] {
return [
projectModule.members
.filter((member: IOrganizationProjectModuleEmployee) => !member.isManager)
.map((member: IOrganizationProjectModuleEmployee) => member.employee)
];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplify return type in 'getNonManagerEmployees' method

The getNonManagerEmployees method returns an array containing a single array of employees (IEmployee[][]), which introduces unnecessary nesting. Consider returning a flat array of employees (IEmployee[]) to simplify data handling.

Apply this diff to simplify the return value:

- getNonManagerEmployees(projectModule: IOrganizationProjectModule): IEmployee[][] {
-     return [
-         projectModule.members
-             .filter((member: IOrganizationProjectModuleEmployee) => !member.isManager)
-             .map((member: IOrganizationProjectModuleEmployee) => member.employee)
-     ];
+ getNonManagerEmployees(projectModule: IOrganizationProjectModule): IEmployee[] {
+     return projectModule.members
+         .filter((member: IOrganizationProjectModuleEmployee) => !member.isManager)
+         .map((member: IOrganizationProjectModuleEmployee) => member.employee);
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
getNonManagerEmployees(projectModule: IOrganizationProjectModule): IEmployee[][] {
return [
projectModule.members
.filter((member: IOrganizationProjectModuleEmployee) => !member.isManager)
.map((member: IOrganizationProjectModuleEmployee) => member.employee)
];
}
getNonManagerEmployees(projectModule: IOrganizationProjectModule): IEmployee[] {
return projectModule.members
.filter((member: IOrganizationProjectModuleEmployee) => !member.isManager)
.map((member: IOrganizationProjectModuleEmployee) => member.employee);
}

Comment on lines +438 to +503
async updateOrganizationProjectModuleMembers(
organizationProjectModuleId: ID,
organizationId: ID,
employees: IEmployee[],
managerIds: ID[],
memberIds: ID[]
): Promise<void> {
const tenantId = RequestContext.currentTenantId();
const membersToUpdate = new Set([...managerIds, ...memberIds].filter(Boolean));

// Find the manager role
const managerRole = await this._roleService.findOneByWhereOptions({
name: RolesEnum.MANAGER
});

// Fetch existing project members with their roles
const projectMembers = await this.typeOrmOrganizationProjectModuleEmployeeRepository.find({
where: { tenantId, organizationId, organizationProjectModuleId }
});

// Create a map of existing members for quick lookup
const existingMemberMap = new Map(projectMembers.map((member) => [member.employeeId, member]));

// Separate members into removed, updated, and new members
const removedMembers = projectMembers.filter((member) => !membersToUpdate.has(member.employeeId));
const updatedMembers = projectMembers.filter((member) => membersToUpdate.has(member.employeeId));
const newMembers = employees.filter((employee) => !existingMemberMap.has(employee.id));

// 1. Remove members who are no longer assigned to the project
if (removedMembers.length) {
await this.deleteMemberByIds(removedMembers.map((member) => member.id));
}

// 2. Update roles for existing members where necessary
await Promise.all(
updatedMembers.map(async (member) => {
const isManager = managerIds.includes(member.employeeId);
const newRole = isManager ? managerRole : null;

// Only update if the role has changed
if (newRole?.id !== member.roleId) {
await this.typeOrmOrganizationProjectModuleEmployeeRepository.update(member.id, {
role: newRole,
isManager
});
}
})
);

// 3. Add new members to the project
if (newMembers.length) {
const newProjectMembers = newMembers.map(
(employee) =>
new OrganizationProjectModuleEmployee({
organizationProjectModuleId,
employeeId: employee.id,
tenantId,
organizationId,
isManager: managerIds.includes(employee.id),
roleId: managerIds.includes(employee.id) ? managerRole.id : null
})
);

await this.typeOrmOrganizationProjectModuleEmployeeRepository.save(newProjectMembers);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure consistent use of 'role' and 'roleId' properties

Similar to the OrganizationProjectService, there is inconsistency in using role and roleId when updating and adding module members. This may lead to incorrect role assignments.

Modify the update and creation of members to use consistent property names:

// Update existing members
await this.typeOrmOrganizationProjectModuleEmployeeRepository.update(member.id, {
-    role: newRole,
+    roleId: newRole?.id,
     isManager
});

// Add new members
new OrganizationProjectModuleEmployee({
    organizationProjectModuleId,
    employeeId: employee.id,
    tenantId,
    organizationId,
    isManager: managerIds.includes(employee.id),
-   roleId: managerIds.includes(employee.id) ? managerRole.id : null
+   roleId: managerIds.includes(employee.id) ? managerRole?.id : null
})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async updateOrganizationProjectModuleMembers(
organizationProjectModuleId: ID,
organizationId: ID,
employees: IEmployee[],
managerIds: ID[],
memberIds: ID[]
): Promise<void> {
const tenantId = RequestContext.currentTenantId();
const membersToUpdate = new Set([...managerIds, ...memberIds].filter(Boolean));
// Find the manager role
const managerRole = await this._roleService.findOneByWhereOptions({
name: RolesEnum.MANAGER
});
// Fetch existing project members with their roles
const projectMembers = await this.typeOrmOrganizationProjectModuleEmployeeRepository.find({
where: { tenantId, organizationId, organizationProjectModuleId }
});
// Create a map of existing members for quick lookup
const existingMemberMap = new Map(projectMembers.map((member) => [member.employeeId, member]));
// Separate members into removed, updated, and new members
const removedMembers = projectMembers.filter((member) => !membersToUpdate.has(member.employeeId));
const updatedMembers = projectMembers.filter((member) => membersToUpdate.has(member.employeeId));
const newMembers = employees.filter((employee) => !existingMemberMap.has(employee.id));
// 1. Remove members who are no longer assigned to the project
if (removedMembers.length) {
await this.deleteMemberByIds(removedMembers.map((member) => member.id));
}
// 2. Update roles for existing members where necessary
await Promise.all(
updatedMembers.map(async (member) => {
const isManager = managerIds.includes(member.employeeId);
const newRole = isManager ? managerRole : null;
// Only update if the role has changed
if (newRole?.id !== member.roleId) {
await this.typeOrmOrganizationProjectModuleEmployeeRepository.update(member.id, {
role: newRole,
isManager
});
}
})
);
// 3. Add new members to the project
if (newMembers.length) {
const newProjectMembers = newMembers.map(
(employee) =>
new OrganizationProjectModuleEmployee({
organizationProjectModuleId,
employeeId: employee.id,
tenantId,
organizationId,
isManager: managerIds.includes(employee.id),
roleId: managerIds.includes(employee.id) ? managerRole.id : null
})
);
await this.typeOrmOrganizationProjectModuleEmployeeRepository.save(newProjectMembers);
}
}
async updateOrganizationProjectModuleMembers(
organizationProjectModuleId: ID,
organizationId: ID,
employees: IEmployee[],
managerIds: ID[],
memberIds: ID[]
): Promise<void> {
const tenantId = RequestContext.currentTenantId();
const membersToUpdate = new Set([...managerIds, ...memberIds].filter(Boolean));
// Find the manager role
const managerRole = await this._roleService.findOneByWhereOptions({
name: RolesEnum.MANAGER
});
// Fetch existing project members with their roles
const projectMembers = await this.typeOrmOrganizationProjectModuleEmployeeRepository.find({
where: { tenantId, organizationId, organizationProjectModuleId }
});
// Create a map of existing members for quick lookup
const existingMemberMap = new Map(projectMembers.map((member) => [member.employeeId, member]));
// Separate members into removed, updated, and new members
const removedMembers = projectMembers.filter((member) => !membersToUpdate.has(member.employeeId));
const updatedMembers = projectMembers.filter((member) => membersToUpdate.has(member.employeeId));
const newMembers = employees.filter((employee) => !existingMemberMap.has(employee.id));
// 1. Remove members who are no longer assigned to the project
if (removedMembers.length) {
await this.deleteMemberByIds(removedMembers.map((member) => member.id));
}
// 2. Update roles for existing members where necessary
await Promise.all(
updatedMembers.map(async (member) => {
const isManager = managerIds.includes(member.employeeId);
const newRole = isManager ? managerRole : null;
// Only update if the role has changed
if (newRole?.id !== member.roleId) {
await this.typeOrmOrganizationProjectModuleEmployeeRepository.update(member.id, {
roleId: newRole?.id,
isManager
});
}
})
);
// 3. Add new members to the project
if (newMembers.length) {
const newProjectMembers = newMembers.map(
(employee) =>
new OrganizationProjectModuleEmployee({
organizationProjectModuleId,
employeeId: employee.id,
tenantId,
organizationId,
isManager: managerIds.includes(employee.id),
roleId: managerIds.includes(employee.id) ? managerRole?.id : null
})
);
await this.typeOrmOrganizationProjectModuleEmployeeRepository.save(newProjectMembers);
}
}

const projectModule = await super.create({
...input,
members,
creatorId
});
console.log(input.tasks,projectModule )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samuelmbabhazi Please remove console.log

@rahul-rocket rahul-rocket merged commit 1abe199 into develop Dec 6, 2024
14 of 19 checks passed
@rahul-rocket rahul-rocket deleted the fix/#8532-adding-manager branch December 6, 2024 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants