Skip to content

[WEB-4321]chore: workspace views refactor #7214

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

Merged
merged 9 commits into from
Jun 19, 2025

Conversation

vamsikrishnamathala
Copy link
Member

@vamsikrishnamathala vamsikrishnamathala commented Jun 13, 2025

Description

This update refactors workspace views for better modularity.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Summary by CodeRabbit

  • New Features

    • Introduced layout-aware filtering and layout selection for workspace issue views, allowing users to switch between different layouts and receive layout-specific filter options.
    • Added support for enabling or disabling dependency management in Gantt charts, with options to control this feature globally or per block.
    • Added new workspace spreadsheet layout for issue management with improved permission checks and quick actions.
  • Improvements

    • Enhanced project context in Gantt chart blocks and update payloads, providing better project association for issues.
    • Updated issue visibility rules for guest users based on project settings, improving access control.
    • Refined filter fetching and display logic for more accurate and reliable workspace issue filtering.
    • Improved import organization and code structure in issue stores and hooks.
  • Bug Fixes

    • Improved handling of display filters to avoid empty filter overrides.
    • Adjusted issue date update flows and project ID handling for better consistency and error prevention.
  • Refactor

    • Simplified and centralized workspace layout rendering logic for easier maintenance and extensibility.
    • Streamlined root components and store logic for better code organization and performance.
    • Removed redundant early returns in issue label components to ensure consistent rendering logic.

Copy link
Contributor

coderabbitai bot commented Jun 13, 2025

Walkthrough

This update introduces layout-aware filtering and dependency management for workspace issue views, particularly enhancing Gantt chart and spreadsheet layouts. It adds new props and types for layout and dependency control, refactors several components to support dynamic layouts, and implements conditional rendering and logic for issue relations and permissions. Backend and utility changes support these features with improved data structures and access control.

Changes

