Skip to content

fix: eslint errors and warnings - #8149

Merged
sriramveeraghanta merged 1 commit into
previewfrom
fix-eslint-errors
Nov 20, 2025
Merged

fix: eslint errors and warnings#8149
sriramveeraghanta merged 1 commit into
previewfrom
fix-eslint-errors

Conversation

@sriramveeraghanta

@sriramveeraghanta sriramveeraghanta commented Nov 20, 2025

Copy link
Copy Markdown
Member

Type of Change

  • Improvement (change that would cause existing functionality to not work as expected)

Summary by CodeRabbit

Release Notes

Chores

  • Code cleanup: Removed unused React imports and type definitions across components, resulting in leaner codebase without affecting functionality or user experience.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings November 20, 2025 13:39
@coderabbitai

coderabbitai Bot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Large-scale refactoring removing unused React FC type imports across 100+ component files. Includes several localized logic restructurings: relocating permission/null guards, extracting dependencies, reorganizing imports, and minimal utility removal. No breaking API changes; components maintain existing exports and behavior.

Changes

Cohort / File(s) Summary
FC Type Import Removal (No Logic Changes)
apps/admin/app/(all)/(dashboard)/authentication/gitea/form.tsx, apps/admin/core/components/common/banner.tsx, apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/{archived-at,assignee,attachment,cycle,default,description,estimate,helpers/issue-link,helpers/issue-user,inbox,label-activity-chip,label,link,module,name,parent,priority,start_date,state}.tsx, apps/web/core/components/issues/issue-detail/issue-activity/activity/activity-list.tsx, apps/web/core/components/issues/issue-detail/issue-activity/{root,sort-root}.tsx, apps/web/core/components/issues/issue-detail/label/{create-label,label-list-item,label-list,root,select/root}.tsx, apps/web/core/components/issues/issue-detail/links/{link-detail,link-item,link-list,links,root}.tsx, apps/web/core/components/issues/issue-detail/parent/{root,sibling-item,siblings}.tsx, apps/web/core/components/pages/list/{block-item-action,block,root,search-input,tab-navigation}.tsx, apps/web/core/components/power-k/ui/modal/shortcuts-root.tsx, apps/web/core/components/profile/{sidebar,user-greetings}.tsx, apps/web/core/components/project-states/{create-update/create,create-update/form,create-update/update,group-item,group-list,options/delete,options/mark-as-default,state-item,state-list}.tsx, apps/web/core/components/project/{create-project-modal,form-loader,form,leave-project-modal,project-feature-update,search-projects,settings/features-list}.tsx, apps/web/core/components/sidebar/{search-button,sidebar-wrapper}.tsx, apps/web/core/components/ui/labels-list.tsx, apps/web/core/components/web-hooks/delete-webhook-modal.tsx, apps/web/core/components/workspace-notifications/sidebar/{empty-state,filters/applied-filter,filters/menu/menu-option-item,filters/menu/root,header/options/menu-option/menu-item,header/options/root,header/root,notification-card/content,notification-card/options/{archive,button,read,root,snooze/modal,snooze/root},root}.tsx, apps/web/core/components/workspace/{billing/comparison/feature-detail,create-workspace-form,settings/invitations-list-item}.tsx
Removed unused import type { FC } from "react" imports; no behavioral changes, only type import cleanup across 80+ files.
Extended Sidebar & Link Detail (Guard Relocation)
apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx, apps/web/core/components/home/widgets/links/link-detail.tsx
Relocated permission/null-check guards from early return to later in component (after hooks setup); guard conditions preserved but timing shifted. Also removed FC import.
Issue Root & Delete Page Modal (Guard Repositioning)
apps/web/core/components/inbox/content/issue-root.tsx, apps/web/core/components/pages/modals/delete-page-modal.tsx
Moved early null-check guards to post-hook initialization, allowing hooks to initialize before returning empty fragment/null when data is missing.
Memoization & Dependency Extraction Refactoring
apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx, apps/web/core/components/issues/issue-layouts/calendar/roots/{cycle-root,module-root}.tsx
Explicit memoization with useMemo and empty dependency array for menu options; extracted addIssueToCycle/addIssuesToModule destructuring from hook return to simplify dependency arrays.
Import Cleanup (React & FC Removal)
apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx, apps/web/core/components/issues/issue-detail/links/link-detail.tsx, apps/web/core/components/profile/{profile-setting-content-header,profile-setting-content-wrapper}.tsx, apps/web/core/components/sidebar/{add-button,sidebar-navigation}.tsx, apps/web/core/components/stickies/sticky/sticky-item-drag-handle.tsx, apps/web/core/components/web-hooks/form/form.tsx
Removed both default React import and FC type import; added comment organization for import sections in some files. JSX runtime requires no explicit React.
Unused Utility/Asset Removal
apps/web/core/components/issues/issue-detail/reactions/{issue-comment,issue}.tsx, apps/web/core/components/profile/overview/activity.tsx, apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx
Removed unused imports (formatTextList, cn, asset imports, DropIndicator); adjusted catch block parameter naming (error_error); removed props (isFirstRow, isLastRow) from StickyDNDWrapper.
Notification & Workspace Notifications Misc
apps/web/core/components/workspace-notifications/root.tsx, apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx
Removed unused useTranslation hook; refactored conditional short-circuit to explicit if-block for issue peek assignment.
Pages List & Type Export
apps/web/core/components/pages/pages-list-main-content.tsx, apps/web/core/components/sidebar/sidebar-item.tsx
Removed filters from PageStore destructuring; exported AppSidebarItemComponent type (changed from private to exported).

Sequence Diagram(s)

sequenceDiagram
    participant Component as Extended Sidebar<br/>(Before & After)
    participant Hooks as React Hooks
    participant Guard as Permission Guard
    
    rect rgb(220, 245, 220)
    note over Component,Guard: Before: Early Guard
    Component->>Guard: Check permission (early)
    Guard-->>Component: Return null if denied
    Component->>Hooks: Initialize hooks (skipped)
    end
    
    rect rgb(245, 230, 220)
    note over Component,Guard: After: Late Guard
    Component->>Hooks: Initialize hooks (always)
    Hooks-->>Component: Setup complete
    Component->>Guard: Check permission (after)
    Guard-->>Component: Return null if denied
    Component->>Component: Render if allowed
    end
