Skip to content

[WEB-3788] improvement: enhance project properties related components modularity#6882

Merged
sriramveeraghanta merged 8 commits intopreviewfrom
improvement-ui
Apr 9, 2025
Merged

[WEB-3788] improvement: enhance project properties related components modularity#6882
sriramveeraghanta merged 8 commits intopreviewfrom
improvement-ui

Conversation

@prateekshourya29
Copy link
Member

@prateekshourya29 prateekshourya29 commented Apr 7, 2025

Description

UI / UX improvements and components 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

    • Added dynamic default values for project forms, including randomized cover images and emoji logos.
    • Enhanced issue modals to preload data from URL parameters for smoother navigation.
    • Updated state management with user-friendly status names (e.g., Backlog, Todo, In Progress).
  • Refactor

    • Streamlined label and state operations with callback-driven event handling.
    • Improved form interactions and overall component cohesion.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 7, 2025

Walkthrough

This pull request introduces several new constants, types, and callback functions across multiple modules. It adds a new emoji constant and default project form values, refactors state management types and operations, and streamlines component props for issues, labels, projects, and state updates. Additionally, the changes refactor import declarations and enhance error handling, while integrating URL parameters and callback-driven designs in modal and state components.

Changes

File(s) Change Summary
packages/constants/src/emoji.ts, index.ts, project.ts, state.ts Added new constants (RANDOM_EMOJI_CODES, DEFAULT_PROJECT_FORM_VALUES), updated export statements, and enhanced type definitions (e.g. added defaultStateName to state groups).
packages/types/src/inbox.d.ts, state.d.ts Added new type imports (TInboxIssue, TInboxIssueStatus) and introduced TStateOperationsCallbacks for state operation callbacks; removed deprecated imports.
packages/ui/src/collapsible/collapsible-button.tsx, dropdowns/helper.tsx Updated prop types (e.g. title from string to React.ReactNode) and reformatted object type definitions for clarity.
packages/utils/src/common.ts Added isComplete function with improved type narrowing and null/empty object checks.
web/ce/components/issues/issue-modal/provider.tsx Added optional dataForPreload prop to provider and removed handleParentWorkItemDetails method.
web/ce/components/projects/create/root.tsx, template-select.tsx Removed old project cover logic, integrated DEFAULT_PROJECT_FORM_VALUES, and added a new component and prop (templateId) for project template selection.
web/ce/components/project/settings/features.tsx Refactored feature definitions by categorizing into base and other features with new type definitions and constants.
web/core/components/issues/issue-modal (context/modal).tsx Removed parent work item handling from context and enhanced modal functionality using URL parameters merged into a preload data object.
web/core/components/labels/ Refactored label components to use external labelOperationsCallbacks instead of store hooks; added optional properties like draggable and adjusted rendering logic.
web/core/components/project-states/ Updated multiple state components by removing unused properties (e.g. workspaceSlug, projectId) and adding callback-driven props (stateOperationsCallbacks, shouldTrackEvents), along with refined event tracking and submission logic.
web/core/components/project/ Added templateId prop to project creation modal and integrated a new ProjectTemplateSelect component into the project header.
web/core/store/project/project.store.ts Added methods getProjectByIdentifier and processProjectAfterCreation and updated createProject to consolidate creation logic.
web/helpers/emoji.helper.tsx Modified getRandomEmoji to reference RANDOM_EMOJI_CODES and improved error handling in groupReactions.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant M as CreateUpdateIssueModal
    participant P as IssueModalProvider
    participant R as Router (useParams)

    U->>M: Open Issue Modal
    M->>R: Retrieve URL parameters (cycleId, moduleId)
    R-->>M: Return parameters
    M->>M: Merge URL params with props.data into dataForPreload
    M->>P: Pass dataForPreload via provider
    P-->>U: Render modal with preloaded issue data
Loading
sequenceDiagram
    participant U as User
    participant PS as ProjectStateRoot
    participant OC as Operations Callback
    participant SS as State Service

    U->>PS: Trigger state creation/update
    PS->>OC: Invoke create/update state callback
    OC->>SS: Process state operation
    SS-->>OC: Return updated state info
    OC-->>PS: Propagate state update
    PS-->>U: Update UI with new state
Loading

Suggested reviewers

  • sriramveeraghanta

Poem

I’m just a little rabbit, hopping with delight,
New constants and callbacks, shining oh so bright.
Components smarter, with props so keen,
Code flows gracefully, a sight to be seen.
Hop on, dear coder, in this rhythmic byte 🐇✨
Let’s code, let’s laugh, and get everything right!

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

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

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@makeplane
Copy link

makeplane bot commented Apr 7, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🔭 Outside diff range comments (1)
web/core/components/project-states/state-item-title.tsx (1)

51-77: ⚠️ Potential issue

Add type safety to conditional rendering.

The code correctly conditionally renders components when !disabled, but doesn't ensure type safety when accessing enabled-only props.

Implement a type guard to ensure type safety:

-      {!disabled && (
+      {!disabled && isEnabled(props) && (
        <div className="hidden group-hover:flex items-center gap-2">
          {/* state mark as default option */}
          <div className="flex-shrink-0 text-xs transition-all">
            <StateMarksAsDefault
              stateId={state.id}
              isDefault={state.default ? true : false}
              markStateAsDefaultCallback={props.stateOperationsCallbacks.markStateAsDefault}
            />
          </div>

Without this change, TypeScript might not catch potential runtime errors when accessing props.stateOperationsCallbacks or props.shouldTrackEvents in a disabled state context.

🧰 Tools
🪛 Biome (1.9.4)

[error] 57-57: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🧹 Nitpick comments (8)
web/core/components/issues/issue-modal/modal.tsx (1)

34-50: Enhanced issue modal with URL parameter integration

The updated modal component now intelligently extracts cycle and module IDs from URL parameters and incorporates them into the preloaded data. This improves user experience by automatically populating the modal based on the current route.

Consider simplifying the nested ternary expressions for better readability:

-  cycle_id: props.data?.cycle_id ? props.data?.cycle_id : cycleId ? cycleId.toString() : null,
-  module_ids: props.data?.module_ids ? props.data?.module_ids : moduleId ? [moduleId.toString()] : null,
+  cycle_id: props.data?.cycle_id || (cycleId ? cycleId.toString() : null),
+  module_ids: props.data?.module_ids || (moduleId ? [moduleId.toString()] : null),
web/core/components/project-states/create-update/form.tsx (1)

97-97: Button onClick handler properly configured, but missing type attribute.

The button now uses an onClick handler instead of relying on form submission, which is consistent with the new approach. However, consider adding a type="button" attribute to explicitly define its behavior.

-<Button onClick={formSubmit} variant="primary" size="sm" disabled={buttonDisabled}>
+<Button type="button" onClick={formSubmit} variant="primary" size="sm" disabled={buttonDisabled}>
web/core/components/project-states/options/delete.tsx (1)

31-31: Simplify boolean expression in isDeleteDisabled.

The ternary expression can be simplified for better readability.

-const isDeleteDisabled = state.default ? true : totalStates === 1 ? true : false;
+const isDeleteDisabled = state.default || totalStates === 1;
🧰 Tools
🪛 Biome (1.9.4)

[error] 31-31: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

web/core/components/project-states/state-item.tsx (1)

48-48: Simplify boolean expression.

The ternary expression can be simplified for better readability.

-const isDraggable = totalStates === 1 ? false : true;
+const isDraggable = totalStates !== 1;
🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

web/ce/constants/project/settings/features.tsx (1)

25-71: Structured constants improve code organization and maintainability.

Extracting feature definitions into a well-organized constant improves code readability and maintainability. This will make future updates to feature properties more straightforward.

However, there's an inconsistency in the inbox feature:

  inbox: {
-    key: "intake",
+    key: "inbox",
    property: "inbox_view",

The key should match the feature key for consistency, as it does with other features.

web/core/components/labels/create-update-label-inline.tsx (3)

14-17: Consider adding doc comments.

The typed callback definitions look good. However, adding brief doc comments for createLabel and updateLabel would clarify the expected shape of Partial<IIssueLabel> and help maintainers understand the intended usage and potential constraints.


77-80: Suggestion: Provide success feedback on update.

After a successful updateLabel call, consider showing a success toast or visual confirmation alongside the handleClose(). This can inform users that their label was updated.

.then(() => {
+  setToast({
+    title: "Success!",
+    type: TOAST_TYPE.SUCCESS,
+    message: t("project_settings.labels.toast.success"),
+  });
  reset(defaultValues);
  handleClose();
})

128-128: Note about removing <form> usage.

Replacing a <form> with a <div> can limit default browser handling (like submitting on “Enter”), which some users rely on. Consider whether you need a form element for accessibility or if manual submission control is sufficient.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 543552f and c9e4fe3.

📒 Files selected for processing (36)
  • packages/constants/src/emoji.ts (1 hunks)
  • packages/constants/src/index.ts (1 hunks)
  • packages/constants/src/project.ts (2 hunks)
  • packages/constants/src/state.ts (2 hunks)
  • packages/types/src/inbox.d.ts (1 hunks)
  • packages/types/src/state.d.ts (1 hunks)
  • packages/ui/src/collapsible/collapsible-button.tsx (1 hunks)
  • packages/ui/src/dropdowns/helper.tsx (1 hunks)
  • packages/utils/src/common.ts (2 hunks)
  • web/ce/components/issues/issue-modal/provider.tsx (1 hunks)
  • web/ce/components/projects/create/root.tsx (4 hunks)
  • web/ce/components/projects/create/template-select.tsx (1 hunks)
  • web/ce/constants/project/settings/features.tsx (3 hunks)
  • web/core/components/issues/issue-modal/context/issue-modal-context.tsx (0 hunks)
  • web/core/components/issues/issue-modal/modal.tsx (2 hunks)
  • web/core/components/labels/create-update-label-inline.tsx (7 hunks)
  • web/core/components/labels/label-block/label-item-block.tsx (6 hunks)
  • web/core/components/labels/project-setting-label-group.tsx (5 hunks)
  • web/core/components/labels/project-setting-label-item.tsx (4 hunks)
  • web/core/components/labels/project-setting-label-list.tsx (5 hunks)
  • web/core/components/project-states/create-update/create.tsx (2 hunks)
  • web/core/components/project-states/create-update/form.tsx (4 hunks)
  • web/core/components/project-states/create-update/update.tsx (3 hunks)
  • web/core/components/project-states/group-item.tsx (3 hunks)
  • web/core/components/project-states/group-list.tsx (2 hunks)
  • web/core/components/project-states/options/delete.tsx (3 hunks)
  • web/core/components/project-states/options/mark-as-default.tsx (1 hunks)
  • web/core/components/project-states/root.tsx (2 hunks)
  • web/core/components/project-states/state-item-title.tsx (3 hunks)
  • web/core/components/project-states/state-item.tsx (3 hunks)
  • web/core/components/project-states/state-list.tsx (1 hunks)
  • web/core/components/project/create-project-modal.tsx (3 hunks)
  • web/core/components/project/create/header.tsx (2 hunks)
  • web/core/components/project/settings/features-list.tsx (1 hunks)
  • web/core/store/project/project.store.ts (7 hunks)
  • web/helpers/emoji.helper.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • web/core/components/issues/issue-modal/context/issue-modal-context.tsx
🧰 Additional context used
🧬 Code Definitions (21)
web/core/components/project/create/header.tsx (1)
web/ce/components/projects/create/template-select.tsx (1)
  • ProjectTemplateSelect (12-12)
web/ce/components/issues/issue-modal/provider.tsx (1)
packages/types/src/issues/issue.d.ts (1)
  • TIssue (54-67)
web/core/components/issues/issue-modal/modal.tsx (2)
web/ce/components/issues/issue-modal/provider.tsx (1)
  • IssueModalProvider (14-43)
web/core/components/issues/issue-modal/base.tsx (1)
  • CreateUpdateIssueModalBase (26-383)
packages/constants/src/state.ts (1)
packages/types/src/state.d.ts (1)
  • TStateGroups (3-3)
web/core/components/project/settings/features-list.tsx (6)
web/ce/constants/project/settings/features.tsx (1)
  • PROJECT_FEATURES_LIST (104-117)
packages/i18n/src/store/index.ts (1)
  • t (231-252)
packages/ui/src/tooltip/tooltip.tsx (1)
  • Tooltip (36-110)
web/core/store/project/project.store.ts (1)
  • currentProjectDetails (208-211)
packages/types/src/project/projects.d.ts (1)
  • IProject (39-55)
web/core/store/router.store.ts (1)
  • workspaceSlug (69-71)
web/core/components/labels/project-setting-label-item.tsx (1)
web/core/components/labels/create-update-label-inline.tsx (1)
  • TLabelOperationsCallbacks (14-17)
packages/constants/src/project.ts (2)
packages/types/src/project/projects.d.ts (1)
  • IProject (39-55)
packages/constants/src/emoji.ts (1)
  • RANDOM_EMOJI_CODES (12-25)
web/helpers/emoji.helper.tsx (1)
packages/constants/src/emoji.ts (1)
  • RANDOM_EMOJI_CODES (12-25)
web/core/components/project-states/group-list.tsx (2)
packages/types/src/state.d.ts (3)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
  • TStateGroups (3-3)
packages/constants/src/state.ts (1)
  • TStateGroups (1-1)
web/core/components/project-states/state-list.tsx (2)
packages/constants/src/state.ts (1)
  • TStateGroups (1-1)
packages/types/src/state.d.ts (3)
  • TStateGroups (3-3)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
web/core/components/project-states/root.tsx (3)
packages/types/src/state.d.ts (2)
  • TStateOperationsCallbacks (28-34)
  • IState (5-15)
web/core/store/state.store.ts (1)
  • groupedProjectStates (103-119)
web/core/components/project-states/group-list.tsx (1)
  • GroupList (21-75)
packages/utils/src/common.ts (1)
packages/types/src/utils.d.ts (1)
  • CompleteOrEmpty (5-5)
web/core/components/labels/project-setting-label-group.tsx (1)
web/core/components/labels/create-update-label-inline.tsx (1)
  • TLabelOperationsCallbacks (14-17)
web/core/components/project-states/create-update/update.tsx (1)
packages/types/src/state.d.ts (2)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
web/core/components/labels/project-setting-label-list.tsx (2)
web/core/components/labels/create-update-label-inline.tsx (1)
  • TLabelOperationsCallbacks (14-17)
web/core/store/router.store.ts (2)
  • workspaceSlug (69-71)
  • projectId (85-87)
web/core/components/project-states/options/mark-as-default.tsx (1)
packages/types/src/state.d.ts (1)
  • TStateOperationsCallbacks (28-34)
web/core/components/project-states/state-item-title.tsx (2)
packages/types/src/state.d.ts (2)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
web/core/components/project-states/options/delete.tsx (1)
  • StateDelete (22-124)
web/core/components/project-states/create-update/create.tsx (2)
packages/constants/src/state.ts (1)
  • TStateGroups (1-1)
packages/types/src/state.d.ts (3)
  • TStateGroups (3-3)
  • TStateOperationsCallbacks (28-34)
  • IState (5-15)
web/core/components/project-states/state-item.tsx (3)
packages/constants/src/state.ts (1)
  • TStateGroups (1-1)
packages/types/src/state.d.ts (3)
  • TStateGroups (3-3)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
web/core/components/project-states/state-item-title.tsx (1)
  • StateItemTitle (29-80)
web/core/components/project-states/options/delete.tsx (2)
packages/types/src/state.d.ts (2)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
packages/hooks/src/use-platform-os.tsx (1)
  • usePlatformOS (3-34)
web/core/components/project-states/group-item.tsx (3)
packages/constants/src/state.ts (1)
  • TStateGroups (1-1)
packages/types/src/state.d.ts (3)
  • TStateGroups (3-3)
  • IState (5-15)
  • TStateOperationsCallbacks (28-34)
web/core/components/project-states/create-update/create.tsx (1)
  • StateCreate (20-98)
🪛 Biome (1.9.4)
web/core/components/project-states/state-item.tsx

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

web/core/components/project-states/options/delete.tsx

[error] 31-31: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (138)
web/ce/components/issues/issue-modal/provider.tsx (1)

4-4: Appropriate import addition for new type usage

The import of TIssue from @plane/types properly supports the newly added dataForPreload property.

packages/constants/src/index.ts (1)

32-32: Clean export addition

Adding the emoji module export improves modularity by making emoji constants accessible throughout the application.

packages/constants/src/emoji.ts (1)

12-25:

Details

✅ Verification successful

Good addition of reusable emoji constants

The RANDOM_EMOJI_CODES array follows the same pattern as the existing emoji constants and provides a good set of emoji options for random selection. This enhances modularity by centralizing emoji definitions.

Let's verify how these emoji codes are being used:


🏁 Script executed:

#!/bin/bash
# Check how RANDOM_EMOJI_CODES is being used across the codebase
grep -r "RANDOM_EMOJI_CODES" --include="*.tsx" --include="*.ts" --exclude="emoji.ts" .

Length of output: 518


Code Review Approval: Usage of RANDOM_EMOJI_CODES Verified

The addition of the RANDOM_EMOJI_CODES constant in packages/constants/src/emoji.ts is well implemented and consistent with existing emoji constants. Our verification shows its usage in the following locations:

  • packages/constants/src/project.ts: Imported and used for random selection.
  • web/helpers/emoji.helper.tsx: Imported and employed by the getRandomEmoji function for random emoji retrieval.

These usages confirm that the newly added emoji codes are integrated as intended, enhancing modularity and ensuring centralized emoji definitions.

web/core/components/project/create-project-modal.tsx (3)

22-22: Good addition of templateId property

Adding the optional templateId property enhances the component's flexibility and reusability by allowing template-based project creation.


31-31: Clean props destructuring

The destructuring pattern properly includes the new templateId property while maintaining the existing structure.


67-67: Proper prop forwarding to child component

Passing the templateId to the CreateProjectForm component follows good practices for prop forwarding and enhances component modularity.

packages/ui/src/dropdowns/helper.tsx (1)

47-55: Improved code formatting enhances readability.

The reformatting of the options property in the CustomSearchSelectProps interface improves code readability while maintaining the same functionality. This structured formatting makes the interface definition clearer and easier to understand.

packages/ui/src/collapsible/collapsible-button.tsx (2)

3-3: Import organization improvement.

Moving the DropdownIcon import to the top of the file follows better code organization practices.


7-7: Enhanced component flexibility with React.ReactNode.

Changing the title prop type from string to React.ReactNode significantly enhances the component's flexibility, allowing it to accept not just strings but also complex React elements, icons, or other components as titles.

This change aligns well with the PR's objective of enhancing component modularity and will enable more dynamic and interactive UI elements in the collapsible component.

packages/utils/src/common.ts (2)

3-3: Added import for type support.

Adding the import for CompleteOrEmpty from @plane/types correctly supports the new utility function.


44-60: Well-implemented type narrowing utility function.

The isComplete function is a well-designed utility that enhances TypeScript's type narrowing capabilities. It properly checks for null/undefined values, validates that the input is an object type, and verifies the presence of properties.

The function's type predicate (obj is T) effectively helps TypeScript narrow from CompleteOrEmpty<T> to T in conditional branches, improving type safety throughout the codebase.

The comprehensive JSDoc comments clearly explain the function's purpose, parameters, and return value, which will facilitate correct usage by other developers.

packages/types/src/inbox.d.ts (1)

1-3: Improved type dependency organization.

Importing TInboxIssue and TInboxIssueStatus from @plane/constants instead of defining them locally or importing from another file reflects a positive move toward centralizing type definitions. This approach enhances consistency across the codebase and aligns with the PR's objective of improving component modularity.

The refactoring suggests a thoughtful reorganization of type dependencies, which should make the codebase more maintainable in the long run.

web/core/components/project/create/header.tsx (2)

17-18: New import added for project template selection

Good job adding the import for the ProjectTemplateSelect component from the plane-web components. This follows the project's modular approach by keeping template selection functionality in a separate component.


44-46: Template selection component placement is appropriate

The absolute positioning of the template selector in the top-left corner is consistent with the UI design pattern used for other components in this header. The prop passing follows good practices by reusing the existing handleClose function.

web/ce/components/projects/create/template-select.tsx (2)

1-9: Well-structured type definitions for template selection

The type definitions are clear and properly exported. The TProjectTemplateSelect interface includes a good mix of required and optional properties that will allow for flexible component usage.


11-12: Component is just a placeholder - implementation needed

The component currently renders an empty fragment. While this establishes the component structure, you'll need to implement the actual functionality for template selection.

Can you confirm if the actual template selection component implementation is planned for a future PR? If this is intended to be a placeholder for now, consider adding a TODO comment explaining this.

web/ce/components/projects/create/root.tsx (5)

6-6: Good use of constants for default values

Using the DEFAULT_PROJECT_FORM_VALUES constant from the constants package improves maintainability by centralizing default values.


27-27: Added template support via new prop

Adding the optional templateId property enhances the component's flexibility for template-based project creation.


32-32: Updated prop destructuring to include data

Good change to include data in the destructured props, which is now being used in the defaultValues.


41-41: Improved form default values handling

Using spread operators to combine default values with passed data is a clean approach that enhances reusability and flexibility.


92-92: Enhanced error handling with optional chaining

Good improvement to error handling by adding optional chaining and nullish coalescing. This prevents potential runtime errors when err or err.data is undefined.

packages/constants/src/state.ts (3)

1-1: Simplified type definition

Simplifying the TStateGroups type definition to a single line improves code readability while maintaining the same functionality.


12-12: Added default state names for improved consistency

Adding the defaultStateName property to state groups is a good improvement for modularity. This allows components to reference standard state names without hardcoding them, which will help maintain consistency across the application.

Also applies to: 19-19, 25-25, 31-31, 37-37, 43-43


48-48: Simplified constant definition

The simplified one-line definition of ARCHIVABLE_STATE_GROUPS is more concise while maintaining the same functionality.

packages/types/src/state.d.ts (1)

28-34: Well-structured state operation callbacks type definition

The TStateOperationsCallbacks type is a clean and comprehensive definition for state operation callbacks. The type signature covers all the necessary operations with appropriate parameter and return types.

web/core/components/project/settings/features-list.tsx (1)

62-106: Improved iteration over features list using Object.entries

The refactoring from Object.keys() to Object.entries() improves code readability and efficiency by directly destructuring both keys and values. This eliminates the need for additional lookups and makes the code more maintainable.

packages/constants/src/project.ts (2)

1-4: Improved import organization

The imports have been reorganized with clearer comments, separating plane imports from local imports for better readability.


138-151: New default project form values constant

The DEFAULT_PROJECT_FORM_VALUES constant provides a well-structured set of default values for project forms, including random cover images and emojis for better user experience.

Be aware that using Math.random() means different values will be selected each time this code is executed. This could potentially lead to inconsistent behavior in server-side rendering scenarios. Consider if this randomization should happen at render time instead of module import time.

web/core/components/project-states/create-update/form.tsx (2)

3-3: Import statement change aligns with new event handling approach.

The removal of the FormEvent import and maintaining only the essential React hooks is consistent with the changes in the form submission mechanism.


31-31: Function parameter type updated for button-based submission.

The parameter type change from FormEvent<HTMLFormElement> to React.MouseEvent<HTMLButtonElement, MouseEvent> correctly reflects the shift from form submission to button click event handling.

web/core/components/project-states/state-list.tsx (4)

5-5: Import updated to include new type dependency.

The addition of TStateOperationsCallbacks import from @plane/types correctly supports the type changes in this file.


13-16: Component interface improved for better modularity.

The removal of direct dependencies on workspaceSlug and projectId in favor of stateOperationsCallbacks enhances component reusability. The addition of shouldTrackEvents and optional stateItemClassName provides better flexibility.


20-28: Props destructuring updated to match type changes.

The destructuring has been properly updated to include the new properties and remove the unused ones, ensuring type safety and code clarity.


40-42: StateItem props correctly passed to maintain functionality.

The new props are properly passed to the StateItem component, ensuring that the callback-based approach is consistently applied throughout the component hierarchy.

web/helpers/emoji.helper.tsx (4)

1-2: Centralized emoji constants for better maintainability.

Good practice to import the RANDOM_EMOJI_CODES constant from a centralized location rather than maintaining hardcoded values in multiple files.


5-5: Simplified getRandomEmoji function using imported constant.

The function has been elegantly simplified by using the imported constant, making the code more maintainable and consistent.


32-35: Enhanced error handling for non-array inputs.

Good defensive programming by checking if the input is an array before processing, preventing potential runtime errors.


39-42: Improved robustness with reaction validity checks.

The additional checks for undefined reactions or missing keys with appropriate warning logs enhance the reliability of the function and make debugging easier.

web/core/components/project-states/options/mark-as-default.tsx (6)

5-7: Imports reorganized and updated to support callback pattern.

The addition of TStateOperationsCallbacks import and cn utility supports the new callback-based approach and provides better styling utilities.


9-13: Type definition improved for better modularity.

Replacing direct dependencies on workspaceSlug and projectId with a specific callback function enhances component reusability and encapsulation.


16-16: Props destructuring updated to match type changes.

The destructuring has been properly updated to include the new callback and remove the unused properties.


21-21: Simplified condition check for better readability.

The condition in handleMarkAsDefault has been simplified to focus on the essential checks, making the code more readable.


26-26: Updated function call to use the callback pattern.

The function call has been correctly updated to use the new callback approach, maintaining functionality while improving modularity.


28-28: Simplified error handling in catch block.

Removed the unused error parameter from the catch block, which is a good practice for cleaner code.

web/core/store/project/project.store.ts (7)

40-40: New method to get a project by identifier.

This new method provides a convenient way to search for projects by their identifier, adding flexibility to how projects can be retrieved.


49-50: Added helper action category for better code organization.

The helper actions category provides a clear separation between helper methods and other store actions.


112-112: Added helper action to makeObservable.

Properly registering the new processProjectAfterCreation method as an action ensures MobX correctly tracks and processes it.


241-246: Improved code formatting for better readability.

The filter conditions are now properly aligned, making the code more readable.


268-279: Encapsulated project creation processing logic.

This new method encapsulates the logic for updating state after a project is created, making the code more modular and maintainable. Using runInAction ensures that all state updates are properly tracked by MobX.


388-395: Added method to find projects by identifier.

The new getProjectByIdentifier method is a useful addition that allows finding projects by their identifier string, complementing the existing methods that find projects by ID.


515-515: Refactored project creation to use the new helper method.

The createProject method now uses the processProjectAfterCreation method, improving code organization by centralizing the state update logic.

web/core/components/project-states/group-list.tsx (5)

6-7: Enhanced imports organization with "plane imports" comment.

Clearly separating imports with comments improves code organization and readability.


13-18: Added new props to enhance component flexibility.

The component now receives callbacks for state operations, editability control, event tracking flags, and styling customizations, making it more modular and reusable.


22-30: Refactored props destructuring for better maintainability.

The component now destructures the new props and no longer depends on workspace and project IDs, enhancing its reusability across different contexts.


52-52: Improved className handling with the cn utility.

Using the cn utility to combine classNames makes the component's styling more flexible and maintainable.


63-69: Updated GroupItem props to support the new component structure.

The GroupItem component now receives the state operation callbacks and styling props, ensuring consistent implementation throughout the component hierarchy.

web/core/components/project-states/options/delete.tsx (8)

6-10: Organized imports with clear categorization.

The imports are now better organized with clear separator comments, enhancing code readability.


15-20: Refactored component props for better modularity.

The component now accepts a callback for state deletion and a flag for event tracking rather than relying on direct workspace and project IDs, making it more reusable.


23-23: Updated props destructuring to reflect new component structure.

The component now properly destructures the new props, enhancing its maintainability.


33-37: Added helper function for conditional event tracking.

The captureEventIfEnabled function elegantly handles conditional event tracking based on the shouldTrackEvents flag.


39-44: Simplified state deletion logic with callback pattern.

The handleDeleteState function now has a cleaner implementation, checking only if deletion is disabled and conditionally setting tracking elements.


47-54: Updated state deletion implementation to use callback.

The component now uses the provided callback for state deletion rather than a direct hook call, enhancing its modularity.


58-64: Improved error handling with conditional event tracking.

The error handling now uses the captureEventIfEnabled function for better code consistency.


101-102: Added button type attribute for better accessibility.

Adding type="button" to the button element improves accessibility by preventing form submission in nested contexts.

web/core/components/project-states/state-item.tsx (9)

10-10: Updated import for state types.

The component now imports the necessary state types and callbacks from @plane/types.


18-27: Enhanced component props for better flexibility.

The component now accepts callbacks for state operations, event tracking flag, and custom styling, making it more configurable and reusable.


30-39: Refactored props destructuring for better readability.

The component now properly destructures all the props, including the new ones, enhancing code readability.


44-53: Created a common props object for the StateItemTitle component.

Using a common props object for shared properties improves code organization and reduces duplication.

🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


58-59: Simplified state sequence handling with callback pattern.

The component now uses the provided callback for moving state positions rather than a direct hook call, enhancing its modularity.


64-64: Updated dependency array in useCallback.

The dependency array now correctly includes the stateOperationsCallbacks to ensure the callback is updated when the callbacks change.


123-124: Updated StateUpdate component props.

The StateUpdate component now receives the update callback and event tracking flag, consistent with the overall refactoring approach.


138-139: Improved conditional styling with custom class name support.

The component now supports custom class names through props, enhancing styling flexibility.


142-154: Enhanced conditional rendering with proper props passing.

The component now conditionally renders the StateItemTitle with appropriate props based on the disabled state, improving code clarity and maintainability.

web/core/components/project-states/create-update/update.tsx (9)

5-6: Good job updating the imports.

The imports now correctly include the EventProps from constants and TStateOperationsCallbacks from types, which aligns with the new callback-driven approach being implemented.


13-18: Props interface refactoring enhances modularity.

Removing direct dependencies on workspaceSlug and projectId in favor of callback functions makes this component more reusable and decoupled from specific data sources. The addition of shouldTrackEvents also provides better control over analytics.


21-21: Updated props destructuring matches the new interface.

This change correctly reflects the updated component interface, focusing on the callback-driven approach.


32-36: Great encapsulation of event tracking logic.

Creating a helper function captureEventIfEnabled centralizes the conditional event tracking logic and reduces code duplication. This is a good practice for maintainability.


38-40: Simplified validation logic.

The validation is now more focused, only checking what's necessary (state.id) rather than also verifying workspaceSlug and projectId, which are now handled by the parent component.


41-43: Conditional event tracking respects configuration.

The event tracking is now properly conditional based on the shouldTrackEvents flag, which is a good improvement for flexibility.


45-45: Using callback for state updates enhances modularity.

Switching to the callback approach decouples this component from the specific implementation of state updates, making it more reusable.


46-53: Good use of the new event tracking helper.

Using the captureEventIfEnabled function here maintains consistent event tracking behavior while respecting the configuration.


76-83: Consistent error handling with conditional event tracking.

The error handling section properly uses the same conditional event tracking approach, maintaining consistency throughout the component.

web/core/components/project-states/group-item.tsx (8)

8-8: Good import update for the callback types.

Including the TStateOperationsCallbacks import from @plane/types properly supports the new callback-driven approach.


14-26: Enhanced component interface improves modularity and customization.

The updated TGroupItem type removes direct dependencies on workspaceSlug and projectId while adding support for callbacks, styling customization, and behavior control. This makes the component more reusable across different contexts.


29-41: Updated props destructuring aligns with the new type definition.

The destructuring now correctly extracts all the new properties from props, making them available to the component logic.


54-57: Good use of className composition with cn utility.

Using the cn utility for conditional class merging while including the optional groupItemClassName prop allows for flexible styling customization.


84-86: Improved disabled state styling logic.

The button's styling now correctly reflects both the isEditable state and the createState condition.


87-93: Enhanced button click handler with additional checks.

The modified click handler now checks if createState is false before proceeding with the expand action, and the disabled state properly reflects both required conditions. This prevents potential issues with multiple create states being initiated.


108-116: Properly passing new props to child StateList component.

The StateList component now receives the necessary callbacks and configuration options, aligning with the modular architecture.


122-127: Updated StateCreate props for callback-driven approach.

The StateCreate component now receives the specific callback function and tracking configuration, enhancing modularity.

web/core/components/project-states/create-update/create.tsx (9)

5-6: Good update to imports for the new functionality.

Including EventProps and TStateOperationsCallbacks properly supports the modified component logic.


13-18: Props interface refactoring enhances modularity.

Removing direct dependencies on workspaceSlug and projectId in favor of callback functions improves component reusability. The addition of shouldTrackEvents aligns with the consistent approach to analytics across components.


21-21: Updated props destructuring matches the new interface.

Properly destructuring the new props makes them available to the component logic.


27-31: Excellent encapsulation of event tracking logic.

The captureEventIfEnabled function centralizes conditional event tracking, consistent with the approach in the update component.


38-39: Simplified validation logic.

The validation is now more focused, only checking for groupKey rather than also verifying workspaceSlug and projectId.


41-43: Conditional event tracking based on configuration.

Properly implementing conditional event tracking based on the shouldTrackEvents flag enhances flexibility.


45-45: Using callback pattern for state creation.

Using the provided callback function instead of direct state creation enhances modularity.


46-53: Consistent event tracking with the helper function.

The success event capture now uses the conditional helper function, maintaining consistency.


63-70: Consistent error handling with conditional event tracking.

The error handling properly uses the same conditional approach to event tracking.

web/core/components/project-states/root.tsx (5)

3-11: Good updates to imports for enhanced functionality.

Adding useMemo, permission-related constants, and the state types properly supports the new component functionality. The updated imports for hooks, particularly including useUserPermissions, enables proper permission handling.


21-31: Enhanced state operations access.

Destructuring additional state operation functions from useProjectState and adding the permissions hook allows for more comprehensive state management and access control.


32-37: Properly implemented permission checking.

The isEditable flag is now derived from explicit permission checks, ensuring that only users with appropriate permissions can make changes. This is a good security practice.


47-58: Excellent use of useMemo for callback creation.

Creating the stateOperationsCallbacks object with useMemo and the proper dependency array ensures that callbacks are only recreated when necessary, which is good for performance. The comprehensive set of wrapped callbacks provides all necessary operations to child components.


65-70: Updated GroupList props for the new architecture.

The GroupList component now receives the necessary callbacks, editability state, and event tracking configuration, aligning with the modular architecture implemented across the component tree.

web/ce/constants/project/settings/features.tsx (7)

3-4: Adding "plane imports" comment for better organization.

Good practice to add comments that organize imports based on their source, making the code structure clearer for maintainers.


18-20: Well-defined type categorization for project features.

Creating distinct union types for base and other feature keys improves type safety and code organization.


21-24: Good use of mapped types for feature lists.

Using TypeScript's mapped types to ensure each feature key maps to the correct properties structure enhances type safety and prevents errors.


73-87: Consistent structure for other features list.

The structure for TOtherFeatureList and its implementation maintain consistency with the base features approach, which is good for maintainability.


89-102: Improved type safety for project features.

Updating the TProjectFeatures type to use the new feature list types enhances type safety and makes the code more robust.


109-110: Good refactoring to use constants.

Using the new constants for feature lists rather than inline definitions improves code maintainability and reduces duplication.


115-116: Consistent usage of feature list constants.

Maintaining consistency by using structured constants for both base and other features improves code quality.

web/core/components/project-states/state-item-title.tsx (3)

5-5: Updated import to include TStateOperationsCallbacks.

Good practice to explicitly import the types you need, improving code readability and maintainability.


10-25: Well-structured props type hierarchy with discriminated union.

Creating a base type with shared properties and specialized types for enabled/disabled states enhances type safety and code clarity. The discriminated union pattern with disabled as the discriminant is an excellent TypeScript practice.


69-74: Improved prop passing to child components.

Passing callback functions directly to the StateDelete component enhances modularity and makes the component relationships clearer.

web/core/components/labels/project-setting-label-item.tsx (4)

9-9: Added import for TLabelOperationsCallbacks type

The addition of the TLabelOperationsCallbacks import enhances the component's modularity by allowing it to leverage standardized callbacks for label operations.


26-26: Good addition of labelOperationsCallbacks property

Adding this property to the Props type enhances modularity by allowing the component to receive label operation callbacks from parent components rather than implementing the logic itself.


39-39: Properly destructured the new prop

The labelOperationsCallbacks property is correctly destructured from props to be used within the component.


94-94: Correctly passed labelOperationsCallbacks to child component

The labelOperationsCallbacks is properly passed to the CreateUpdateLabelInline component, ensuring consistent label operation handling throughout the component hierarchy.

web/core/components/labels/label-block/label-item-block.tsx (5)

32-32: Added draggable prop for enhanced flexibility

The addition of the optional draggable property improves the component's flexibility and reusability by allowing parent components to control whether the label item can be dragged.


44-44: Good default value for draggable prop

Setting the default value to true maintains backward compatibility with existing usage of the component while allowing explicit control when needed.


47-47: Changed initial state of isMenuActive

The initial state of isMenuActive has been changed to true. Make sure this change doesn't affect the menu's default visibility in unexpected ways.

Please verify this change doesn't negatively impact the user experience by making menus unexpectedly visible by default.


56-56: Enhanced conditional rendering with draggable prop

The DragHandle component now correctly considers both the disabled state and the new draggable property, improving control over when drag functionality is available.


82-82: Updated sizing classes for better consistency

Changed from dimension-specific classes (h-4 w-4) to the more concise size-4 utility class for better maintainability and consistency across the codebase.

Also applies to: 92-92, 95-95

web/core/components/labels/project-setting-label-group.tsx (5)

10-10: Added import for TLabelOperationsCallbacks type

The addition of the TLabelOperationsCallbacks import enhances the component's modularity by allowing it to leverage standardized callbacks for label operations.


28-28: Good addition of labelOperationsCallbacks property

Adding this property to the Props type enhances modularity by allowing the component to receive label operation callbacks from parent components rather than implementing the logic itself.


42-42: Properly destructured the new prop

The labelOperationsCallbacks property is correctly destructured from props to be used within the component.


92-92: Correctly passed labelOperationsCallbacks to CreateUpdateLabelInline

The labelOperationsCallbacks is properly passed to the CreateUpdateLabelInline component, ensuring consistent label operation handling during the label editing process.


140-140: Properly propagated labelOperationsCallbacks to child components

The labelOperationsCallbacks is correctly passed down to each ProjectSettingLabelItem child component, ensuring consistent label operation handling throughout the component hierarchy.

web/core/components/labels/project-setting-label-list.tsx (5)

17-17: Added import for TLabelOperationsCallbacks type

The addition of the TLabelOperationsCallbacks import is necessary to define the label operations callbacks structure within this component.


28-28: Updated ref type from HTMLFormElement to HTMLDivElement

The scrollToRef is now correctly typed as HTMLDivElement, which better matches its usage within the component.


36-36: Added createLabel and updateLabel to hook destructuring

The destructuring now includes the createLabel and updateLabel methods from the useLabel hook, which are used to implement the label operations callbacks.


41-45: Well-structured implementation of labelOperationsCallbacks

The implementation of labelOperationsCallbacks is clean and follows the required interface. It correctly passes the workspace and project IDs to the hook methods.

However, consider adding null/undefined checks for workspaceSlug and projectId to prevent potential issues:

  const labelOperationsCallbacks: TLabelOperationsCallbacks = {
-   createLabel: (data: Partial<IIssueLabel>) => createLabel(workspaceSlug?.toString(), projectId?.toString(), data),
+   createLabel: (data: Partial<IIssueLabel>) => {
+     if (!workspaceSlug || !projectId) return Promise.reject(new Error("Missing workspace or project ID"));
+     return createLabel(workspaceSlug.toString(), projectId.toString(), data);
+   },
-   updateLabel: (labelId: string, data: Partial<IIssueLabel>) =>
-     updateLabel(workspaceSlug?.toString(), projectId?.toString(), labelId, data),
+   updateLabel: (labelId: string, data: Partial<IIssueLabel>) => {
+     if (!workspaceSlug || !projectId) return Promise.reject(new Error("Missing workspace or project ID"));
+     return updateLabel(workspaceSlug.toString(), projectId.toString(), labelId, data);
+   },
  };

93-93: Correctly passed labelOperationsCallbacks to all child components

The labelOperationsCallbacks is properly passed to CreateUpdateLabelInline, ProjectSettingLabelGroup, and ProjectSettingLabelItem components, ensuring consistent label operation handling throughout the component hierarchy.

Also applies to: 127-127, 141-141

web/core/components/labels/create-update-label-inline.tsx (5)

19-23: Good separation of concerns with callback-based label operations.

Passing label operations into the component via labelOperationsCallbacks promotes looser coupling and improved modularity. This approach helps keep your business logic separate from UI concerns.


34-35: Appropriate usage of forwardRef.

The component’s reference is applied correctly to the <div>. This pattern is useful for managing scroll or focus events in parent components and ensures the ref is accessible if needed.


58-61: Prevention of double submission is a nice touch.

Checking isSubmitting before calling createLabel helps protect against multiple rapid clicks. This is a solid practice to avoid creating duplicate labels or causing data inconsistencies.


95-101: Clear separation of create vs. update logic.

The handleFormSubmit function neatly branches to handleLabelUpdate or handleLabelCreate. This is easy to follow and maintains clarity in each operation’s flow.


206-217: Manual form submission handling is implemented correctly.

Calling e.preventDefault(); followed by handleSubmit(handleFormSubmit)() effectively processes the form data under your control. This pattern aligns with typical react-hook-form usage for custom submission flows.

@prateekshourya29 prateekshourya29 changed the title [WEB-3788] Enhance project properties related components modularity [WEB-3788] improvement: enhance project properties related components modularity Apr 7, 2025
@sriramveeraghanta sriramveeraghanta merged commit 1f92220 into preview Apr 9, 2025
5 of 6 checks passed
@sriramveeraghanta sriramveeraghanta deleted the improvement-ui branch April 9, 2025 09:20
@coderabbitai coderabbitai bot mentioned this pull request Apr 9, 2025
6 tasks
lifeiscontent pushed a commit that referenced this pull request Aug 18, 2025
… modularity (#6882)

* improvement: work item modal data preload and parent work item details

* improvement: collapsible button title

* improvement: project creation form and modal

* improvement: emoji helper

* improvement: enhance labels component modularity

* improvement: enable state group and state list components modularity

* improvement: project settings feature list

* improvement: common utils
@coderabbitai coderabbitai bot mentioned this pull request Sep 3, 2025
2 tasks
@coderabbitai coderabbitai bot mentioned this pull request Oct 1, 2025
Closed
6 tasks
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