File(s) Change Summary
web/app/(all)/[workspaceSlug]/(projects)/workspace-views/header.tsx Refined GlobalIssuesHeader for layout-aware display filter management, added layout selection, and dynamic filter options.
web/ce/components/views/helper.tsx Added type and placeholder components for layout selection and additional layouts.
web/ce/store/issue/workspace/issue.store.ts Added re-export of all exports from another module.
web/ce/store/timeline/base-timeline.store.ts Extended BlockData type and updateBlocks to include optional project_id.
web/core/components/gantt-chart/blocks/block.tsx Added enableDependency boolean prop to GanttChartBlock and passed to child.
web/core/components/gantt-chart/blocks/blocks-list.tsx Added enableDependency prop (boolean or function) to block list and passed to blocks.
web/core/components/gantt-chart/chart/main-content.tsx Added enableDependency prop and passed to block list.
web/core/components/gantt-chart/chart/root.tsx Added enableDependency prop and passed to main content.
web/core/components/gantt-chart/helpers/draggable.tsx Added enableDependency prop; dependency drag handles rendered conditionally.
web/core/components/gantt-chart/root.tsx Added optional enableDependency prop, defaulting to false, and passed to chart view root.
web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx Changed argument order for updateIssueDates and updated dependency array.
web/core/components/issues/issue-layouts/properties/labels.tsx Removed early return guard, allowing logic to execute when value is falsy.
web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx Refactored to delegate rendering to WorkspaceActiveLayout, removed direct issue management and permission checks.
web/core/components/issues/issue-layouts/spreadsheet/roots/workspace-root.tsx Added new WorkspaceSpreadsheetRoot component for spreadsheet layout with permissions and actions.
web/core/components/views/helper.tsx Added WorkspaceActiveLayout to select and render layouts based on active type.
web/core/hooks/store/use-issues.ts Adjusted imports for workspace issues types.
web/core/services/workspace.service.ts Modified getViewIssues to use a different endpoint if issue_relation is expanded.
web/core/store/issue/helpers/base-issues.store.ts Changed updateIssueDates signature to make projectId optional and reordered parameters.
web/core/store/issue/issue-details/relation.store.ts Changed how projectId is retrieved in createCurrentRelation method.
web/core/store/issue/root.store.ts Adjusted imports for workspace issues types and classes.
web/core/store/issue/workspace/filter.store.ts Refactored fetchFilters logic, removed outer try-catch, and simplified control flow.
apiserver/plane/app/views/issue/base.py Added role-based filtering for issue visibility in IssueDetailEndpoint.get.
packages/types/src/layout/gantt.d.ts Extended IGanttBlock and IBlockUpdateDependencyData with project_id.
packages/utils/src/work-item/base.ts Updated getIssueBlocksStructure and getComputedDisplayFilters for project ID and empty filter handling.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GlobalIssuesHeader
    participant GlobalViewLayoutSelection
    participant WorkspaceActiveLayout
    participant WorkspaceSpreadsheetRoot
    participant GanttChartRoot
    participant ChartViewRoot
    participant GanttChartMainContent
    participant GanttChartBlocksList
    participant GanttChartBlock
    participant ChartDraggable

    User->>GlobalIssuesHeader: Selects layout
    GlobalIssuesHeader->>GlobalViewLayoutSelection: Renders layout selector
    GlobalViewLayoutSelection-->>GlobalIssuesHeader: onChange(layout)
    GlobalIssuesHeader->>WorkspaceActiveLayout: Renders with activeLayout
    WorkspaceActiveLayout->>WorkspaceSpreadsheetRoot: If layout == SPREADSHEET
    WorkspaceActiveLayout->>WorkspaceAdditionalLayouts: If other layout
    WorkspaceSpreadsheetRoot->>GanttChartRoot: Renders Gantt chart with enableDependency
    GanttChartRoot->>ChartViewRoot: Passes enableDependency
    ChartViewRoot->>GanttChartMainContent: Passes enableDependency
    GanttChartMainContent->>GanttChartBlocksList: Passes enableDependency
    GanttChartBlocksList->>GanttChartBlock: Passes enableDependency (per block)
    GanttChartBlock->>ChartDraggable: Passes enableDependency
    ChartDraggable->>ChartDraggable: Conditionally render dependency handles
Loading

Suggested labels

🌐frontend

Suggested reviewers

  • prateekshourya29
  • vamsikrishnamathala

Poem

In the warren of code, a new path appears,
Layouts now shift as the user steers.
Gantt blocks gain wisdom, dependencies bloom,
Filters grow smarter, more features resume.
With a hop and a skip, the workspace feels bright—
Rabbits rejoice in this layout delight! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

Copy link

makeplane bot commented Jun 13, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

@vamsikrishnamathala vamsikrishnamathala marked this pull request as ready for review June 16, 2025 07:07
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: 8

🔭 Outside diff range comments (1)
web/core/services/workspace.service.ts (1)

265-276: ⚠️ Potential issue

Potential APIService.get signature mismatch – may cause runtime/TS errors

this.get is now invoked with three positional args (path, { params }, config).
Throughout the rest of the service (searchWorkspace, fetchWorkspaceRecents, etc.) get is called with two args (url, config), with config embedding params.

Unless APIService.get() is explicitly overloaded to accept (url, paramsWrapper, config), this change will:

  1. Break TypeScript checks (excess argument).
  2. Drop config at runtime – Axios will treat the second param as the config object and silently ignore the third.

Proposed fix – merge params into the optional config and keep the 2-arg call:

-    return this.get(
-      path,
-      {
-        params,
-      },
-      config
-    )
+    const requestConfig = { ...(config ?? {}), params };
+    return this.get(path, requestConfig);

Double-check APIService.get’s signature and add a unit test to cover both branches of the new path selection logic.

♻️ Duplicate comments (1)
web/core/components/gantt-chart/helpers/draggable.tsx (1)

33-34: Same issue for right handle – patch together with previous diff

Ensure both left and right dependency draggables apply the predicate logic; see diff above.