Loading
sequenceDiagram
    participant Module as Calendar Module Root
    participant Store as useIssues Store
    participant Extracted as addIssuesToModule Var
    participant Callback as useCallback Deps
    
    rect rgb(220, 245, 220)
    note over Module,Callback: Before: Full Issues Object
    Module->>Store: Call useIssues(EIssuesStoreType.MODULE)
    Store-->>Module: Return issues object
    Module->>Callback: Register dependency on issues?.addIssuesToModule
    end
    
    rect rgb(245, 230, 220)
    note over Module,Callback: After: Extracted Function
    Module->>Store: Call useIssues(EIssuesStoreType.MODULE)
    Store-->>Module: Return issues object
    Module->>Extracted: Destructure addIssuesToModule
    Extracted-->>Module: Extracted function reference
    Module->>Callback: Register dependency on addIssuesToModule only
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Notes:

  • Majority of changes (80+ files) are repetitive FC import removals—homogeneous, low-risk cleanup requiring minimal per-file attention.
  • Files requiring closer review:
    • extended-sidebar-item.tsx, link-detail.tsx (home), issue-root.tsx, delete-page-modal.tsx: Verify guard relocation logic preserves intended null/permission checks and doesn't break hook dependency chains.
    • cycle-root.tsx, module-root.tsx: Confirm extracted dependency updates (addIssueToCycle, addIssuesToModule) maintain correct closure references in callbacks.
    • sticky-dnd-wrapper.tsx: Verify removal of DropIndicator and props (isFirstRow, isLastRow) doesn't break drag-and-drop behavior.
    • sidebar-item.tsx: Confirm exporting AppSidebarItemComponent type doesn't unintentionally expose internal implementation details.

Poem

🐰 A thousand imports, one by one,
We've cleaned the FC that went unused—
The rabbit hops through files in fun,
Now React's less cluttered, less confused!
Twitches nose 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete, providing only a checked 'Improvement' type without the required Description, Screenshots, Test Scenarios, or References sections from the template. Add a detailed description of the changes, test scenarios, and any related references to complete the PR documentation.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: eslint errors and warnings' is directly related to the changeset, which contains extensive removal of unused imports (primarily FC from React) and minor cleanup across numerous component files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-eslint-errors

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

This PR aims to fix ESLint errors and warnings across the codebase, primarily by removing unused imports (specifically unused FC type imports from React), prefixing unused variables with underscores, adding dependency arrays to hooks, and reorganizing code structure. However, several issues have been identified that introduce bugs or contradict the stated purpose.

Key Changes:

  • Removal of 50+ unused FC type imports from React across component files
  • Addition/correction of dependency arrays in useEffect and useCallback hooks
  • Prefixing unused error/variable parameters with underscores to suppress warnings
  • Moving early return checks to different positions in components (which introduced bugs)
  • Increasing the ESLint max-warnings threshold from 821 to 934

Reviewed Changes

