Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions web/core/components/issues/issue-detail/reactions/issue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ export type TIssueReaction = {
issueId: string;
currentUser: IUser;
disabled?: boolean;
className?: string;
};

export const IssueReaction: FC<TIssueReaction> = observer((props) => {
const { workspaceSlug, projectId, issueId, currentUser, disabled = false } = props;
const { workspaceSlug, projectId, issueId, currentUser, disabled = false, className = "" } = props;
// hooks
const {
reaction: { getReactionsByIssueId, reactionsByUser, getReactionById },
Expand Down Expand Up @@ -92,7 +93,7 @@ export const IssueReaction: FC<TIssueReaction> = observer((props) => {
};

return (
<div className="relative mt-4 flex items-center gap-1.5">
<div className={cn("relative mt-4 flex items-center gap-1.5", className)}>
{!disabled && (
<ReactionSelector size="md" position="top" value={userReactions} onSelect={issueReactionOperations.react} />
)}
Expand Down
57 changes: 33 additions & 24 deletions web/core/store/project/project.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ import { ProjectService, ProjectStateService, ProjectArchiveService } from "@/se
// store
import { CoreRootStore } from "../root.store";

type ProjectOverviewCollapsible = "links" | "attachments";

export interface IProjectStore {
// observables
isUpdatingProject: boolean;
loader: boolean;
projectMap: {
[projectId: string]: TProject; // projectId: project Info
};
projectEpicPropertiesMap: {
[projectId: string]: any;
};
// computed
filteredProjectIds: string[] | undefined;
workspaceProjectIds: string[] | undefined;
Expand All @@ -32,9 +31,15 @@ export interface IProjectStore {
// actions
getProjectById: (projectId: string | undefined | null) => TProject | undefined;
getProjectIdentifierById: (projectId: string | undefined | null) => string;
getProjectEpicPropertiesById: (projectId: string | undefined | null) => any;
// collapsible
openCollapsibleSection: ProjectOverviewCollapsible[];
lastCollapsibleAction: ProjectOverviewCollapsible | null;

setOpenCollapsibleSection: (section: ProjectOverviewCollapsible[]) => void;
setLastCollapsibleAction: (section: ProjectOverviewCollapsible) => void;
toggleOpenCollapsibleSection: (section: ProjectOverviewCollapsible) => void;

// fetch actions
fetchProjectEpicProperties: (workspaceSlug: string, projectId: string) => Promise<any>;
fetchProjects: (workspaceSlug: string) => Promise<TProject[]>;
fetchProjectDetails: (workspaceSlug: string, projectId: string) => Promise<TProject>;
// favorites actions
Expand All @@ -58,9 +63,9 @@ export class ProjectStore implements IProjectStore {
projectMap: {
[projectId: string]: TProject; // projectId: project Info
} = {};
projectEpicPropertiesMap: {
[projectId: string]: any;
} = {};
openCollapsibleSection: ProjectOverviewCollapsible[] = [];
lastCollapsibleAction: ProjectOverviewCollapsible | null = null;

// root store
rootStore: CoreRootStore;
// service
Expand All @@ -76,6 +81,8 @@ export class ProjectStore implements IProjectStore {
isUpdatingProject: observable,
loader: observable.ref,
projectMap: observable,
openCollapsibleSection: observable.ref,
lastCollapsibleAction: observable.ref,
// computed
filteredProjectIds: computed,
workspaceProjectIds: computed,
Expand All @@ -85,7 +92,6 @@ export class ProjectStore implements IProjectStore {
joinedProjectIds: computed,
favoriteProjectIds: computed,
// fetch actions
fetchProjectEpicProperties: action,
fetchProjects: action,
fetchProjectDetails: action,
// favorites actions
Expand All @@ -96,6 +102,10 @@ export class ProjectStore implements IProjectStore {
// CRUD actions
createProject: action,
updateProject: action,
// collapsible actions
setOpenCollapsibleSection: action,
setLastCollapsibleAction: action,
toggleOpenCollapsibleSection: action,
});
// root store
this.rootStore = _rootStore;
Expand Down Expand Up @@ -214,23 +224,22 @@ export class ProjectStore implements IProjectStore {
return projectIds;
}

fetchProjectEpicProperties = async (workspaceSlug: string, projectId: string) => {
try {
const response = await this.projectService.fetchProjectEpicProperties(workspaceSlug, projectId);
runInAction(() => {
set(this.projectEpicPropertiesMap, [projectId], response);
});
return response;
} catch (error) {
console.log("Failed to fetch epic properties from project store");
throw error;
}
setOpenCollapsibleSection = (section: ProjectOverviewCollapsible[]) => {
this.openCollapsibleSection = section;
if (this.lastCollapsibleAction) this.lastCollapsibleAction = null;
};

getProjectEpicPropertiesById = computedFn((projectId: string | undefined | null) => {
const projectEpicProperties = this.projectEpicPropertiesMap[projectId ?? ""];
return projectEpicProperties;
});
setLastCollapsibleAction = (section: ProjectOverviewCollapsible) => {
this.openCollapsibleSection = [section];
};
Comment on lines +232 to +234
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

Method implementation doesn't match its name.

The setLastCollapsibleAction method not only sets the last action but also modifies the openCollapsibleSection. This violates the Single Responsibility Principle and is inconsistent with the method name.

Consider separating the concerns:

  setLastCollapsibleAction = (section: ProjectOverviewCollapsible) => {
-   this.openCollapsibleSection = [section];
+   this.lastCollapsibleAction = section;
  };

Committable suggestion skipped: line range outside the PR's diff.


toggleOpenCollapsibleSection = (section: ProjectOverviewCollapsible) => {
if (this.openCollapsibleSection && this.openCollapsibleSection.includes(section)) {
this.openCollapsibleSection = this.openCollapsibleSection.filter((s) => s !== section);
} else {
this.openCollapsibleSection = [...this.openCollapsibleSection, section];
}
};
Comment on lines +236 to +242
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

Add null check and use optional chaining.

The toggleOpenCollapsibleSection method should handle the case where openCollapsibleSection is null and use optional chaining for better safety.

Apply this diff to improve the implementation:

  toggleOpenCollapsibleSection = (section: ProjectOverviewCollapsible) => {
-   if (this.openCollapsibleSection && this.openCollapsibleSection.includes(section)) {
+   if (this.openCollapsibleSection?.includes(section)) {
      this.openCollapsibleSection = this.openCollapsibleSection.filter((s) => s !== section);
    } else {
-     this.openCollapsibleSection = [...this.openCollapsibleSection, section];
+     this.openCollapsibleSection = [...(this.openCollapsibleSection ?? []), section];
    }
  };
📝 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
toggleOpenCollapsibleSection = (section: ProjectOverviewCollapsible) => {
if (this.openCollapsibleSection && this.openCollapsibleSection.includes(section)) {
this.openCollapsibleSection = this.openCollapsibleSection.filter((s) => s !== section);
} else {
this.openCollapsibleSection = [...this.openCollapsibleSection, section];
}
};
toggleOpenCollapsibleSection = (section: ProjectOverviewCollapsible) => {
if (this.openCollapsibleSection?.includes(section)) {
this.openCollapsibleSection = this.openCollapsibleSection.filter((s) => s !== section);
} else {
this.openCollapsibleSection = [...(this.openCollapsibleSection ?? []), section];
}
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 237-237: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


/**
* get Workspace projects using workspace slug
Expand Down
Loading