🧹 Nitpick comments (12)
web/core/hooks/store/use-issues.ts (1)

12-13: Mixed import roots for workspace stores

IWorkspaceIssues is now imported from @/plane-web/store/issue/workspace/issue.store, while the corresponding IWorkspaceIssuesFilter still comes from @/store/issue/workspace.
For consistency (and to avoid bundler duplication of the same module under two paths) consider re-exporting the filter alongside the store or updating this import to the same alias.

web/core/components/gantt-chart/blocks/block.tsx (1)

23-24: Default enableDependency value

enableDependency is required here, but many existing call-sites might not pass it yet.
Either make the prop optional with a default of false, or ensure every upstream component forwards a definite boolean.

web/ce/store/timeline/base-timeline.store.ts (1)

198-199: Minor optimisation suggestion

Because project_id will rarely change, you could skip the deep-compare for it inside the update loop to spare a few isEqual cycles per frame:

-          const currValue = this.blocksMap[blockId][key as keyof IGanttBlock];
+          if (key === "project_id") continue; // id is immutable
+          const currValue = this.blocksMap[blockId][key as keyof IGanttBlock];

Not critical, but the inner loop runs often while dragging large datasets.

web/core/components/gantt-chart/chart/main-content.tsx (1)

49-50: Prop added – consider defaulting behaviour

enableDependency is optional yet immediately destructured. If a parent forgets to pass it, its value is undefined which is falsy – fine – but an explicit default (e.g. const { enableDependency = false } = props;) documents intent and reduces undefined checks downstream.

web/core/components/gantt-chart/chart/root.tsx (1)

40-41: Prop tubing works – guard against backwards-compat

Older callers of ChartViewRoot won’t provide enableDependency; TypeScript will catch missing required props, but if any JS callers exist consider marking the prop optional (enableDependency?: …) here as well.

web/core/services/workspace.service.ts (1)

266-268: Minor: guard against non-array params.expand

includes exists on both string and Array, but the intent seems “array contains value”.
For clarity & type-safety:

const hasRelation = Array.isArray(params.expand) && params.expand.includes("issue_relation");
const path = `/api/workspaces/${workspaceSlug}/${hasRelation ? "issues-detail" : "issues"}/`;

Not blocking, but improves readability and avoids false positives when expand is a comma-separated string.

web/core/store/issue/issue-details/relation.store.ts (1)

185-188: Fallback if issue metadata is not yet hydrated

projectId is now derived from the issue cache. When the relation is created before the issue is fetched, the early return silently does nothing.

Consider surfacing an explicit error or awaiting issue hydration to avoid UX confusion (the “add relation” UI pretends nothing happened).

web/core/components/views/helper.tsx (1)

20-51: Nice centralisation of layout switching

Clean switch statement and prop forwarding.
Future-proofing idea: wrap the component in React.memo to avoid unnecessary re-renders when unrelated props mutate.

web/core/components/gantt-chart/types/index.ts (1)

25-31: Redundant sort_order re-declaration in IBlockUpdatePayload

IBlockUpdateData already declares an optional sort_order field with exactly the same shape.
Re-adding the property provides no extra type-safety and only bloats the alias while risking divergence if one definition is ever updated.

-export type IBlockUpdatePayload = IBlockUpdateData & {
-  sort_order?: {
-    destinationIndex: number;
-    newSortOrder: number;
-    sourceIndex: number;
-  };
-};
+export type IBlockUpdatePayload = IBlockUpdateData;
web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx (1)

1-17: Minor: Organize imports for better readability

Consider grouping imports more consistently:

 import React, { useCallback } from "react";
 import { isEmpty } from "lodash";
 import { observer } from "mobx-react";
 import { useParams, useSearchParams } from "next/navigation";
-// plane constants
 import useSWR from "swr";
+// plane constants
 import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
-// hooks
 // components
-// hooks
 import { EmptyState } from "@/components/common";
 import { WorkspaceActiveLayout } from "@/components/views/helper";