Copilot reviewed 137 out of 137 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/propel/.eslintignore Added storybook-static/* to ignore list
apps/web/package.json Increased max-warnings from 821 to 934 (contradicts PR purpose)
apps/web/core/store/project-view.store.ts Prefixed unused error variable with underscore
apps/web/core/store/pages/project-page.store.ts Added eslint-disable comment for unused variable in destructuring
apps/web/core/store/issue/cycle/issue.store.ts Prefixed unused error variable with underscore
apps/web/core/lib/wrappers/store-wrapper.tsx Removed unused FC import
apps/web/core/lib/wrappers/instance-wrapper.tsx Removed unused FC import
apps/web/core/lib/wrappers/authentication-wrapper.tsx Removed unused FC import
apps/web/core/lib/posthog-provider.tsx Removed unused FC import
apps/web/core/lib/intercom-provider.tsx Removed unused FC and React imports
apps/web/core/layouts/default-layout/index.tsx Removed unused FC import
apps/web/core/layouts/auth-layout/workspace-wrapper.tsx Removed unused FC import, reorganized comment sections
apps/web/core/hooks/use-local-storage.tsx Prefixed unused error variables with underscore
apps/web/core/components/workspace/sidebar/*.tsx Removed multiple unused FC imports across sidebar components
apps/web/core/components/workspace/sidebar/quick-actions.tsx Prefixed unused state variable with underscore, removed unused import
apps/web/core/components/workspace/sidebar/projects-list-item.tsx Added dependency arrays to useEffect hooks, moved early return (introduced bug)
apps/web/core/components/workspace/sidebar/project-navigation.tsx Removed unused early return, added optional chaining for project properties
apps/web/core/components/workspace/settings/*.tsx Removed multiple unused FC imports and unused import
apps/web/core/components/workspace-notifications/sidebar/*.tsx Removed multiple unused FC imports across notification components
apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx Replaced logical AND operator with if statement for better readability
apps/web/core/components/web-hooks/*.tsx Removed unused FC imports
apps/web/core/components/pages/modals/delete-page-modal.tsx Moved early return after property destructuring (introduced bug)
apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx Added type annotation to useMemo but left dependency array empty (introduced bug)
apps/web/core/components/pages/list/*.tsx Removed unused FC imports
apps/web/core/components/issues/issue-layouts/calendar/roots/*.tsx Moved early returns after useCallback definitions (introduced bugs)
apps/web/core/components/issues/issue-detail/reactions/*.tsx Prefixed unused error variables, removed unused imports
apps/web/core/components/issues/issue-detail/issue-activity/*.tsx Removed multiple unused FC imports
apps/web/core/components/inbox/content/issue-root.tsx Moved early return after useMemo definition
apps/web/core/components/home/widgets/links/link-detail.tsx Moved early return, extracted linkUrl variable (introduced bugs in callbacks)
apps/web/core/components/stickies/*.tsx Removed unused variables and imports, prefixed unused state variable
apps/web/core/components/sidebar/*.tsx Removed unused FC and React imports
apps/web/core/components/project/*.tsx Removed multiple unused FC imports
apps/web/core/components/profile/*.tsx Removed multiple unused FC and React imports
apps/web/core/components/power-k/ui/modal/shortcuts-root.tsx Removed unused FC import
apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx Moved permission check after hooks (correct)
apps/admin/core/components/common/banner.tsx Removed unused FC import
apps/admin/app/(all)/(dashboard)/authentication/gitea/form.tsx Removed unused FC import

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/web/package.json
"start": "serve -s build/client -l 3000",
"clean": "rm -rf .turbo && rm -rf .next && rm -rf .react-router && rm -rf node_modules && rm -rf dist && rm -rf build",
"check:lint": "eslint . --max-warnings 821",
"check:lint": "eslint . --max-warnings 934",

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

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

The ESLint max-warnings threshold has been increased from 821 to 934 (an increase of 113 warnings). This PR claims to "fix eslint errors and warnings," but increasing the threshold actually allows more warnings rather than fixing them. This goes against the stated purpose of the PR and degrades code quality standards.

Consider either:

  1. Actually fixing the warnings to reduce the count
  2. If warnings are intentionally being introduced, document why and create a plan to address them

Copilot uses AI. Check for mistakes.
}, [linkDetail.url, t]);
}, [linkUrl, t]);

const handleOpenInNewTab = useCallback(() => {

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

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

The handleOpenInNewTab function uses linkUrl without checking if it's defined. If linkUrl is undefined (when linkDetail is null), this will attempt to open a new window with "undefined" as the URL, which will likely result in unwanted behavior. Add a guard: if (!linkUrl) return; at the beginning of the function.

Suggested change
const handleOpenInNewTab = useCallback(() => {
const handleOpenInNewTab = useCallback(() => {
if (!linkUrl) return;

Copilot uses AI. Check for mistakes.
Comment on lines 19 to +27
const addIssuesToView = useCallback(
(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !moduleId) throw new Error();
return issues.addIssuesToModule(workspaceSlug.toString(), projectId.toString(), moduleId.toString(), issueIds);
return addIssuesToModule(workspaceSlug.toString(), projectId.toString(), moduleId.toString(), issueIds);
},
[issues?.addIssuesToModule, workspaceSlug, projectId, moduleId]
[addIssuesToModule, workspaceSlug, projectId, moduleId]
);

if (!moduleId) return null;

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

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

The addIssuesToView callback is defined before checking if moduleId exists (line 27). The callback includes a runtime check that throws an error if moduleId is undefined. If the callback is invoked before moduleId is available, it will throw an error.

Move the early return check for moduleId to the beginning of the component (right after line 13) to prevent creating the callback with invalid dependencies.

Copilot uses AI. Check for mistakes.
Comment on lines 23 to +31
const addIssuesToView = useCallback(
(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
return addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
},
[issues?.addIssueToCycle, workspaceSlug, projectId, cycleId]
[addIssueToCycle, workspaceSlug, projectId, cycleId]
);

if (!cycleId) return null;

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

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

The addIssuesToView callback is defined before checking if cycleId exists (line 31). The callback includes a runtime check that throws an error if cycleId is undefined. If the callback is invoked before cycleId is available, it will throw an error.

Move the early return check for cycleId to the beginning of the component (right after line 14) to prevent creating the callback with invalid dependencies.

Copilot uses AI. Check for mistakes.
// states
const [isDragging, setIsDragging] = useState(false);
const [instruction, setInstruction] = useState<InstructionType | undefined>(undefined);
const [_instruction, setInstruction] = useState<InstructionType | undefined>(undefined);

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

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

The _instruction state variable is set via setInstruction but is never read anywhere in the component. If this state is truly unused, consider removing both the state variable and all calls to setInstruction. If it's intended for future use or debugging, add a comment explaining why it's being kept.

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
apps/web/core/components/sidebar/sidebar-item.tsx (2)

122-122: Missing type annotation on function parameters.

The AppSidebarItem function is missing type annotations for its parameters, which defeats TypeScript's type checking. This is likely one of the ESLint errors the PR aims to fix.

Apply this diff to add the proper type annotation:

-function AppSidebarItem({ variant = "link", item }) {
+function AppSidebarItem({ variant = "link", item }: AppSidebarItemProps) {

115-120: Add type annotation to AppSidebarItem function parameter and reconsider the AppSidebarItemComponent type export.

The AppSidebarItemComponent type (line 115) is exported but not used anywhere in the codebase—neither in this file nor imported elsewhere. Consider whether this export is intentional for the public API or if it can be removed.

More importantly, the AppSidebarItem function parameter on line 122 is missing type annotation: change function AppSidebarItem({ variant = "link", item }) to function AppSidebarItem({ variant = "link", item }: AppSidebarItemProps) to maintain type safety.

apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx (1)

56-64: Add missing await on line 59 for async operation.

The removeCommentReaction function is async (verified in apps/web/core/store/issue/issue-details/root.store.ts:407), but line 59 calls it without await. This is inconsistent with line 42, which correctly awaits createCommentReaction, and with the parallel file issue.tsx line 64 which awaits the equivalent operation. Missing await on an async function can cause unhandled promise rejection and incorrect error handling flow.

Add await before removeCommentReaction on line 59.

apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx (1)

48-113: Fix stale closure in EXTRA_MENU_OPTIONS useMemo by adding required dependencies

The useMemo with empty dependency array [] captures stale values. When isFullWidth or isStickyToolbarEnabled change (e.g., user toggles the switch), the memoized array is not recomputed, so:

  • Toggle switches display stale state
  • Toggle actions operate on initial values instead of current state

The hooks you're consuming (isFullWidth, handleFullWidth, isStickyToolbarEnabled, handleStickyToolbar from usePageFilters(), and others) can change during render cycles. Add these to the dependency array or remove useMemo entirely.

Required dependencies:

[isFullWidth, handleFullWidth, isStickyToolbarEnabled, handleStickyToolbar, isContentEditable, editorRef, updateQueryParams, router]

Alternatively, remove useMemo and build the array inline on each render to avoid the complexity of managing hook dependencies.

♻️ Duplicate comments (1)
apps/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx (1)

16-29: Same MobX binding concern for addIssueToCycle as in module calendar layout.

Destructuring addIssueToCycle from the MobX store and calling it as a bare function can drop its this context unless the store methods are auto‑bound. The previous pattern (issues.addIssueToCycle(...)) would have preserved this.

Please either confirm that the cycle issues store uses auto‑binding (or arrow‑function actions) or keep the call on the store instance, analogous to the module layout suggestion:

-  const {
-    issues: { addIssueToCycle },
-  } = useIssues(EIssuesStoreType.CYCLE);
+  const { issues } = useIssues(EIssuesStoreType.CYCLE);

   const addIssuesToView = useCallback(
     (issueIds: string[]) => {
       if (!workspaceSlug || !projectId || !cycleId) throw new Error();
-      return addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
+      return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
     },
-    [addIssueToCycle, workspaceSlug, projectId, cycleId]
+    [issues, workspaceSlug, projectId, cycleId]
   );

You can reuse the same rg script from the module layout comment to verify how addIssueToCycle is defined/bound.

🧹 Nitpick comments (8)
apps/web/core/components/pages/pages-list-main-content.tsx (1)

92-159: Consider consolidating the duplicated empty state blocks.

Lines 94-111, 114-131, and 133-150 contain nearly identical EmptyStateDetailed components. The only differences are the conditional checks for pageType. This duplication could be simplified:

  if (!isAnyPageAvailable || pageIds?.length === 0) {
-   if (!isAnyPageAvailable) {
-     return (
-       <EmptyStateDetailed
-         assetKey="page"
-         title={t("project_empty_state.pages.title")}
-         description={t("project_empty_state.pages.description")}
-         actions={[
-           {
-             label: t("project_empty_state.pages.cta_primary"),
-             onClick: () => {
-               handleCreatePage();
-               captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON });
-             },
-             variant: "primary",
-             disabled: !canPerformEmptyStateActions || isCreatingPage,
-           },
-         ]}
-       />
-     );
-   }
-   if (pageType === "public")
-     return (
-       <EmptyStateDetailed
-         assetKey="page"
-         title={t("project_empty_state.pages.title")}
-         description={t("project_empty_state.pages.description")}
-         actions={[
-           {
-             label: t("project_empty_state.pages.cta_primary"),
-             onClick: () => {
-               handleCreatePage();
-               captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON });
-             },
-             variant: "primary",
-             disabled: !canPerformEmptyStateActions || isCreatingPage,
-           },
-         ]}
-       />
-     );
-   if (pageType === "private")
-     return (
-       <EmptyStateDetailed
-         assetKey="page"
-         title={t("project_empty_state.pages.title")}
-         description={t("project_empty_state.pages.description")}
-         actions={[
-           {
-             label: t("project_empty_state.pages.cta_primary"),
-             onClick: () => {
-               handleCreatePage();
-               captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON });
-             },
-             variant: "primary",
-             disabled: !canPerformEmptyStateActions || isCreatingPage,
-           },
-         ]}
-       />
-     );
    if (pageType === "archived")
      return (
        <EmptyStateDetailed
          assetKey="page"
          title={t("project_empty_state.archive_pages.title")}
          description={t("project_empty_state.archive_pages.description")}
        />
      );
+   // For non-archived pages, show create action
+   return (
+     <EmptyStateDetailed
+       assetKey="page"
+       title={t("project_empty_state.pages.title")}
+       description={t("project_empty_state.pages.description")}
+       actions={[
+         {
+           label: t("project_empty_state.pages.cta_primary"),
+           onClick: () => {
+             handleCreatePage();
+             captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON });
+           },
+           variant: "primary",
+           disabled: !canPerformEmptyStateActions || isCreatingPage,
+         },
+       ]}
+     />
+   );
  }
apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx (3)

27-28: Remove unused props from type definition.

The isInFirstRow and isInLastRow props are declared in the Props type but are no longer destructured or used in the component (see line 34). These should be removed from the type definition to maintain consistency.

Apply this diff to remove the unused props:

 type Props = {
   stickyId: string;
   workspaceSlug: string;
   itemWidth: string;
   isLastChild: boolean;
-  isInFirstRow: boolean;
-  isInLastRow: boolean;
   handleDrop: (self: DropTargetRecord, source: ElementDragPayload, location: DragLocationHistory) => void;
   handleLayout: () => void;
 };

37-37: Consider removing unused state.

The _instruction state variable (underscore prefix indicates it's unused) is set at lines 104, 107, and 110 but is never read. If this state is no longer needed, consider removing both the state declaration and the corresponding setInstruction calls to eliminate dead code.

If this state is truly unused, apply this diff:

-  const [_instruction, setInstruction] = useState<InstructionType | undefined>(undefined);

And remove the setInstruction calls at lines 104, 107, and 110:

           onDrag: ({ self, source, location }) => {
-            const instruction = getInstructionFromPayload(self, source, location);
-            setInstruction(instruction);
           },
           onDragLeave: () => {
-            setInstruction(undefined);
           },
           onDrop: ({ self, source, location }) => {
-            setInstruction(undefined);
             handleDrop(self, source, location);
           },

124-124: Remove commented-out code.

Lines 124 and 131 contain commented-out DropIndicator components. Commented-out code should be removed to improve readability—version control will preserve the history if this functionality needs to be restored later.

Apply this diff to remove the commented code:

     <div
       className="flex flex-col box-border p-[8px]"
       style={{
         width: itemWidth,
       }}
     >
-      {/* {!isInFirstRow && <DropIndicator isVisible={instruction === "reorder-above"} />} */}
       <StickyNote
         key={stickyId || "new"}
         workspaceSlug={workspaceSlug}
         stickyId={stickyId}
         handleLayout={handleLayout}
       />