+// hooks
 import { useGlobalView, useIssues } from "@/hooks/store";
 import { useAppRouter } from "@/hooks/use-app-router";
 import { useWorkspaceIssueProperties } from "@/hooks/use-workspace-issue-properties";
-// store
+// assets
 import emptyView from "@/public/empty-state/view.svg";
web/core/components/issues/issue-layouts/spreadsheet/roots/workspace-root.tsx (2)

1-26: Clean up duplicate import section comments

 import React, { useCallback } from "react";
 import { observer } from "mobx-react";
 // plane constants
 import {
   ALL_ISSUES,
   EIssueLayoutTypes,
   EIssueFilterType,
   EIssuesStoreType,
   EUserPermissions,
   EUserPermissionsLevel,
 } from "@plane/constants";
 import { IIssueDisplayFilterOptions } from "@plane/types";
-// hooks
 // components
 import { SpreadsheetView } from "@/components/issues/issue-layouts";
 import { AllIssueQuickActions } from "@/components/issues/issue-layouts/quick-action-dropdowns";
 import { SpreadsheetLayoutLoader } from "@/components/ui";
 // hooks
 import { useIssues, useUserPermissions } from "@/hooks/store";
 import { IssuesStoreContext } from "@/hooks/use-issue-layout-store";
 import { useIssuesActions } from "@/hooks/use-issues-actions";
 import { useWorkspaceIssueProperties } from "@/hooks/use-workspace-issue-properties";
-// store
+// components
 import { IssuePeekOverview } from "../../../peek-overview";
 import { IssueLayoutHOC } from "../../issue-layout-HOC";
+// types
 import { TRenderQuickActions } from "../../list/list-view-types";

90-105: Use optional chaining for cleaner code

The static analysis correctly identifies that optional chaining would be cleaner here.

   const renderQuickActions: TRenderQuickActions = useCallback(
     ({ issue, parentRef, customActionButton, placement, portalElement }) => (
       <AllIssueQuickActions
         parentRef={parentRef}
         customActionButton={customActionButton}
         issue={issue}
         handleDelete={async () => removeIssue(issue.project_id, issue.id)}
-        handleUpdate={async (data) => updateIssue && updateIssue(issue.project_id, issue.id, data)}
-        handleArchive={async () => archiveIssue && archiveIssue(issue.project_id, issue.id)}
+        handleUpdate={async (data) => updateIssue?.(issue.project_id, issue.id, data)}
+        handleArchive={async () => archiveIssue?.(issue.project_id, issue.id)}
         portalElement={portalElement}
         readOnly={!canEditProperties(issue.project_id ?? undefined)}
         placements={placement}
       />
     ),
     [canEditProperties, removeIssue, updateIssue, archiveIssue]
   );
🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fe0415 and dfa551b.

📒 Files selected for processing (23)
  • web/app/(all)/[workspaceSlug]/(projects)/workspace-views/header.tsx (6 hunks)
  • web/ce/components/views/helper.tsx (1 hunks)
  • web/ce/store/issue/workspace/issue.store.ts (1 hunks)
  • web/ce/store/timeline/base-timeline.store.ts (2 hunks)
  • web/core/components/gantt-chart/blocks/block.tsx (3 hunks)
  • web/core/components/gantt-chart/blocks/blocks-list.tsx (3 hunks)
  • web/core/components/gantt-chart/chart/main-content.tsx (3 hunks)
  • web/core/components/gantt-chart/chart/root.tsx (3 hunks)
  • web/core/components/gantt-chart/helpers/draggable.tsx (3 hunks)
  • web/core/components/gantt-chart/root.tsx (3 hunks)
  • web/core/components/gantt-chart/types/index.ts (2 hunks)
  • web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx (1 hunks)
  • web/core/components/issues/issue-layouts/properties/labels.tsx (1 hunks)
  • web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx (6 hunks)
  • web/core/components/issues/issue-layouts/spreadsheet/roots/workspace-root.tsx (1 hunks)
  • web/core/components/views/helper.tsx (1 hunks)
  • web/core/hooks/store/use-issues.ts (1 hunks)
  • web/core/services/workspace.service.ts (1 hunks)
  • web/core/store/issue/helpers/base-issues.store.ts (2 hunks)
  • web/core/store/issue/issue-details/relation.store.ts (1 hunks)
  • web/core/store/issue/root.store.ts (2 hunks)
  • web/core/store/issue/workspace/filter.store.ts (1 hunks)
  • web/helpers/issue.helper.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
web/core/components/views/helper.tsx (2)
web/core/components/issues/issue-layouts/spreadsheet/roots/workspace-root.tsx (1)
  • WorkspaceSpreadsheetRoot (42-137)
web/ce/components/views/helper.tsx (1)
  • WorkspaceAdditionalLayouts (12-12)
web/ce/components/views/helper.tsx (1)
web/core/components/views/helper.tsx (1)
  • TWorkspaceLayoutProps (5-18)
web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx (5)
web/core/hooks/store/use-issues.ts (1)
  • useIssues (83-158)
web/core/hooks/use-workspace-issue-properties.ts (1)
  • useWorkspaceIssueProperties (7-46)
web/core/store/router.store.ts (2)
  • workspaceSlug (69-71)
  • globalViewId (117-119)
web/core/store/issue/workspace/filter.store.ts (1)
  • issueFilters (109-112)
web/core/components/views/helper.tsx (1)
  • WorkspaceActiveLayout (20-51)
web/core/store/issue/helpers/base-issues.store.ts (2)
web/core/store/router.store.ts (1)
  • projectId (85-87)
web/core/components/gantt-chart/types/index.ts (1)
  • IBlockUpdateDependencyData (33-38)
🪛 Biome (1.9.4)
web/core/components/issues/issue-layouts/spreadsheet/roots/workspace-root.tsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (14)
web/ce/store/issue/workspace/issue.store.ts (1)

1-1: Path alias consistency check