-      {/* {!isInLastRow && <DropIndicator isVisible={instruction === "reorder-below"} />} */}
     </div>

Also applies to: 131-131

apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx (1)

149-151: Move permission guard earlier to avoid wasteful computations.

The permission check should occur immediately after obtaining allowPermissions (line 56) rather than after computing derived values (lines 59-78). Currently, sidebar preferences, hrefs, and icon lookups execute even when the component returns null.

Apply this diff to optimize the guard placement:

   const { data } = useUser();
   const { allowPermissions } = useUserPermissions();
 
+  if (!allowPermissions(item.access as any, EUserPermissionsLevel.WORKSPACE, workspaceSlug.toString())) {
+    return null;
+  }
+
   // derived values
   const sidebarPreference = getNavigationPreferences(workspaceSlug.toString());
   const isPinned = sidebarPreference?.[item.key]?.is_pinned;

And remove the duplicate guard before the return:

     );
   }, [isLastChild, handleOnNavigationItemDrop, disableDrag, disableDrop, item.key]);
 
-  if (!allowPermissions(item.access as any, EUserPermissionsLevel.WORKSPACE, workspaceSlug.toString())) {
-    return null;
-  }
-
   return (
apps/web/core/components/inbox/content/issue-root.tsx (1)

165-166: Guard placement correctly ensures React Rules of Hooks compliance.

Relocating the !issue guard to after all hooks ensures they are called unconditionally on every render, which is required by React's Rules of Hooks. This is the correct approach.

Optional: Consider guard redundancy.

Line 165's check is technically redundant with line 167, since !issue?.project_id evaluates to true when issue is undefined. However, the explicit guard improves readability by clearly stating the intent.

apps/web/core/components/home/widgets/links/link-detail.tsx (1)

43-56: Consider consistent guard approach across callbacks.

handleCopyText includes a defensive guard if (!linkUrl) while handleOpenInNewTab directly uses linkUrl without checking. Since the component-level guard at line 93 ensures linkDetail is defined before rendering, both patterns are safe, but consistency would improve maintainability.

Either add a guard to handleOpenInNewTab for consistency:

 const handleOpenInNewTab = useCallback(() => {
+  if (!linkUrl) return;
   window.open(linkUrl, "_blank", "noopener,noreferrer");
 }, [linkUrl]);

Or remove the guard from handleCopyText if the component-level guard is deemed sufficient.

apps/web/core/components/pages/modals/delete-page-modal.tsx (1)

45-47: Early-return on missing pageId is a good defensive addition

The if (!pageId) return; guard in handleDelete prevents calling removePage with an invalid id, which is a nice hardening step. You might optionally wrap the body in try/finally to guarantee setIsDeleting(false) even if any of the callbacks throw, but that’s not strictly required for this ESLint-focused PR.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83fdebf and 250b590.

📒 Files selected for processing (107)
  • apps/admin/app/(all)/(dashboard)/authentication/gitea/form.tsx (0 hunks)
  • apps/admin/core/components/common/banner.tsx (0 hunks)
  • apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx (1 hunks)
  • apps/web/core/components/home/widgets/links/link-detail.tsx (3 hunks)
  • apps/web/core/components/inbox/content/issue-root.tsx (1 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx (1 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/archived-at.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/attachment.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/cycle.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/default.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/description.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx (1 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-user.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/inbox.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/label-activity-chip.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/label.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/link.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/module.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/name.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/parent.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/priority.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/relation.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/start_date.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/state.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/activity-list.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/label/create-label.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/label/label-list-item.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/label/label-list.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/label/root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/label/select/root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/links/link-detail.tsx (1 hunks)
  • apps/web/core/components/issues/issue-detail/links/link-item.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/links/link-list.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/links/links.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/links/root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/parent/root.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/parent/sibling-item.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/parent/siblings.tsx (0 hunks)
  • apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx (2 hunks)
  • apps/web/core/components/issues/issue-detail/reactions/issue.tsx (2 hunks)
  • apps/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx (0 hunks)
  • apps/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx (1 hunks)
  • apps/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx (1 hunks)
  • apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx (4 hunks)
  • apps/web/core/components/pages/list/block-item-action.tsx (0 hunks)
  • apps/web/core/components/pages/list/block.tsx (0 hunks)
  • apps/web/core/components/pages/list/root.tsx (0 hunks)
  • apps/web/core/components/pages/list/search-input.tsx (0 hunks)
  • apps/web/core/components/pages/list/tab-navigation.tsx (0 hunks)
  • apps/web/core/components/pages/modals/delete-page-modal.tsx (4 hunks)
  • apps/web/core/components/pages/pages-list-main-content.tsx (1 hunks)
  • apps/web/core/components/power-k/ui/modal/shortcuts-root.tsx (0 hunks)
  • apps/web/core/components/profile/overview/activity.tsx (0 hunks)
  • apps/web/core/components/profile/profile-setting-content-header.tsx (0 hunks)
  • apps/web/core/components/profile/profile-setting-content-wrapper.tsx (1 hunks)
  • apps/web/core/components/profile/sidebar.tsx (0 hunks)
  • apps/web/core/components/project-states/create-update/create.tsx (0 hunks)
  • apps/web/core/components/project-states/create-update/form.tsx (0 hunks)
  • apps/web/core/components/project-states/create-update/update.tsx (0 hunks)
  • apps/web/core/components/project-states/group-item.tsx (0 hunks)
  • apps/web/core/components/project-states/group-list.tsx (0 hunks)
  • apps/web/core/components/project-states/options/delete.tsx (0 hunks)
  • apps/web/core/components/project-states/options/mark-as-default.tsx (0 hunks)
  • apps/web/core/components/project-states/state-item.tsx (0 hunks)
  • apps/web/core/components/project-states/state-list.tsx (0 hunks)
  • apps/web/core/components/project/create-project-modal.tsx (0 hunks)
  • apps/web/core/components/project/form-loader.tsx (0 hunks)
  • apps/web/core/components/project/form.tsx (0 hunks)
  • apps/web/core/components/project/leave-project-modal.tsx (0 hunks)
  • apps/web/core/components/project/project-feature-update.tsx (0 hunks)
  • apps/web/core/components/project/search-projects.tsx (0 hunks)
  • apps/web/core/components/project/settings/features-list.tsx (0 hunks)
  • apps/web/core/components/sidebar/add-button.tsx (0 hunks)
  • apps/web/core/components/sidebar/search-button.tsx (0 hunks)
  • apps/web/core/components/sidebar/sidebar-item.tsx (1 hunks)
  • apps/web/core/components/sidebar/sidebar-navigation.tsx (1 hunks)
  • apps/web/core/components/sidebar/sidebar-wrapper.tsx (0 hunks)
  • apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx (1 hunks)
  • apps/web/core/components/stickies/sticky/sticky-item-drag-handle.tsx (0 hunks)
  • apps/web/core/components/ui/labels-list.tsx (0 hunks)
  • apps/web/core/components/user/user-greetings.tsx (0 hunks)
  • apps/web/core/components/web-hooks/delete-webhook-modal.tsx (1 hunks)
  • apps/web/core/components/web-hooks/form/form.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/root.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/empty-state.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/filters/applied-filter.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/header/root.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/content.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx (1 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx (1 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/read.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx (1 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx (0 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/root.tsx (1 hunks)
  • apps/web/core/components/workspace-notifications/sidebar/root.tsx (1 hunks)
  • apps/web/core/components/workspace/billing/comparison/feature-detail.tsx (0 hunks)
  • apps/web/core/components/workspace/create-workspace-form.tsx (1 hunks)
  • apps/web/core/components/workspace/settings/invitations-list-item.tsx (0 hunks)
⛔ Files not processed due to max files limit (30)
  • apps/web/core/components/workspace/settings/member-columns.tsx
  • apps/web/core/components/workspace/settings/members-list-item.tsx
  • apps/web/core/components/workspace/settings/members-list.tsx
  • apps/web/core/components/workspace/settings/workspace-details.tsx
  • apps/web/core/components/workspace/sidebar/favorites/favorite-items/common/favorite-item-drag-handle.tsx
  • apps/web/core/components/workspace/sidebar/favorites/favorite-items/common/favorite-item-quick-action.tsx
  • apps/web/core/components/workspace/sidebar/favorites/favorite-items/common/favorite-item-title.tsx
  • apps/web/core/components/workspace/sidebar/favorites/favorite-items/common/favorite-item-wrapper.tsx
  • apps/web/core/components/workspace/sidebar/favorites/favorite-items/root.tsx
  • apps/web/core/components/workspace/sidebar/project-navigation.tsx
  • apps/web/core/components/workspace/sidebar/projects-list-item.tsx
  • apps/web/core/components/workspace/sidebar/projects-list.tsx
  • apps/web/core/components/workspace/sidebar/quick-actions.tsx
  • apps/web/core/components/workspace/sidebar/sidebar-item.tsx
  • apps/web/core/components/workspace/sidebar/user-menu-item.tsx
  • apps/web/core/components/workspace/sidebar/workspace-menu-header.tsx
  • apps/web/core/components/workspace/sidebar/workspace-menu-item.tsx
  • apps/web/core/hooks/use-local-storage.tsx
  • apps/web/core/layouts/auth-layout/workspace-wrapper.tsx
  • apps/web/core/layouts/default-layout/index.tsx
  • apps/web/core/lib/intercom-provider.tsx
  • apps/web/core/lib/posthog-provider.tsx
  • apps/web/core/lib/wrappers/authentication-wrapper.tsx
  • apps/web/core/lib/wrappers/instance-wrapper.tsx
  • apps/web/core/lib/wrappers/store-wrapper.tsx
  • apps/web/core/store/issue/cycle/issue.store.ts
  • apps/web/core/store/pages/project-page.store.ts
  • apps/web/core/store/project-view.store.ts
  • apps/web/package.json
  • packages/propel/.eslintignore
💤 Files with no reviewable changes (83)
  • apps/web/core/components/issues/issue-detail/links/root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/name.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/relation.tsx
  • apps/web/core/components/project-states/state-item.tsx
  • apps/web/core/components/power-k/ui/modal/shortcuts-root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/attachment.tsx
  • apps/web/core/components/issues/issue-detail/label/label-list.tsx
  • apps/web/core/components/sidebar/sidebar-wrapper.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/parent.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/state.tsx
  • apps/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/cycle.tsx
  • apps/web/core/components/project-states/create-update/create.tsx
  • apps/web/core/components/user/user-greetings.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/label-activity-chip.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-user.tsx
  • apps/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx
  • apps/web/core/components/pages/list/root.tsx
  • apps/web/core/components/project/leave-project-modal.tsx
  • apps/web/core/components/workspace-notifications/root.tsx
  • apps/web/core/components/project/form-loader.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx
  • apps/web/core/components/project/form.tsx
  • apps/admin/app/(all)/(dashboard)/authentication/gitea/form.tsx
  • apps/web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx
  • apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/start_date.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/archived-at.tsx
  • apps/web/core/components/project/create-project-modal.tsx
  • apps/web/core/components/stickies/sticky/sticky-item-drag-handle.tsx
  • apps/web/core/components/project-states/options/mark-as-default.tsx
  • apps/web/core/components/project-states/state-list.tsx
  • apps/web/core/components/issues/issue-detail/label/root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/default.tsx
  • apps/web/core/components/pages/list/search-input.tsx
  • apps/web/core/components/profile/overview/activity.tsx
  • apps/web/core/components/web-hooks/form/form.tsx
  • apps/web/core/components/pages/list/block-item-action.tsx
  • apps/web/core/components/project/search-projects.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/module.tsx
  • apps/web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx
  • apps/web/core/components/ui/labels-list.tsx
  • apps/web/core/components/workspace-notifications/sidebar/filters/applied-filter.tsx
  • apps/web/core/components/profile/profile-setting-content-header.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/description.tsx
  • apps/web/core/components/project-states/options/delete.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/content.tsx
  • apps/web/core/components/workspace-notifications/sidebar/empty-state.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/priority.tsx
  • apps/web/core/components/profile/sidebar.tsx
  • apps/web/core/components/workspace/billing/comparison/feature-detail.tsx
  • apps/web/core/components/pages/list/block.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/link.tsx
  • apps/web/core/components/sidebar/search-button.tsx
  • apps/web/core/components/workspace/settings/invitations-list-item.tsx
  • apps/web/core/components/issues/issue-detail/parent/siblings.tsx
  • apps/web/core/components/project-states/create-update/form.tsx
  • apps/admin/core/components/common/banner.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/activity-list.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/label.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/read.tsx
  • apps/web/core/components/project-states/create-update/update.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx
  • apps/web/core/components/issues/issue-detail/links/link-item.tsx
  • apps/web/core/components/issues/issue-detail/parent/sibling-item.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/inbox.tsx
  • apps/web/core/components/issues/issue-detail/parent/root.tsx
  • apps/web/core/components/workspace-notifications/sidebar/header/root.tsx
  • apps/web/core/components/project-states/group-item.tsx
  • apps/web/core/components/project-states/group-list.tsx
  • apps/web/core/components/issues/issue-detail/links/link-list.tsx
  • apps/web/core/components/issues/issue-detail/label/create-label.tsx
  • apps/web/core/components/issues/issue-detail/label/select/root.tsx
  • apps/web/core/components/project/project-feature-update.tsx
  • apps/web/core/components/issues/issue-detail/links/links.tsx
  • apps/web/core/components/issues/issue-detail/label/label-list-item.tsx
  • apps/web/core/components/sidebar/add-button.tsx
  • apps/web/core/components/project/settings/features-list.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/root.tsx
  • apps/web/core/components/pages/list/tab-navigation.tsx
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T20:42:31.843Z
Learning: In the makeplane/plane repository, React types are globally available through TypeScript configuration. Type annotations like React.FC, React.ReactNode, etc. can be used without explicitly importing the React namespace. The codebase uses the modern JSX transform, so React imports are not required for JSX or type references.
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T22:12:26.424Z
Learning: When `types/react` is installed in a TypeScript project (which is standard for React + TypeScript codebases), React types (React.FC, React.ReactNode, React.ComponentProps, etc.) are globally available by design. These type annotations can and should be used without explicitly importing the React namespace. This is a TypeScript/DefinitelyTyped feature, not codebase-specific configuration.
📚 Learning: 2025-10-09T20:42:31.843Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T20:42:31.843Z
Learning: In the makeplane/plane repository, React types are globally available through TypeScript configuration. Type annotations like React.FC, React.ReactNode, etc. can be used without explicitly importing the React namespace. The codebase uses the modern JSX transform, so React imports are not required for JSX or type references.

Applied to files:

  • apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx
  • apps/web/core/components/workspace/create-workspace-form.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx
  • apps/web/core/components/workspace-notifications/sidebar/root.tsx
  • apps/web/core/components/profile/profile-setting-content-wrapper.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx
  • apps/web/core/components/issues/issue-detail/links/link-detail.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/root.tsx
  • apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx
  • apps/web/core/components/web-hooks/delete-webhook-modal.tsx
  • apps/web/core/components/issues/issue-detail/reactions/issue.tsx
  • apps/web/core/components/sidebar/sidebar-navigation.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx
  • apps/web/core/components/home/widgets/links/link-detail.tsx
  • apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx
  • apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx
📚 Learning: 2025-10-09T22:12:26.424Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T22:12:26.424Z
Learning: When `types/react` is installed in a TypeScript project (which is standard for React + TypeScript codebases), React types (React.FC, React.ReactNode, React.ComponentProps, etc.) are globally available by design. These type annotations can and should be used without explicitly importing the React namespace. This is a TypeScript/DefinitelyTyped feature, not codebase-specific configuration.

Applied to files:

  • apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx
  • apps/web/core/components/workspace/create-workspace-form.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx
  • apps/web/core/components/workspace-notifications/sidebar/root.tsx
  • apps/web/core/components/profile/profile-setting-content-wrapper.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/root.tsx
  • apps/web/core/components/web-hooks/delete-webhook-modal.tsx
  • apps/web/core/components/issues/issue-detail/reactions/issue.tsx
  • apps/web/core/components/sidebar/sidebar-navigation.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx
  • apps/web/core/components/home/widgets/links/link-detail.tsx
  • apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx
  • apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx
📚 Learning: 2025-09-02T08:14:49.260Z
Learnt from: sriramveeraghanta
Repo: makeplane/plane PR: 7697
File: apps/web/app/(all)/[workspaceSlug]/(projects)/header.tsx:12-13
Timestamp: 2025-09-02T08:14:49.260Z
Learning: The star-us-link.tsx file in apps/web/app/(all)/[workspaceSlug]/(projects)/ already has "use client" directive at the top, making it a proper Client Component for hook usage.

Applied to files:

  • apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx
  • apps/web/core/components/workspace-notifications/sidebar/root.tsx
  • apps/web/core/components/profile/profile-setting-content-wrapper.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx
  • apps/web/core/components/issues/issue-detail/links/link-detail.tsx
  • apps/web/core/components/web-hooks/delete-webhook-modal.tsx
  • apps/web/core/components/issues/issue-detail/reactions/issue.tsx
  • apps/web/core/components/sidebar/sidebar-navigation.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx
  • apps/web/core/components/home/widgets/links/link-detail.tsx
  • apps/web/core/components/pages/modals/delete-page-modal.tsx
📚 Learning: 2025-10-21T17:22:05.204Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7989
File: apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx:45-46
Timestamp: 2025-10-21T17:22:05.204Z
Learning: In the makeplane/plane repository, the refactor from useParams() to params prop is specifically scoped to page.tsx and layout.tsx files in apps/web/app (Next.js App Router pattern). Other components (hooks, regular client components, utilities) should continue using the useParams() hook as that is the correct pattern for non-route components.

Applied to files:

  • apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx
  • apps/web/core/components/pages/pages-list-main-content.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx
  • apps/web/core/components/workspace-notifications/sidebar/root.tsx
  • apps/web/core/components/profile/profile-setting-content-wrapper.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx
  • apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx
  • apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx
  • apps/web/core/components/web-hooks/delete-webhook-modal.tsx
  • apps/web/core/components/sidebar/sidebar-navigation.tsx
  • apps/web/core/components/pages/modals/delete-page-modal.tsx
  • apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx
📚 Learning: 2025-10-01T15:30:17.605Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7888
File: packages/propel/src/avatar/avatar.stories.tsx:2-3
Timestamp: 2025-10-01T15:30:17.605Z
Learning: In the makeplane/plane repository, avoid suggesting inline type imports (e.g., `import { Avatar, type TAvatarSize }`) due to bundler compatibility issues. Keep type imports and value imports as separate statements.

Applied to files:

  • apps/web/core/components/workspace-notifications/sidebar/root.tsx
  • apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx
  • apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx
📚 Learning: 2025-06-16T07:23:39.497Z
Learnt from: vamsikrishnamathala
Repo: makeplane/plane PR: 7214
File: web/core/store/issue/helpers/base-issues.store.ts:117-117
Timestamp: 2025-06-16T07:23:39.497Z
Learning: In the updateIssueDates method of BaseIssuesStore (web/core/store/issue/helpers/base-issues.store.ts), the projectId parameter is intentionally made optional to support override implementations in subclasses. The base implementation requires projectId and includes an early return check, but making it optional allows derived classes to override the method with different parameter requirements.

Applied to files:

  • apps/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx
🧬 Code graph analysis (6)
apps/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx (2)
apps/web/core/hooks/store/use-issues.ts (1)
  • useIssues (82-157)
apps/web/core/store/issue/helpers/base-issues.store.ts (2)
  • moduleId (264-266)
  • addIssuesToModule (965-994)
apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx (2)
packages/ui/src/dropdowns/context-menu/root.tsx (1)
  • TContextMenuItem (10-23)
apps/web/core/components/pages/dropdowns/actions.tsx (1)
  • TPageActions (41-54)
apps/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx (2)
apps/web/core/hooks/store/use-issues.ts (1)
  • useIssues (82-157)
apps/web/core/store/cycle.store.ts (1)
  • currentProjectCompletedCycleIds (171-185)
apps/web/core/components/home/widgets/links/link-detail.tsx (2)
packages/propel/src/toast/toast.tsx (1)
  • setToast (202-222)
packages/i18n/src/store/index.ts (1)
  • t (223-244)
apps/web/ce/components/workspace/sidebar/extended-sidebar-item.tsx (1)
apps/space/core/store/publish/publish.store.ts (1)
  • workspaceSlug (93-95)
apps/web/core/components/stickies/layout/sticky-dnd-wrapper.tsx (1)
packages/types/src/pragmatic.ts (1)
  • InstructionType (29-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL analysis (javascript-typescript)
  • GitHub Check: Agent
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (23)
apps/web/core/components/workspace-notifications/sidebar/root.tsx (1)

3-3: Correct removal of unused FC import.

The FC type is not used anywhere in this component. Since the component is defined as a named function without explicit React.FC type annotation and React types are globally available in the codebase (per TS configuration), this removal is appropriate.

apps/web/core/components/workspace/create-workspace-form.tsx (1)

3-3: Correct removal of unused FC import.

The component is already using an explicit function pattern with typed props (props: Props) rather than the React.FC<Props> typing at line 43, so removing the unused FC import is appropriate. React types like React.ReactNode (used at line 34) remain globally available through the TypeScript configuration. Based on learnings

apps/web/core/components/workspace-notifications/sidebar/notification-card/options/root.tsx (1)

3-3: Clean removal of unused import.

The FC type import has been successfully removed. The component functions correctly without it—it uses a standard function pattern with explicit prop typing (TNotificationOption) rather than relying on React.FC. Per the codebase's TypeScript configuration, React types are globally available, making this import unnecessary. The remaining imports (Dispatch, SetStateAction) are properly utilized in the type definition.

apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx (1)

3-3: Import grouping comment looks good

The // plane imports comment cleanly documents the local import group and has no runtime impact. It also aligns with the project’s existing import-structure style.

apps/web/core/components/sidebar/sidebar-navigation.tsx (1)

2-2: LGTM! Unused imports correctly removed.

The removal of unused React and FC imports is correct. The React.ReactNode type annotation on line 8 remains functional because React types are globally available via @types/react. The modern JSX transform eliminates the need for a React import.

Based on learnings

apps/web/core/components/profile/profile-setting-content-wrapper.tsx (1)

2-2: LGTM! Unused import removal is correct.

The removal of the React import and FC type is appropriate. The component uses the automatic JSX runtime and doesn't require React to be in scope. The React.ReactNode type on line 7 continues to work correctly because React types are globally available in this codebase through TypeScript configuration.

Based on learnings

apps/web/core/components/web-hooks/delete-webhook-modal.tsx (1)

3-3: LGTM! Clean removal of unused imports.

The change correctly removes unused React and FC imports while retaining only useState, which is actually used at line 22. This aligns with ESLint best practices and the modern JSX transform that doesn't require React to be in scope for JSX.

Based on learnings

apps/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx (1)

57-59: LGTM! Improved readability by replacing short-circuit with explicit conditional.

Refactoring from short-circuit evaluation (&&) to an explicit if-block makes the side effect more obvious and addresses ESLint warnings. The logic is functionally equivalent and more maintainable.

apps/web/core/components/pages/pages-list-main-content.tsx (1)

37-38: LGTM! Unused variable removed.

The removal of filters from the destructuring is correct—it's not referenced anywhere in the component. This properly addresses the ESLint unused variable warning.

apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/root.tsx (1)

3-3: Import cleanup correctly matches actual type usage

Removing the unused FC type and keeping only Dispatch/SetStateAction aligns the import with how props are typed later in the file, and should clear the eslint unused-import warning without changing behavior.

apps/web/core/components/workspace-notifications/sidebar/notification-card/options/button.tsx (1)

3-3: React type import is now minimal and appropriate

Keeping only ReactNode for the children prop while dropping unused FC is a precise fix for eslint’s unused-import warning and keeps the component’s typing intact.

apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/issue-link.tsx (1)

5-5: LGTM! Comment reorganization and type import cleanup are correct.

The comment relocation and removal of the unused FC type import align with the project's TypeScript configuration. Based on learnings, React types are globally available in this codebase, so explicit imports are unnecessary.

apps/web/core/components/issues/issue-detail/links/link-detail.tsx (1)

7-12: LGTM! Import organization improved.

The addition of comment headers (// hooks and // types) improves code readability by clearly grouping related imports.

apps/web/core/components/home/widgets/links/link-detail.tsx (2)

32-32: LGTM! Extracting linkUrl improves clarity.

Extracting the URL into a dedicated variable with optional chaining simplifies the subsequent callback implementations and dependency arrays.


93-94: LGTM! Guard relocation fixes Rules of Hooks violation.

Moving the null-return guard after all hooks and memoized values is correct and necessary. React requires hooks to be called unconditionally and in the same order on every render. The guard still prevents rendering when linkDetail is null, and since the component returns early, the constructed callbacks will never be invoked in that case.

apps/web/core/components/issues/issue-detail/reactions/issue.tsx (2)

12-12: LGTM! Good cleanup of unused imports.

The removal of unused FC and formatTextList imports addresses eslint warnings while correctly retaining cn which is used on line 127. Based on learnings, React types are globally available in this codebase, so explicit FC imports are unnecessary.


70-70: LGTM! Follows eslint convention for unused variables.

Renaming the catch parameter to _error properly indicates it's intentionally unused, addressing the eslint no-unused-vars rule.

apps/web/core/components/issues/issue-detail/reactions/issue-comment.tsx (1)

48-48: LGTM! Consistent eslint convention for unused variables.

Both catch parameter renames to _error properly indicate they're intentionally unused, addressing the eslint no-unused-vars rule consistently across the component.

Also applies to: 65-65

apps/web/core/components/pages/modals/delete-page-modal.tsx (1)

3-3: React default import removal is correct

Dropping the unused React default and importing only useState matches the modern JSX transform and the repo’s convention of relying on globally available React types; no issues here.
Based on learnings

apps/web/core/components/pages/editor/toolbar/options-dropdown.tsx (1)

9-23: Type-only imports and stricter key typing look good

Using import type for TContextMenuItem and TPageActions is appropriate, and the (TContextMenuItem & { key: TPageActions })[] annotation nicely constrains key to the known page actions while remaining compatible with TContextMenuItem’s key: string. No issues here.

apps/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx (2)

27-28: Guard placement after hooks looks good.

Keeping if (!moduleId) return null; after all hooks (including useIssues and useCallback) satisfies React’s rules‑of‑hooks while still preventing the calendar from rendering when there is no moduleId. No issues here.


15-25: Review comment is incorrect; no changes needed.

The method addIssuesToModule is explicitly marked with action.bound in the store's makeAutoObservable configuration (apps/web/core/store/issue/helpers/base-issues.store.ts:241). This auto-binding means destructuring and calling the method directly is safe—the this context is preserved. The concern about losing context when destructuring does not apply here.

Likely an incorrect or invalid review comment.

apps/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx (1)

31-32: Cycle ID guard after hooks is correct.

if (!cycleId) return null; now runs after all hooks while still short‑circuiting rendering when there is no cycleId, which is compliant with rules‑of‑hooks and matches the intended behavior.

Comment on lines 35 to 36
const { id: pageId, name } = page;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against falsy page before destructuring to avoid potential runtime errors

You’re checking if (!page || !page.id) return null; after already doing const { id: pageId, name } = page;. If page can ever be null/undefined at runtime, the destructuring would throw before the guard runs.

To keep hooks order correct and make the guard actually protective, consider moving it above the destructuring but below all hooks, e.g.:

-  // derived values
-  const { id: pageId, name } = page;
+  const router = useAppRouter();
+  const { pageId: routePageId } = useParams();
+
+  if (!page || !page.id) return null;
+
+  // derived values
+  const { id: pageId, name } = page;
-
-  const router = useAppRouter();
-  const { pageId: routePageId } = useParams();

(or any equivalent ordering where all hooks run first, then the falsy-page guard, then the destructuring).

Also applies to: 84-85

🤖 Prompt for AI Agents
In apps/web/core/components/pages/modals/delete-page-modal.tsx around lines
35-36 (and similarly at 84-85), the code destructures const { id: pageId, name }
= page before checking if page is falsy; move the falsy-page guard (if (!page ||
!page.id) return null;) to appear before any destructuring of page but after all
React hooks have run so hooks order is preserved; update both occurrences so
destructuring only happens when page is guaranteed non-null.

@sriramveeraghanta
sriramveeraghanta merged commit 8307bad into preview Nov 20, 2025
11 of 13 checks passed
@sriramveeraghanta
sriramveeraghanta deleted the fix-eslint-errors branch November 20, 2025 14:01
ClarenceChen0627 pushed a commit to ClarenceChen0627/plane that referenced this pull request Dec 5, 2025
ClarenceChen0627 pushed a commit to ClarenceChen0627/plane that referenced this pull request Dec 5, 2025
ClarenceChen0627 pushed a commit to ClarenceChen0627/plane that referenced this pull request Dec 5, 2025
@sriramveeraghanta
sriramveeraghanta removed the request for review from Copilot March 23, 2026 18:38
DoctorFogarty pushed a commit to DoctorFogarty/plane that referenced this pull request Aug 7, 2026
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