Good call adding a thin re-export; it shields callers from the path shuffle.
Double-check that tsconfig.paths (and Jest/Vite aliases, if any) map @/store/* identically in both CE and EE bundles so we don’t create a split-brain import situation at build time.

web/core/components/gantt-chart/blocks/block.tsx (1)

95-96: Prop forwarding verified

Forwarding enableDependency down to ChartDraggable completes the dependency-toggle plumbing – looks correct.

web/core/store/issue/root.store.ts (2)

17-17: Import path refactor looks good

Pulling IWorkspaceIssues and WorkspaceIssues directly from workspace/issue.store removes an unnecessary re-export layer and makes the dependency graph clearer. 👍


36-36: Sanity-check build after the split import

WorkspaceIssuesFilter still comes from ./workspace, while the interfaces now live in workspace/issue.store.
Make sure the barrel file in ./workspace no longer re-exports IWorkspaceIssues / WorkspaceIssues; otherwise duplicate‐identifier errors may slip past CI depending on ts-config paths.

web/ce/store/timeline/base-timeline.store.ts (1)

25-26: Type extension acknowledged – verify downstream typings

Adding project_id to BlockData is a non-breaking, optional extension. Ensure the corresponding IGanttBlock definition has been updated everywhere (IDE still finds only one declaration?) to avoid structural type mismatches during assignment.

web/core/components/gantt-chart/chart/main-content.tsx (1)

225-226: Forwarding prop ✅ – double-check list component signature

GanttChartBlocksList now receives enableDependency, but its prop definition wasn’t shown in this diff. Make sure the new boolean/function union is reflected there; TS won’t complain if the component is untyped.

web/core/components/gantt-chart/chart/root.tsx (2)

74-75: Pipeline: verify prop plumbed from GanttChartRoot

GanttChartRoot (outer wrapper) must now accept & forward enableDependency; ensure its public API and docs are updated, otherwise consumers compiling against previous types will break.


209-210: Prop forwarding looks correct

The prop is forwarded to GanttChartMainContent; once upstream changes are in place no further action is required here. 👍

web/core/components/gantt-chart/root.tsx (1)

26-51: Prop plumbing looks good – verify downstream types

enableDependency is threaded through with a sensible default.
Please confirm ChartViewRoot’s prop definition has been updated; otherwise TypeScript will complain or the value will be silently dropped.

web/core/components/gantt-chart/blocks/blocks-list.tsx (1)

15-47: 👍 Dependency enablement correctly cascaded

Good use of the existing pattern (typeof === "function" ? fn(id) : bool). Implementation is consistent with other feature toggles.

web/core/components/gantt-chart/types/index.ts (1)

12-12: project_id addition looks good

Including project_id on the block interface keeps timeline data project-aware and is consistent with other fields. No issues spotted.

web/helpers/issue.helper.ts (2)

174-182: Project context propagated correctly

project_id is now carried into the Gantt block structure – good consistency!


254-258: Possible undefined leak after new emptiness check

When both displayFilters is an empty object and defaultValues is undefined, filters becomes undefined, yet the subsequent code dereferences it (filters?.calendar…).
While optional-chaining prevents crashes, default fallbacks will all evaluate to undefined, which differs from the previous behaviour that returned explicit defaults.

Consider defaulting to an empty object to preserve previous semantics:

-const filters = !isEmpty(displayFilters) ? displayFilters : defaultValues;
+const filters = !isEmpty(displayFilters) ? displayFilters : (defaultValues ?? {});
web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx (1)

135-148: Excellent refactoring for improved modularity!

The delegation of layout rendering to WorkspaceActiveLayout significantly improves the separation of concerns. This component now focuses solely on data fetching and filter management while letting specialized components handle the rendering logic.

@vamsikrishnamathala vamsikrishnamathala marked this pull request as draft June 16, 2025 07:12
@vamsikrishnamathala vamsikrishnamathala marked this pull request as ready for review June 16, 2025 07:24
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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 701d0f0 and 6f78148.

📒 Files selected for processing (1)
  • apiserver/plane/app/views/issue/base.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.11.9)
apiserver/plane/app/views/issue/base.py

1018-1018: Line too long (104 > 88)

(E501)


1019-1019: Line too long (95 > 88)

(E501)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)

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: 1

🧹 Nitpick comments (1)
packages/utils/src/work-item/base.ts (1)

264-264: Potential undefined fallback when both sources are empty

filters may become undefined if displayFilters is empty and defaultValues is undefined.
Although optional chaining prevents runtime errors, it silently returns defaults like false/null, which may mask configuration mistakes.

-const filters = !isEmpty(displayFilters) ? displayFilters : defaultValues;
+const filters = !isEmpty(displayFilters) ? displayFilters : (defaultValues ?? {});

This guarantees an object and makes the intent explicit.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d048aa and d6300c6.

📒 Files selected for processing (10)
  • packages/types/src/layout/gantt.d.ts (2 hunks)
  • packages/utils/src/work-item/base.ts (2 hunks)
  • web/app/(all)/[workspaceSlug]/(projects)/workspace-views/header.tsx (6 hunks)
  • web/ce/store/timeline/base-timeline.store.ts (2 hunks)
  • web/core/components/gantt-chart/blocks/block.tsx (3 hunks)
  • web/core/components/gantt-chart/blocks/blocks-list.tsx (3 hunks)
  • web/core/components/gantt-chart/chart/main-content.tsx (3 hunks)
  • web/core/components/gantt-chart/chart/root.tsx (3 hunks)
  • web/core/components/gantt-chart/helpers/draggable.tsx (3 hunks)
  • web/core/components/gantt-chart/root.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • web/core/components/gantt-chart/blocks/block.tsx
  • web/core/components/gantt-chart/chart/root.tsx
  • web/core/components/gantt-chart/chart/main-content.tsx
  • web/ce/store/timeline/base-timeline.store.ts
  • web/core/components/gantt-chart/root.tsx
  • web/app/(all)/[workspaceSlug]/(projects)/workspace-views/header.tsx
  • web/core/components/gantt-chart/blocks/blocks-list.tsx
  • web/core/components/gantt-chart/helpers/draggable.tsx
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)
🔇 Additional comments (2)
packages/types/src/layout/gantt.d.ts (1)

12-13: Project-scoped blocks 👍

Adding the optional project_id field to IGanttBlock improves multi-project support and keeps the type backward-compatible.

packages/utils/src/work-item/base.ts (1)

188-189: Propagating project_id – good, but verify downstream usage

getIssueBlocksStructure now returns project_id. Ensure any existing consumers that destructure IGanttBlock (e.g. timeline stores, drag-and-drop helpers) account for the new key and don’t rely on ...rest patterns that exclude it.

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: 0

♻️ Duplicate comments (1)
apiserver/plane/app/views/issue/base.py (1)

950-973: Consider simplifying the complex query structure as suggested in past reviews.

While the role-based filtering logic is now correct (addressing the previous reversed comparison issue), the implementation still adds significant complexity to an already heavy query. The subquery approach, while functional, makes the code harder to maintain and potentially less performant.

As suggested by dheeru0198 in the past review, consider this simpler approach:

# Get project and user's role in a separate, simple query
project = Project.objects.select_related().get(pk=project_id, workspace__slug=slug)
user_project_member = ProjectMember.objects.filter(
    project_id=project_id,
    member=self.request.user,
    is_active=True
).first()

# Apply simple filtering based on role
issue_queryset = Issue.issue_objects.filter(workspace__slug=slug, project_id=project_id)

# If user is guest with restricted access, filter to their own issues
if (user_project_member and 
    user_project_member.role == ROLE.GUEST.value and 
    not project.guest_view_all_features):
    issue_queryset = issue_queryset.filter(created_by=self.request.user)

# Continue with the rest of the query...
issue = issue_queryset.prefetch_related(...)

This approach:

  • Separates access control logic from the main query
  • Is easier to understand and maintain
  • Avoids complex subqueries and OR conditions
  • Performs better by reducing query complexity
🧹 Nitpick comments (1)
apiserver/plane/app/views/issue/base.py (1)

948-949: Fix line length violations flagged by static analysis.

The lines exceed the 88-character limit. Consider breaking the comments into multiple lines.

-        # check for the project member role, if the role is 5 then check for the guest_view_all_features
-        #  if it is true then show all the issues else show only the issues created by the user
+        # check for the project member role, if the role is 5 then check for the 
+        # guest_view_all_features if it is true then show all the issues else 
+        # show only the issues created by the user
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4785c2c and 6f8836b.

📒 Files selected for processing (1)
  • apiserver/plane/app/views/issue/base.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.11.9)
apiserver/plane/app/views/issue/base.py

948-948: Line too long (104 > 88)

(E501)


949-949: Line too long (95 > 88)

(E501)

🔇 Additional comments (1)
apiserver/plane/app/views/issue/base.py (1)

955-958: Verify the role comparison logic is correct.

The current logic uses Q(role__gt=ROLE.GUEST.value) which appears correct for showing all issues to users with roles higher than GUEST (ADMIN/MEMBER). This addresses the previous issue where the comparison was reversed.

The access control logic correctly handles:

  • ADMIN/MEMBER users (role > GUEST): See all issues
  • GUEST users with guest_view_all_features=True: See all issues
  • GUEST users with guest_view_all_features=False: See only their own issues

@sriramveeraghanta sriramveeraghanta merged commit 64fd0b2 into preview Jun 19, 2025
5 of 6 checks passed
@sriramveeraghanta sriramveeraghanta deleted the chore-workspace_views branch June 19, 2025 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants