Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[WEB-2388] dev: workspace draft issues #5772

Merged
merged 26 commits into from
Oct 10, 2024
Merged

Conversation

anmolsinghbhatia
Copy link
Collaborator

@anmolsinghbhatia anmolsinghbhatia commented Oct 8, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced components for managing draft issues, including WorkspaceDraftHeader, WorkspaceDraftLayout, and DraftIssueBlock.
    • Added functionality for creating, updating, and deleting draft issues with user permission checks.
    • New hooks and services for managing workspace draft issues.
  • Enhancements

    • Improved filtering and querying of draft issues.
    • Added new menu items and empty state handling for draft issues.
  • Bug Fixes

    • Streamlined error handling and data fetching for draft issues.
  • Documentation

    • Updated type definitions to enhance type safety for draft issue management.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2024

Walkthrough

The pull request introduces significant refactoring and new features across various components related to workspace draft issues. Key changes include the enhancement of the WorkspaceDraftIssueViewSet for better maintainability, the introduction of multiple new components for managing draft issues, and the addition of new TypeScript type definitions. The pagination logic has been refined, and new hooks and services have been created to facilitate CRUD operations on draft issues, alongside updates to existing components for improved functionality and user experience.

Changes

File Path Change Summary
apiserver/plane/app/views/workspace/draft.py Refactored WorkspaceDraftIssueViewSet, added get_queryset, updated method signatures for list, create, partial_update, retrieve, create_draft_to_issue.
apiserver/plane/utils/paginator.py Updated OffsetPaginator, GroupedOffsetPaginator, SubGroupedOffsetPaginator, BasePaginator with logging and slicing logic enhancements.
packages/types/src/index.d.ts Added export for workspace-draft-issues/base.
packages/types/src/issues/base.d.ts Introduced new type definitions for improved type safety.
packages/types/src/workspace-draft-issues/base.d.ts Added new TypeScript type definitions for workspace draft issues.
web/app/[workspaceSlug]/(projects)/drafts/header.tsx Introduced WorkspaceDraftHeader component for managing draft issue modal state and permissions.
web/app/[workspaceSlug]/(projects)/drafts/layout.tsx Added WorkspaceDraftLayout component as a wrapper for drafts.
web/app/[workspaceSlug]/(projects)/drafts/page.tsx Created WorkspaceDraftPage component for displaying draft issues.
web/core/components/issues/issue-layouts/filters/applied-filters/roots/workspace-draft-root.tsx Added WorkspaceDraftIssueLayoutRoot component for managing draft issue layout.
web/core/components/issues/issue-layouts/list/base-list-root.tsx Updated ListStoreType to include EIssuesStoreType.WORKSPACE_DRAFT.
web/core/components/issues/workspace-draft/delete-modal.tsx Introduced WorkspaceDraftIssueDeleteIssueModal component for deleting draft issues.
web/core/components/issues/workspace-draft/draft-issue-block.tsx Added DraftIssueBlock component for displaying draft issues.
web/core/components/issues/workspace-draft/draft-issue-properties.tsx Created DraftIssueProperties component for managing draft issue properties.
web/core/components/issues/workspace-draft/empty-state.tsx Added WorkspaceDraftEmptyState component for handling empty draft states.
web/core/constants/dashboard.ts Added new "Drafts" menu item to SIDEBAR_USER_MENU_ITEMS.
web/core/constants/empty-state.ts Added entry for WORKSPACE_DRAFT_ISSUES in EmptyStateType enum.
web/core/constants/issue.ts Added WORKSPACE_DRAFT to EIssuesStoreType enum.
web/core/hooks/store/workspace-draft/use-workspace-draft-issue-filters.ts Introduced useWorkspaceDraftIssueFilters hook for accessing filters.
web/core/hooks/store/workspace-draft/use-workspace-draft-issue.ts Introduced useWorkspaceDraftIssues hook for accessing draft issues.
web/core/services/issue/workspace_draft.service.ts Added WorkspaceDraftService class for managing draft issues.
web/core/store/issue/workspace-draft/filter.store.ts Introduced WorkspaceDraftIssuesFilter class for managing filters.

Possibly related PRs

Suggested labels

🌐frontend, ⚙️backend, 🌟enhancement, 🧹chore

Suggested reviewers

  • SatishGandham
  • sriramveeraghanta

Poem

In the workspace where drafts do play,
New features hop and dance all day.
With headers bright and layouts neat,
Draft issues now are quite the treat!
So gather 'round, let’s create and cheer,
For every draft brings us near! 🐰✨


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

e.stopPropagation();
}}
>
<WorkspaceDraftIssueQuickActions
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is there two WorkspaceDraftIssueQuickActions

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a bug please check

Copy link
Collaborator

Choose a reason for hiding this comment

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

@rahulramesha We have that because we have to render in two different places based on the responsiveness

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

@@ -428,7 +428,7 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
</div>
</CustomMenu.MenuItem>
)}
{isAuthorized && (
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove commented code if not required

@@ -102,7 +102,7 @@ export const SidebarQuickActions = observer(() => {
<PenSquare className="size-4" />
{!isSidebarCollapsed && <span className="text-sm font-medium">New issue</span>}
</button>
{!disabled && workspaceDraftIssue && (
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

) => Promise<TWorkspaceDraftIssue | undefined>;
}

export class WorkspaceDraftIssues implements IWorkspaceDraftIssues {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should extend base issues store and use the methods within that for pagination, this looks like it is different from the pattern we have

Copy link
Contributor

@rahulramesha rahulramesha left a comment

Choose a reason for hiding this comment

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

Approving this, please raise another PR for refactoring the store

@anmolsinghbhatia anmolsinghbhatia marked this pull request as ready for review October 10, 2024 13:21
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: 33

🧹 Outside diff range and nitpick comments (55)
web/core/constants/workspace-drafts.ts (1)

1-1: Consider adding documentation for the enum.

To improve code maintainability and make it easier for other developers to understand the purpose and usage of this enum, consider adding a brief documentation comment above the enum declaration. This could include a description of when each state is used in the pagination process.

Here's an example of how you might document this enum:

/**
 * Represents the different states of pagination for draft issues.
 * 
 * INIT: Used when initializing the pagination, typically for the first page load.
 * NEXT: Used when moving to the next page of draft issues.
 * PREV: Used when moving to the previous page of draft issues.
 * CURRENT: Used to refresh or stay on the current page.
 */
export enum EDraftIssuePaginationType {
  // ... (enum members remain the same)
}
web/core/components/issues/issue-layouts/quick-action-dropdowns/index.ts (1)

7-7: LGTM! Consider grouping related exports.

The addition of the new export for workspace draft quick actions is appropriate and consistent with the existing code style. This change enhances the modularity of the component's interface by making the workspace draft quick actions available through this index file.

For better code organization, consider grouping related exports together. You might want to move this new export next to the draft-issue export if they are closely related. This would improve readability and make it easier to maintain the file in the future.

web/app/[workspaceSlug]/(projects)/drafts/layout.tsx (2)

6-6: LGTM: Component definition is clear and well-typed.

The component is correctly defined as a default export using function declaration syntax. The prop type is appropriately defined using TypeScript.

Consider using a separate interface for the props to improve reusability and maintainability:

interface WorkspaceDraftLayoutProps {
  children: React.ReactNode;
}

export default function WorkspaceDraftLayout({ children }: WorkspaceDraftLayoutProps) {
  // ...
}

7-13: LGTM: Component render logic is clean and well-structured.

The component's render logic is clear and follows good practices:

  • Use of a fragment to avoid unnecessary DOM nesting
  • Logical structure with a header and content area
  • Good separation of concerns with a specific WorkspaceDraftHeader

For consistency, consider using self-closing tags for components without children:

<AppHeader header={<WorkspaceDraftHeader />} />

instead of:

<AppHeader header={<WorkspaceDraftHeader></WorkspaceDraftHeader>} />
web/core/hooks/store/workspace-draft/use-workspace-draft-issue.ts (2)

7-12: LGTM: Well-implemented custom hook with good error handling.

The useWorkspaceDraftIssues hook is correctly implemented, following React's conventions and best practices. It properly handles the case where the context is undefined, which is a good defensive programming approach.

Consider adding a type assertion for the context to improve type safety:

const context = useContext(StoreContext);
if (context === undefined) throw new Error("useWorkspaceDraftIssues must be used within StoreProvider");

return (context as { issue: { workspaceDraftIssues: IWorkspaceDraftIssues } }).issue.workspaceDraftIssues;

This change ensures that TypeScript knows the exact shape of the context object when it's defined, potentially catching errors earlier in the development process.


1-12: Great addition: Custom hook enhances code reusability and maintainability.

The introduction of useWorkspaceDraftIssues is a positive addition to the codebase. This custom hook encapsulates the logic for accessing workspace draft issues from the MobX store, promoting code reuse and separation of concerns. Its implementation follows React best practices and includes proper error handling.

As this hook is likely to be used across multiple components, consider the following to further improve its robustness and usefulness:

  1. Add unit tests to ensure the hook behaves correctly in various scenarios.
  2. Consider adding memoization if the returned data is complex or if you notice performance issues in components using this hook frequently.
  3. Document the hook's usage and any prerequisites (like required provider wrappers) in a comment above the function to aid other developers.
web/core/hooks/store/workspace-draft/use-workspace-draft-issue-filters.ts (1)

7-12: LGTM: Well-implemented custom hook with proper error handling.

The useWorkspaceDraftIssueFilters hook is correctly implemented, following React conventions and best practices. It properly accesses the context and includes error handling for incorrect usage.

A minor suggestion for improvement:

Consider making the error message more specific by mentioning the StoreProvider:

- throw new Error("useWorkspaceDraftIssueFilters must be used within StoreProvider");
+ throw new Error("useWorkspaceDraftIssueFilters must be used within a StoreProvider");

This change makes it clearer which provider is required.

web/core/components/issues/workspace-draft/loader.tsx (1)

13-19: LGTM! Component structure is well-implemented, with a minor optimization suggestion.

The JSX structure is clean and efficient. The use of Array constructor with map to render multiple ListLoaderItemRow components is a good approach.

Consider using Array.from() instead of [...Array(items)] for slightly better readability:

-      {[...Array(items)].map((_, index) => (
+      {Array.from({ length: items }).map((_, index) => (
         <ListLoaderItemRow key={index} />
       ))}

This change doesn't affect functionality but might be considered more idiomatic JavaScript.

web/app/[workspaceSlug]/(projects)/drafts/page.tsx (1)

8-25: LGTM: Component logic is well-structured. Consider adding type annotations.

The component logic is clean, easy to understand, and follows React and Next.js best practices. The early return for handling the case when workspaceSlug is not available is a good practice.

Consider adding type annotations to improve type safety:

- const WorkspaceDraftPage = () => {
+ const WorkspaceDraftPage: React.FC = () => {
  // ...
- const workspaceSlug = (routeWorkspaceSlug as string) || undefined;
+ const workspaceSlug = routeWorkspaceSlug ? String(routeWorkspaceSlug) : undefined;

This change ensures that workspaceSlug is always of type string | undefined, improving type safety.

web/core/components/issues/issue-layouts/list/list-view-types.d.ts (1)

12-12: LGTM! Consider adding a brief JSDoc comment.

The addition of handleMoveToIssues method is consistent with the existing interface structure and naming conventions. It's correctly defined as optional and returns a Promise, which aligns well with other handler methods.

Consider adding a brief JSDoc comment to describe the purpose of this method, for example:

/** Handles moving the issue to the main issues list */
handleMoveToIssues?: () => Promise<void>;

This would improve the self-documentation of the interface.

packages/types/src/issues/base.d.ts (1)

Line range hint 28-28: LGTM with a minor suggestion: Consider a more specific name

The TIssues type is well-defined as a union of TGroupedIssues and TSubGroupedIssues, allowing for flexibility in representing issues. However, the name TIssues might be slightly ambiguous as it doesn't immediately convey the grouped nature of the type.

Consider renaming to TGroupedOrSubGroupedIssues for more clarity, although this is a minor suggestion and the current name is acceptable.

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

Line range hint 24-24: Consider addressing the TODO comment.

There's an existing TODO comment on line 24 about removing an export after development. While not directly related to your current changes, it might be worth considering if this TODO can be addressed in this PR or if it should be tracked for future cleanup.

Would you like me to create a GitHub issue to track this TODO for future cleanup?

web/core/components/issues/workspace-draft/empty-state.tsx (2)

17-22: LGTM: CreateUpdateIssueModal is well-implemented with a minor suggestion.

The modal component is correctly implemented with appropriate props. For improved type safety, consider using a boolean literal type for the isDraft prop:

isDraft={true as const}

This ensures that the prop is always true for this usage, which aligns with the component's purpose of creating draft issues.


15-33: LGTM: Overall component structure is well-implemented with a minor suggestion.

The component structure, including the use of Fragment and the EmptyState implementation, is well-done. For consistency and to avoid potential issues with automatic semicolon insertion, consider adding a semicolon after the component's closing curly brace:

export const WorkspaceDraftEmptyState: FC = () => {
  // ... component implementation ...
};

This follows a common style guide practice and can prevent subtle bugs in certain situations.

packages/types/src/workspace-draft-issues/base.d.ts (4)

3-29: LGTM! Consider using a more specific type for date fields.

The TWorkspaceDraftIssue type is well-defined and comprehensive. It covers various aspects of a draft issue, including identifiers, state, priority, assignments, and timestamps.

Consider using a more specific type for date fields (e.g., start_date, target_date, completed_at, created_at, updated_at) instead of string | undefined. You could use Date | string | undefined to allow for both Date objects and string representations, improving type safety and flexibility.


31-44: LGTM! Consider refining the extra_stats field.

The TWorkspaceDraftPaginationInfo<T> type is well-structured and covers essential pagination information. The use of a generic type parameter T allows for flexibility in the type of paginated results.

Consider refining the extra_stats field. Currently, it's typed as string | undefined, which is quite generic. If possible, define a more specific type or interface for extra_stats to provide better type safety and documentation of its expected structure.


46-49: LGTM! Consider future extensibility of query parameters.

The TWorkspaceDraftQueryParams type provides basic pagination parameters, which is good for simple use cases.

Consider the potential need for additional query parameters in the future. You might want to make this type more extensible by either:

  1. Adding an optional additionalParams field of type Record<string, unknown>, or
  2. Using a mapped type with optional properties for known parameters.

This would allow for easier addition of new query parameters without breaking existing code.


51-61: LGTM! Consider removing 'undefined' from the union type.

The TWorkspaceDraftIssueLoader type effectively captures various loading states for draft issues, which is crucial for managing UI states and user feedback.

Consider removing undefined from the union type. Having undefined as a possible value might lead to ambiguous states. If you need to represent a "not set" or "initial" state, it's often clearer to use an explicit string literal like "initial" or "not-set" instead of undefined. This approach can help prevent potential bugs and improve type safety.

web/app/[workspaceSlug]/(projects)/drafts/header.tsx (2)

19-28: Consider using a more descriptive variable name for authorization check.

The permissions check is implemented correctly. However, to improve code readability, consider renaming isAuthorizedUser to something more specific, such as canCreateDraftIssue. This would make the purpose of the check more immediately clear to other developers.

Here's a suggested change:

-  const isAuthorizedUser = allowPermissions(
+  const canCreateDraftIssue = allowPermissions(
     [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
     EUserPermissionsLevel.WORKSPACE
   );

38-61: Consider extracting the button's onClick handler to a separate function.

The header rendering and button implementation look good overall. The conditional disabling of the button based on user permissions is a good security practice, and the responsive text is a nice touch for better mobile experience.

However, to improve code maintainability and make it easier to add potential logic in the future, consider extracting the button's onClick handler to a separate function.

Here's a suggested change:

+  const handleCreateDraftIssue = () => {
+    setIsDraftIssueModalOpen(true);
+    // Any additional logic can be added here in the future
+  };

   // ... (rest of the component)

   <Button
     variant="primary"
     size="sm"
     className="items-center gap-1"
-    onClick={() => setIsDraftIssueModalOpen(true)}
+    onClick={handleCreateDraftIssue}
-    disabled={!isAuthorizedUser}
+    disabled={!canCreateDraftIssue}
   >
     Draft <span className="hidden sm:inline-block">issue</span>
   </Button>

This change also incorporates the previously suggested variable name change for consistency.

web/core/components/workspace/sidebar/quick-actions.tsx (1)

Residual References Found After Code Removal

The removal of the last drafted issue button in quick-actions.tsx has left several references to workspaceDraftIssue and removeWorkspaceDraftIssue across the codebase:

  • web/core/store/issue/root.store.ts
  • web/core/hooks/use-issues-actions.tsx
  • web/core/hooks/store/use-issues.ts
  • web/core/hooks/store/workspace-draft/use-workspace-draft-issue.ts
  • web/core/hooks/store/workspace-draft/use-workspace-draft-issue-filters.ts

Action Items:

  1. Cleanup Unused Code:

    • Remove or update the unused variables and functions related to workspaceDraftIssue and removeWorkspaceDraftIssue in the aforementioned files.
  2. Verify Feature Deprecation:

    • Ensure that the removal aligns with the PR's objectives and that this feature is intended to be deprecated.
  3. Update Documentation:

    • If the feature is permanently removed, update any related documentation or user guides to reflect this change.
  4. Run Tests:

    • Execute relevant tests to confirm that the removal does not negatively impact other functionalities.
🔗 Analysis chain

Line range hint 105-130: Removal of last drafted issue button: Clarification needed

The code for rendering the last drafted issue button has been commented out. While this simplifies the component, it also removes functionality that might be valuable to users.

  1. Could you please clarify the rationale behind removing this feature? Does it align with the PR objectives or is it part of a larger redesign?

  2. If this feature is being permanently removed:
    a. Consider cleaning up unused code, such as the workspaceDraftIssue variable and the removeWorkspaceDraftIssue function.
    b. Update any related documentation or user guides that might reference this feature.

  3. If this is a temporary change or part of a phased approach, consider adding a TODO comment explaining the plan for this functionality.

To ensure there are no lingering references to this removed feature, you can run the following command:

This will help identify any other places in the codebase that might need to be updated following this change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for references to workspaceDraftIssue or removeWorkspaceDraftIssue
rg 'workspaceDraftIssue|removeWorkspaceDraftIssue' --type typescript --type tsx

Length of output: 116


Script:

#!/bin/bash
# Search for references to workspaceDraftIssue or removeWorkspaceDraftIssue
rg 'workspaceDraftIssue|removeWorkspaceDraftIssue' -t ts -t tsx

Length of output: 93


Script:

#!/bin/bash
# Search for references to workspaceDraftIssue or removeWorkspaceDraftIssue in .ts and .tsx files
rg 'workspaceDraftIssue|removeWorkspaceDraftIssue' -g '*.ts' -g '*.tsx'

Length of output: 2031

web/core/components/issues/issue-layouts/list/base-list-root.tsx (2)

28-29: LGTM! Consider adding comments for new store types.

The addition of EIssuesStoreType.ARCHIVED and EIssuesStoreType.WORKSPACE_DRAFT to ListStoreType is appropriate and aligns with the PR objectives. This expansion allows for more versatile issue management.

Consider adding brief comments explaining the purpose of these new store types to improve code readability and maintainability.


127-129: LGTM! Consider using object spread for clarity.

The changes to the handleCollapsedGroups function improve code readability and type safety. The multi-line formatting of the updateFilters call and the explicit type annotation are good practices.

For even better clarity, consider using object spread syntax:

updateFilters(projectId?.toString() ?? "", EIssueFilterType.KANBAN_FILTERS, {
  ...issuesFilter?.issueFilters?.kanbanFilters,
  group_by: collapsedGroups,
} as TIssueKanbanFilters);

This approach ensures that any existing properties in kanbanFilters are preserved while updating group_by.

web/core/constants/dashboard.ts (1)

332-339: LGTM: New "Drafts" menu item added correctly.

The new "Drafts" menu item has been added to the SIDEBAR_USER_MENU_ITEMS array with appropriate properties. The structure is consistent with other menu items, and the access permissions are set correctly for ADMIN and MEMBER roles.

Minor suggestion for consistency:

Consider updating the href property to be consistent with other menu items that use template literals:

-    href: `/drafts`,
+    href: `/drafts`,

This change doesn't affect functionality but maintains consistency with other menu items.

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

117-119: LGTM: Class implementation updated to support workspace draft issues.

The addition of workspaceDraftIssuesFilter and workspaceDraftIssues properties to the IssueRootStore class, along with their initialization in the constructor, properly implements the interface changes. This ensures that the store can handle workspace draft issues as intended.

Consider grouping related properties and their initializations together for better code organization. For example, you could move the workspaceDraftIssues* properties next to the workspaceIssues* properties in both the class declaration and the constructor.

Also applies to: 200-202

web/core/components/issues/issue-modal/form.tsx (1)

410-418: LGTM: Submit button text update for draft issues

The submit button text now correctly includes "Create draft issue" when creating a new draft, which is consistent with the title changes and provides clear feedback to the user about the action they're taking.

Consider adjusting the indentation for better readability:

 {data?.id
   ? isSubmitting
     ? "Updating"
     : "Update"
   : isSubmitting
     ? "Creating"
-    : isDraft
-      ? "Create draft issue"
-      : "Create"}
+    : isDraft
+    ? "Create draft issue"
+    : "Create"}

This change aligns the indentation of the nested ternary operators, making the code structure more apparent.

web/core/components/issues/issue-layouts/properties/all-properties.tsx (3)

Line range hint 4-4: Address TODO comment: Add tests

There's a TODO comment about adding tests. It's important to ensure proper test coverage for the component. Consider implementing the required tests to improve the overall quality and maintainability of the code.


Line range hint 325-330: Remove commented-out code

There's a commented-out router.push call. If this code is no longer needed, it should be removed to keep the codebase clean and prevent confusion. If it's kept for future reference, consider adding a comment explaining why it's being preserved.


Line range hint 1-577: Consider component decomposition

The IssueProperties component is quite large and complex, handling multiple properties and actions. Consider breaking it down into smaller, more focused components to improve readability, maintainability, and reusability. This could involve creating separate components for different sections of the issue properties or extracting some of the logic into custom hooks.

web/core/components/workspace/sidebar/projects-list-item.tsx (1)

Line range hint 431-440: Remove commented code for better maintainability

The "Draft issues" menu item has been commented out. To improve code cleanliness and maintainability, it's recommended to remove commented-out code entirely rather than leaving it in the codebase. This aligns with the previous review comment as well.

Please remove the commented-out code block for the "Draft issues" menu item. If this functionality needs to be preserved for future reference, consider documenting it in a separate file or in the project's documentation.

-  {/* {isAuthorized && (
-    <CustomMenu.MenuItem>
-      <Link href={`/${workspaceSlug}/projects/${project?.id}/draft-issues/`}>
-        <div className="flex items-center justify-start gap-2">
-          <PenSquare className="h-3.5 w-3.5 stroke-[1.5] text-custom-text-300" />
-          <span>Draft issues</span>
-        </div>
-      </Link>
-    </CustomMenu.MenuItem>
-  )} */}
apiserver/plane/utils/paginator.py (2)

Line range hint 391-391: Remove debug print statement

The print statement on line 391 should be removed before merging to production. Leaving debug statements in production code can lead to unnecessary console output and potential performance issues.

Remove the following line:

print(limit, "limit")

Line range hint 1-831: Summary of review findings

  1. Several debug print statements were added throughout the file. These should be removed or replaced with proper logging before merging to production.

  2. A change in the OffsetPaginator's slicing logic (lines 154-155) needs careful review, as it might lead to unexpected behavior.

  3. No other significant issues were found in the changes.

Consider implementing a consistent logging strategy across the project to facilitate debugging without relying on print statements. This could involve:

  1. Setting up a logging configuration that can be easily adjusted for different environments (development, staging, production).
  2. Using appropriate log levels (DEBUG, INFO, WARNING, ERROR) throughout the code.
  3. Including relevant context in log messages to aid in troubleshooting.

Example:

import logging

logger = logging.getLogger(__name__)

class OffsetPaginator:
    def get_result(self, limit=1000, cursor=None):
        logger.debug(f"get_result called with limit={limit}, cursor={cursor}")
        # ... rest of the method

This approach will make it easier to manage debug output and troubleshoot issues in various environments.

web/core/constants/empty-state.ts (2)

109-109: LGTM! Consider adding a more specific path.

The addition of the WORKSPACE_DRAFT_ISSUES enum and its corresponding entry in emptyStateDetails is well-structured and consistent with the existing pattern. Good job!

Consider making the path property more specific. Instead of /empty-state/workspace-draft/issue, you might want to use something like /empty-state/workspace/draft-issues to maintain consistency with other workspace-related paths.

Also applies to: 762-772


Line range hint 1-772: Consider refactoring for improved maintainability and consistency.

While the current implementation works, there are a few areas where we could improve maintainability and consistency:

  1. File length: This file is quite long. Consider splitting it into smaller, more focused files (e.g., one for enums, one for details).

  2. Reduce duplication: There's some repetition in descriptions and titles. Consider using variables or functions to generate common parts of these strings.

  3. String consistency: Standardize on either string literals or template literals for multi-line strings throughout the file.

  4. Type safety: The use of as const is good for type safety. Consider using TypeScript's satisfies operator for additional type checking.

Here's a small example of how you might reduce duplication:

const createEmptyStateDetail = (
  key: EmptyStateType,
  title: string,
  description: string,
  path: string,
  buttonText: string,
  access: EUserPermissions[] = [EUserPermissions.ADMIN, EUserPermissions.MEMBER]
): EmptyStateDetails => ({
  key,
  title,
  description,
  path,
  primaryButton: { text: buttonText },
  accessType: "workspace",
  access,
});

// Usage:
[EmptyStateType.WORKSPACE_DRAFT_ISSUES]: createEmptyStateDetail(
  EmptyStateType.WORKSPACE_DRAFT_ISSUES,
  "No Draft Issues Yet",
  "There are no draft issues in your workspace right now. Begin by adding your first one.",
  "/empty-state/workspace/draft-issues",
  "Create draft issue"
),

This approach could help reduce repetition and make it easier to maintain consistent structures across different empty states.

web/core/components/issues/issue-layouts/filters/applied-filters/roots/workspace-draft-root.tsx (1)

18-18: Ensure the usage of useWorkspaceIssueProperties

The hook useWorkspaceIssueProperties(workspaceSlug); is called but its return value is not captured. If the hook returns data needed for the component, consider capturing and utilizing it. If it's used solely for side effects, ensure that this is intentional.

web/core/services/issue/workspace_draft.service.ts (1)

13-14: Specify a more precise type for the query parameter

In the getIssues method, the query parameter is currently typed as object. This is too general and doesn't provide type safety. Consider specifying a more precise type, such as Record<string, any>, or defining an interface that represents the expected query parameters.

Apply this diff:

-    query: object = {}
+    query: Record<string, any> = {}
web/core/components/issues/workspace-draft/root.tsx (4)

28-30: Refactor to avoid repeating the same condition in useSWR

The condition workspaceSlug && issueIds.length <= 0 is used twice in the useSWR call. Assigning it to a variable would improve readability and reduce repetition.

Apply this diff to refactor:

+    const shouldFetchIssues = workspaceSlug && issueIds.length === 0;

     useSWR(
-      workspaceSlug && issueIds.length <= 0 ? `WORKSPACE_DRAFT_ISSUES_${workspaceSlug}` : null,
-      workspaceSlug && issueIds.length <= 0 ? async () => await fetchIssues(workspaceSlug, "init-loader") : null
+      shouldFetchIssues ? `WORKSPACE_DRAFT_ISSUES_${workspaceSlug}` : null,
+      shouldFetchIssues ? async () => await fetchIssues(workspaceSlug, "init-loader") : null
     );

38-42: Simplify conditions by using issueIds.length === 0

Since array lengths cannot be negative, issueIds.length <= 0 can be replaced with issueIds.length === 0 for clarity.

Apply this diff to simplify the conditions:

-    if (loader === "init-loader" && issueIds.length <= 0) {
+    if (loader === "init-loader" && issueIds.length === 0) {

...

-    if (loader === "empty-state" && issueIds.length <= 0) return <WorkspaceDraftEmptyState />;
+    if (loader === "empty-state" && issueIds.length === 0) return <WorkspaceDraftEmptyState />;

51-53: Simplify condition: issueIds.length >= 0 is always true

The condition issueIds.length >= 0 will always be true because array lengths are never negative. You can simplify the ternary condition by removing this check.

Apply this diff to simplify the condition:

-      {loader === "pagination" && issueIds.length >= 0 ? (
+      {loader === "pagination" ? (

24-24: Unused variable issuesMap

The issuesMap variable is extracted from useWorkspaceDraftIssues() but is not used within the component. Consider removing it if it's not needed to keep the code clean.

Apply this diff to remove the unused variable:

-    const { loader, paginationInfo, fetchIssues, issuesMap, issueIds } = useWorkspaceDraftIssues();
+    const { loader, paginationInfo, fetchIssues, issueIds } = useWorkspaceDraftIssues();
web/core/components/issues/workspace-draft/delete-modal.tsx (2)

65-87: Handle cases when onSubmit is undefined.

Since onSubmit is optional, there should be a fallback or appropriate handling when it is not provided to prevent unexpected behavior.

Apply this diff to handle the absence of onSubmit:

if (onSubmit)
  await onSubmit()
    .then(() => {
      // success handling
    })
    .catch((errors) => {
      // error handling
    })
    .finally(() => onClose());
+else {
+  onClose();
+}

98-101: Correct the modal content formatting.

There's an unnecessary {""} in the modal content which might result in extra spacing or unintended rendering.

Apply this diff to clean up the content:

Are you sure you want to delete issue{" "}
<span className="break-words font-medium text-custom-text-100">{projectDetails?.identifier}</span>
- {""}? All of the data related to the issue will be permanently removed. This action cannot be undone.
+ ? All of the data related to the issue will be permanently removed. This action cannot be undone.
web/core/components/issues/issue-modal/draft-issue-layout.tsx (2)

Line range hint 54-54: Fix the variable naming to prevent overwriting

The variable usePathname is being reassigned, which overwrites the imported hook and may cause unexpected behavior.

Apply this diff to correct the variable name:

- const usePathname = usePathname();
+ const pathname = usePathname();

This change assigns the result of usePathname() to pathname, avoiding the conflict with the imported hook.


96-99: Simplify the name assignment in the payload

The current ternary expression can be simplified for better readability and maintainability.

Apply this diff to streamline the code:

 const payload = {
   ...changesMade,
-  name:
-    changesMade?.name && changesMade?.name?.trim() !== ""
-      ? changesMade.name?.trim()
-      : "Untitled",
+  name: changesMade?.name?.trim() || "Untitled",
   project_id: projectId,
 };

This uses the logical OR operator to assign name to the trimmed value or "Untitled" if the trimmed name is falsy.

web/core/components/issues/workspace-draft/draft-issue-block.tsx (3)

36-36: Remove unnecessary space in className

There's an extra space at the beginning of the className string.

Apply this change:

- <div id={`issue-${issue.id}`} className=" relative border-b border-b-custom-border-200 w-full cursor-pointer">
+ <div id={`issue-${issue.id}`} className="relative border-b border-b-custom-border-200 w-full cursor-pointer">

70-73: Remove commented-out code for cleaner codebase

Lines 70 and 72 contain commented-out properties. If these are no longer needed, consider removing them to keep the codebase clean.


100-102: Remove unused 'projectId' parameter in 'updateIssue' function

The projectId parameter is unused in the updateIssue function and can be removed for clarity.

Apply this change:

- updateIssue={async (projectId, issueId, data) => {
+ updateIssue={async (issueId, data) => {
    await updateIssue(workspaceSlug, issueId, data);
  }}
web/core/components/issues/workspace-draft/draft-issue-properties.tsx (4)

68-89: Reevaluate the necessity of useMemo for issueOperations

The issueOperations object is memoized using useMemo, but its dependencies include issue, which may change frequently. This might negate the performance benefits of memoization.

Consider defining issueOperations without useMemo if memoization does not provide significant benefits:

- const issueOperations = useMemo(
-   () => ({ ... }),
-   [workspaceSlug, issue, addCycleToIssue, addModulesToIssue]
- );
+ const issueOperations = {
+   ... // same operations
+ };

155-158: Review event handling in handleEventPropagation

The handleEventPropagation function both prevents the default action and stops propagation for all events. While stopping propagation might be necessary, preventing the default action could interfere with expected behaviors like form submissions or link navigation.

Assess whether e.preventDefault() is necessary, or if only e.stopPropagation() suffices:

const handleEventPropagation = (e: React.MouseEvent) => {
  e.stopPropagation();
- e.preventDefault();
};

243-244: Avoid assigning empty string to buttonClassName

In the MemberDropdown component, when issue.assignee_ids is empty or undefined, buttonClassName is set to an empty string. This might override default styles unintentionally.

Instead of using an empty string, consider setting buttonClassName conditionally only when needed:

- buttonClassName={issue.assignee_ids?.length > 0 ? "hover:bg-transparent px-0" : ""}
+ buttonClassName={issue.assignee_ids?.length > 0 ? "hover:bg-transparent px-0" : undefined}

55-55: Unnecessary string conversion of project_id

In the areEstimateEnabledByProjectId call, issue.project_id is converted to a string using toString(). If project_id is already a string, this conversion is redundant.

Simplify the code by removing the unnecessary conversion:

- areEstimateEnabledByProjectId(issue.project_id?.toString())
+ areEstimateEnabledByProjectId(issue.project_id)
apiserver/plane/app/views/workspace/draft.py (3)

Line range hint 159-162: Update @allow_permission decorator to reference DraftIssue in partial_update.

The @allow_permission decorator specifies model=Issue, but the partial_update method operates on DraftIssue instances. Updating the model to DraftIssue ensures correct permission checks.

Apply this diff:

 @allow_permission(
     allowed_roles=[ROLE.ADMIN, ROLE.MEMBER],
     creator=True,
-    model=Issue,
+    model=DraftIssue,
     level="WORKSPACE",
 )

Line range hint 190-193: Update @allow_permission decorator to reference DraftIssue in retrieve.

The @allow_permission decorator specifies model=Issue, but the retrieve method operates on DraftIssue instances. Updating the model to DraftIssue ensures correct permission checks.

Apply this diff:

 @allow_permission(
     allowed_roles=[ROLE.ADMIN],
     creator=True,
-    model=Issue,
+    model=DraftIssue,
     level="WORKSPACE",
 )

Line range hint 214-217: Update @allow_permission decorator to reference DraftIssue in destroy.

The @allow_permission decorator specifies model=Issue, but the destroy method operates on DraftIssue instances. Updating the model to DraftIssue ensures correct permission checks.

Apply this diff:

 @allow_permission(
     allowed_roles=[ROLE.ADMIN],
     creator=True,
-    model=Issue,
+    model=DraftIssue,
     level="WORKSPACE",
 )
web/core/hooks/use-issues-actions.tsx (1)

752-755: Simplify workspaceSlug usage in fetchIssues

Since workspaceSlug is already a string after applying .toString(), calling .toString() again is redundant. Consider removing the extra .toString() call.

Update the line as follows:

-return issues.fetchIssues(workspaceSlug.toString(), loadType, options);
+return issues.fetchIssues(workspaceSlug, loadType, options);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c1f881b and a9f4294.

📒 Files selected for processing (43)
  • apiserver/plane/app/views/workspace/draft.py (6 hunks)
  • apiserver/plane/utils/paginator.py (3 hunks)
  • packages/types/src/index.d.ts (1 hunks)
  • packages/types/src/issues/base.d.ts (1 hunks)
  • packages/types/src/workspace-draft-issues/base.d.ts (1 hunks)
  • web/app/[workspaceSlug]/(projects)/drafts/header.tsx (1 hunks)
  • web/app/[workspaceSlug]/(projects)/drafts/layout.tsx (1 hunks)
  • web/app/[workspaceSlug]/(projects)/drafts/page.tsx (1 hunks)
  • web/core/components/issues/issue-layouts/filters/applied-filters/roots/workspace-draft-root.tsx (1 hunks)
  • web/core/components/issues/issue-layouts/list/base-list-root.tsx (3 hunks)
  • web/core/components/issues/issue-layouts/list/default.tsx (2 hunks)
  • web/core/components/issues/issue-layouts/list/list-view-types.d.ts (1 hunks)
  • web/core/components/issues/issue-layouts/properties/all-properties.tsx (1 hunks)
  • web/core/components/issues/issue-layouts/quick-action-dropdowns/index.ts (1 hunks)
  • web/core/components/issues/issue-modal/base.tsx (8 hunks)
  • web/core/components/issues/issue-modal/draft-issue-layout.tsx (2 hunks)
  • web/core/components/issues/issue-modal/form.tsx (2 hunks)
  • web/core/components/issues/workspace-draft/delete-modal.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/draft-issue-block.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/draft-issue-properties.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/empty-state.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/index.ts (1 hunks)
  • web/core/components/issues/workspace-draft/loader.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/quick-action.tsx (1 hunks)
  • web/core/components/issues/workspace-draft/root.tsx (1 hunks)
  • web/core/components/workspace/sidebar/projects-list-item.tsx (2 hunks)
  • web/core/components/workspace/sidebar/quick-actions.tsx (2 hunks)
  • web/core/constants/dashboard.ts (2 hunks)
  • web/core/constants/empty-state.ts (2 hunks)
  • web/core/constants/issue.ts (1 hunks)
  • web/core/constants/workspace-drafts.ts (1 hunks)
  • web/core/hooks/store/index.ts (1 hunks)
  • web/core/hooks/store/use-issues.ts (3 hunks)
  • web/core/hooks/store/workspace-draft/index.ts (1 hunks)
  • web/core/hooks/store/workspace-draft/use-workspace-draft-issue-filters.ts (1 hunks)
  • web/core/hooks/store/workspace-draft/use-workspace-draft-issue.ts (1 hunks)
  • web/core/hooks/use-issues-actions.tsx (3 hunks)
  • web/core/services/issue/index.ts (1 hunks)
  • web/core/services/issue/workspace_draft.service.ts (1 hunks)
  • web/core/store/issue/root.store.ts (4 hunks)
  • web/core/store/issue/workspace-draft/filter.store.ts (1 hunks)
  • web/core/store/issue/workspace-draft/index.ts (1 hunks)
  • web/core/store/issue/workspace-draft/issue.store.ts (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • web/core/components/issues/issue-layouts/list/default.tsx
  • web/core/components/issues/workspace-draft/index.ts
  • web/core/hooks/store/workspace-draft/index.ts
  • web/core/store/issue/workspace-draft/index.ts
🧰 Additional context used
🪛 Biome
web/core/components/issues/workspace-draft/draft-issue-block.tsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

web/core/components/issues/workspace-draft/quick-action.tsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

web/core/hooks/store/use-issues.ts

[error] 85-85: Duplicate case label.

The first similar label is here:

(lint/suspicious/noDuplicateCase)

🪛 GitHub Check: lint-web
web/core/store/issue/workspace-draft/issue.store.ts

[failure] 20-20:
lodash import should occur before import of lodash/orderBy

🔇 Additional comments (50)
web/core/constants/workspace-drafts.ts (1)

1-6: LGTM! Well-structured enum implementation.

The EDraftIssuePaginationType enum is well-implemented, following TypeScript best practices. The naming conventions are correct, and the string values match the member names, which enhances clarity.

web/app/[workspaceSlug]/(projects)/drafts/layout.tsx (2)

1-4: LGTM: Directive and imports are well-structured.

The "use client" directive is correctly placed, and imports are appropriately organized. The use of destructuring in imports enhances code readability.


1-13: Overall assessment: Well-implemented layout component.

The WorkspaceDraftLayout component is well-structured and follows React best practices. It provides a clear and logical layout for workspace drafts, with good separation of concerns between the header and content areas. The use of TypeScript for prop types enhances code reliability.

Minor suggestions were made for improving prop type definitions and tag consistency, but these are not critical issues. The component is ready for use and should integrate well with the rest of the application.

web/core/services/issue/index.ts (1)

10-10: LGTM: New export statement is consistent with existing pattern.

The addition of export * from "./workspace_draft.service"; is in line with the file's structure and purpose. It correctly exposes the workspace draft service alongside other issue-related services, maintaining consistency and improving modularity.

web/core/hooks/store/workspace-draft/use-workspace-draft-issue.ts (1)

1-5: LGTM: Imports are correct and necessary.

The imports are well-organized and include all necessary dependencies for the hook's implementation. The use of absolute imports is consistent with the project's style.

web/core/hooks/store/workspace-draft/use-workspace-draft-issue-filters.ts (1)

1-5: LGTM: Imports are well-organized and appropriate.

The imports are correctly structured, using absolute imports for local modules and separating types. This approach enhances code readability and maintainability.

web/core/components/issues/workspace-draft/loader.tsx (2)

1-9: LGTM! Imports and type definition are well-structured.

The "use client" directive, imports, and type definition are correctly implemented. The optional items prop in the TWorkspaceDraftIssuesLoader type provides flexibility for the component's usage.


11-12: LGTM! Component declaration and props handling are well-implemented.

The component is correctly exported and typed. The props destructuring with a default value for items is a clean and effective approach.

web/app/[workspaceSlug]/(projects)/drafts/page.tsx (2)

1-6: LGTM: Imports and setup are well-structured.

The "use client" directive is correctly placed, and all necessary imports are present. The code follows Next.js and React best practices for importing components and hooks.


27-27: LGTM: Export statement is correct.

The default export of the WorkspaceDraftPage component is properly implemented.

packages/types/src/issues/base.d.ts (7)

Line range hint 13-18: LGTM: Well-defined loader type

The TLoader type is well-defined and covers various loading states, including an uninitialized state (undefined). The naming is clear and follows TypeScript conventions.


Line range hint 20-22: LGTM: Clear and appropriate grouping type

The TGroupedIssues type is well-defined for grouping issues by a string identifier. The use of an index signature is appropriate, and the naming clearly indicates the purpose of the type.


Line range hint 24-26: LGTM: Well-structured nested grouping type

The TSubGroupedIssues type is well-defined for nested grouping of issues. It effectively builds upon the TGroupedIssues type, demonstrating good use of composition. The naming clearly indicates the hierarchical nature of the grouping.


Line range hint 30-34: LGTM: Well-structured pagination data type

The TPaginationData type is well-defined with clear and self-explanatory property names. It includes essential information for pagination (next and previous cursors, and a flag for next page results). The type name accurately represents its purpose.


Line range hint 36-38: LGTM: Well-structured group-specific pagination data type

The TIssuePaginationData type is well-defined for storing group-specific pagination data. It effectively builds upon the TPaginationData type, demonstrating good use of composition. The naming clearly indicates its purpose of managing pagination data for grouped issues.


Line range hint 40-42: LGTM: Clear and appropriate grouped issue count type

The TGroupedIssueCount type is well-defined for storing the count of issues for each group. The use of an index signature is appropriate, and the naming clearly indicates the purpose of the type.


Line range hint 44-44: LGTM with a consideration: Simple ungrouped issues type

The TUnGroupedIssues type is clearly defined as an array of strings, representing a list of ungrouped issues. The naming accurately reflects its purpose.

Consider if this simple array structure will be sufficient for future needs. If there's a possibility that more information might be needed for each ungrouped issue in the future, it might be worth exploring a more structured approach. To verify the current usage and potential future needs, you could run the following script:

This script will help identify current usage patterns and any existing notes about potential changes to ungrouped issues handling.

✅ Verification successful

LGTM

The TUnGroupedIssues type is appropriately defined as an array of strings, and its usage within the codebase aligns with this structure. No TODO or FIXME comments related to ungrouped issues were found, indicating that the current implementation meets the requirements.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of TUnGroupedIssues and look for potential expansion points

# Search for usage of TUnGroupedIssues
echo "Usage of TUnGroupedIssues:"
rg --type typescript "TUnGroupedIssues"

# Look for TODO comments or FIXME related to ungrouped issues
echo "\nTODO or FIXME comments related to ungrouped issues:"
rg --type typescript -i "TODO|FIXME" -C 2 | rg -i "ungrouped.*issues"

Length of output: 361


Script:

#!/bin/bash
# Description: Check usage of TUnGroupedIssues and look for potential expansion points using glob patterns

# Search for usage of TUnGroupedIssues in .ts and .tsx files
echo "Usage of TUnGroupedIssues:"
rg "TUnGroupedIssues" --glob "*.ts" --glob "*.tsx"

# Look for TODO or FIXME comments related to ungrouped issues in .ts and .tsx files
echo "\nTODO or FIXME comments related to ungrouped issues:"
rg -i "TODO|FIXME" --glob "*.ts" --glob "*.tsx" -C 2 | rg -i "ungrouped.*issues"

Length of output: 707


Script:

#!/bin/bash
# Description: Further analyze TUnGroupedIssues usage and related structures

# Search for any types that are used alongside TUnGroupedIssues
echo "Types used with TUnGroupedIssues:"
rg "TUnGroupedIssues" --glob "*.ts" --glob "*.tsx" -A 2

# Check for interfaces or types that extend or utilize TUnGroupedIssues
echo "\nInterfaces or types extending TUnGroupedIssues:"
rg "extends .*TUnGroupedIssues" --glob "*.ts" --glob "*.tsx"

# Look for any functions or methods that manipulate TUnGroupedIssues
echo "\nFunctions or methods manipulating TUnGroupedIssues:"
rg "function .*\(.*TUnGroupedIssues.*\)" --glob "*.ts" --glob "*.tsx"

Length of output: 1393

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

32-32: LGTM: New export for workspace draft issues added.

The new export statement for "./workspace-draft-issues/base" has been correctly added, which aligns with the PR objectives for addressing workspace draft issues. This addition will make the types or interfaces related to workspace draft issues available for use in other parts of the project.

web/core/components/issues/workspace-draft/empty-state.tsx (2)

1-9: LGTM: Imports and "use client" directive are well-organized.

The "use client" directive is correctly placed, and imports are appropriately organized. This structure enhances readability and maintainability.


11-13: LGTM: Component declaration and state management are well-implemented.

The WorkspaceDraftEmptyState component is correctly declared as a functional component and exported. The use of the useState hook for managing the modal's visibility is appropriate and follows React best practices.

web/core/hooks/store/index.ts (1)

34-34: LGTM: New export follows existing pattern

The addition of export * from "./workspace-draft"; is consistent with the existing export pattern in this file. It appears to be a valid inclusion for a new module related to workspace drafts.

To ensure the exported module exists and is correctly implemented, let's verify its presence:

web/app/[workspaceSlug]/(projects)/drafts/header.tsx (2)

1-18: LGTM: Imports and component declaration are well-structured.

The use of the 'use client' directive, imports, and component declaration with MobX's observer are all appropriate for this client-side component.


32-37: LGTM: CreateUpdateIssueModal implementation is well-structured.

The modal implementation is correct and follows best practices. The use of a separate component for creating/updating issues promotes code reusability.

web/core/components/issues/issue-layouts/list/base-list-root.tsx (1)

65-67: LGTM! Improved code structure and type safety.

The changes to the BaseListRoot component are well-implemented:

  1. Destructuring updateFilters from useIssuesActions(storeType) improves code readability.
  2. The initialization of collapsedGroups with a fallback object enhances type safety and prevents potential runtime errors.

These refinements align with best practices for React and TypeScript development.

web/core/constants/dashboard.ts (1)

5-5: LGTM: Import statement updated correctly.

The PenSquare icon has been added to the import statement from lucide-react, which is consistent with its usage in the new "Drafts" menu item.

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

26-27: LGTM: Import statements are well-organized.

The consolidation of workspace-related imports and the addition of workspace draft issues imports improve code organization and readability. These changes align with the PR objectives of addressing workspace draft issues.


59-61: LGTM: Interface updated to support workspace draft issues.

The addition of workspaceDraftIssuesFilter and workspaceDraftIssues properties to the IIssueRootStore interface properly extends the store's capabilities to handle workspace draft issues. This change is consistent with the PR objectives.

web/core/constants/issue.ts (1)

33-33: LGTM! Verify usage of the new enum value.

The addition of WORKSPACE_DRAFT to EIssuesStoreType is consistent with the existing structure and aligns with the PR objectives. It expands the enum's capability to represent workspace-level draft issues.

To ensure proper integration, please verify the usage of this new enum value across the codebase:

✅ Verification successful

Verified: The WORKSPACE_DRAFT enum value is appropriately used across the codebase without any detected issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for usage of EIssuesStoreType.WORKSPACE_DRAFT

# Test: Look for direct usage of WORKSPACE_DRAFT
echo "Searching for direct usage of WORKSPACE_DRAFT:"
rg --type typescript --type javascript "EIssuesStoreType\.WORKSPACE_DRAFT"

# Test: Look for string literal "WORKSPACE_DRAFT" in case it's used without the enum
echo "Searching for string literal 'WORKSPACE_DRAFT':"
rg --type typescript --type javascript "'WORKSPACE_DRAFT'|\"WORKSPACE_DRAFT\""

# Test: Look for potential switch statements or if-else chains handling EIssuesStoreType
echo "Searching for potential switch statements or if-else chains:"
rg --type typescript --type javascript "switch.*EIssuesStoreType|case.*:"

Length of output: 687


Script:

#!/bin/bash
# Description: Search for usage of EIssuesStoreType.WORKSPACE_DRAFT

# Test: Look for direct usage of WORKSPACE_DRAFT
echo "Searching for direct usage of WORKSPACE_DRAFT:"
rg --type=ts --type=tsx --type=js --type=jsx "EIssuesStoreType\.WORKSPACE_DRAFT"

# Test: Look for string literal "WORKSPACE_DRAFT" in case it's used without the enum
echo "Searching for string literal 'WORKSPACE_DRAFT':"
rg --type=ts --type=tsx --type=js --type=jsx "'WORKSPACE_DRAFT'|\"WORKSPACE_DRAFT\""

# Test: Look for potential switch statements or if-else chains handling EIssuesStoreType
echo "Searching for potential switch statements or if-else chains:"
rg --type=ts --type=tsx --type=js --type=jsx "switch.*EIssuesStoreType|case.*:"

Length of output: 684


Script:

#!/bin/bash
# Description: Search for usage of EIssuesStoreType.WORKSPACE_DRAFT

# Test: Look for direct usage of WORKSPACE_DRAFT
echo "Searching for direct usage of WORKSPACE_DRAFT:"
rg --glob "*.ts" --glob "*.tsx" --glob "*.js" --glob "*.jsx" "EIssuesStoreType\.WORKSPACE_DRAFT"

# Test: Look for string literal "WORKSPACE_DRAFT" in case it's used without the enum
echo "Searching for string literal 'WORKSPACE_DRAFT':"
rg --glob "*.ts" --glob "*.tsx" --glob "*.js" --glob "*.jsx" "'WORKSPACE_DRAFT'|\"WORKSPACE_DRAFT\""

# Test: Look for potential switch statements or if-else chains handling EIssuesStoreType
echo "Searching for potential switch statements or if-else chains:"
rg --glob "*.ts" --glob "*.tsx" --glob "*.js" --glob "*.jsx" "switch.*EIssuesStoreType|case.*:"

Length of output: 27425

web/core/components/issues/issue-modal/form.tsx (2)

269-271: LGTM: Title update for draft issues

The title now correctly includes "Create draft" when isDraft is true, providing clear feedback to the user about the current action. This change enhances the user experience by differentiating between creating a regular issue and a draft issue.


Line range hint 1-418: Overall assessment: Draft issue handling implemented successfully

The changes to the IssueFormRoot component effectively implement the handling of draft issues. The modifications to the title display and submit button text provide clear feedback to users about whether they are creating a regular issue or a draft issue. These changes are well-integrated into the existing component and consistent with its overall structure.

A few key points:

  1. The title now includes "Create draft" when appropriate.
  2. The submit button text reflects the draft status when creating a new draft issue.
  3. The changes are minimal and focused, reducing the risk of introducing new bugs.

The implementation successfully addresses the requirements for draft issues while maintaining the existing functionality of the component.

web/core/components/issues/issue-layouts/properties/all-properties.tsx (1)

40-40: LGTM: Improved readability of updateIssue property

The refactoring of the updateIssue property in the IIssueProperties interface improves code readability by condensing the multiline declaration into a single line. This change maintains the same functionality while making the code more concise.

web/core/components/issues/workspace-draft/delete-modal.tsx (1)

45-46: Confirm that issue and currentUser are defined before use.

Ensure that issue and currentUser are not undefined or null to prevent potential runtime errors when accessing their properties.

Run the following script to check for null or undefined checks on issue and currentUser:

web/core/hooks/store/use-issues.ts (2)

28-31: Addition of WORKSPACE_DRAFT to TStoreIssues is correct

The WORKSPACE_DRAFT store type has been correctly added to TStoreIssues with appropriate type definitions.


80-84: Implementation of WORKSPACE_DRAFT case in useIssues function is correct

The WORKSPACE_DRAFT case has been properly added to the useIssues function, returning the merged store with the correct issues and issuesFilter.

web/core/components/issues/issue-modal/draft-issue-layout.tsx (1)

19-19: Ensure the new service is correctly integrated

The import statement for workspaceDraftService appears to be correct. Ensure that all previous references to IssueDraftService have been updated throughout the code to prevent any inconsistencies.

web/core/store/issue/workspace-draft/issue.store.ts (1)

66-66: Consider extending the base issues store for consistency

As previously mentioned, this class should extend the base issues store and utilize its pagination methods to adhere to the established pattern in the codebase. This helps avoid code duplication and ensures consistency across stores.

web/core/components/issues/workspace-draft/draft-issue-properties.tsx (3)

85-86: Confirm cycle removal logic in removeIssueFromCycle

There's a TODO comment // TODO: To be checked in the removeIssueFromCycle function. Please verify that setting the cycle ID to an empty string ("") correctly removes the issue from the cycle. Depending on the backend implementation, you might need to pass null or omit the field entirely to properly remove the cycle association.


145-146: Handle cases where issue.project_id is undefined

The component returns null if !issue.project_id. This could lead to the component not rendering when project_id is undefined or null. Ensure that this is the intended behavior and that the parent component handles this scenario appropriately.


255-266: ⚠️ Potential issue

Conditional rendering of ModuleDropdown may cause layout shifts

The ModuleDropdown is conditionally rendered based on projectDetails?.module_view. This could lead to layout shifts if projectDetails updates after the initial render.

Consider rendering a placeholder or reserving space to prevent layout shifts while projectDetails is loading:

{projectDetails ? (
  projectDetails.module_view && (
    <div className="h-5" onClick={handleEventPropagation}>
      {/* ModuleDropdown component */}
    </div>
  )
) : (
  // Placeholder or loading indicator
  <div className="h-5" />
)}

Likely invalid or redundant comment.

apiserver/plane/app/views/workspace/draft.py (1)

Line range hint 49-88: Great refactoring with the get_queryset method.

Centralizing the queryset logic in the get_queryset method enhances maintainability and reduces code redundancy across the viewset methods.

web/core/components/issues/issue-modal/base.tsx (6)

53-53: Update store type to EIssuesStoreType.WORKSPACE_DRAFT is appropriate.

Changing the store type to EIssuesStoreType.WORKSPACE_DRAFT ensures that the component interacts with the correct draft issues store, which aligns with the updated logic for managing workspace draft issues.


73-75: Setting description when issue details are not fetched is correct.

When fetchIssueDetails is false or other conditions are met, setting the description from data?.description_html or a default <p></p> ensures that the description field is populated appropriately in the absence of fetched issue details.


215-216: Confirm createMore functionality enhances user experience.

The logic correctly handles closing the modal or focusing on the issue title field based on the createMore flag, allowing users to efficiently create multiple issues in succession.


316-316: Passing isDraft flag to handleFormSubmit ensures correct handling.

By passing the isDraft flag to handleFormSubmit, the submission logic correctly differentiates between draft and regular issues, which is essential for proper issue handling in DraftIssueLayout.


334-334: Verify isDraft usage in IssueFormRoot submission.

In the IssueFormRoot component, passing isDraft to handleFormSubmit might not be necessary if it's intended for non-draft issues. Ensure that isDraft accurately reflects the issue type to prevent unintended behavior.

Consider reviewing the isDraft flag usage to confirm it aligns with the expected submission process for regular issues.


156-156: ⚠️ Potential issue

Adjust condition to allow creating draft issues without a project ID.

The current precondition if (!workspaceSlug || !payload.project_id) return; prevents creating draft issues when payload.project_id is undefined. Since draft issues may not require a project ID, consider modifying the condition to allow draft issue creation without it.

Apply this diff to adjust the condition:

-    if (!workspaceSlug || !payload.project_id) return;
+    if (!workspaceSlug || (!payload.project_id && !is_draft_issue)) return;

This change ensures that draft issues can be created even if payload.project_id is not provided.

Likely invalid or redundant comment.

web/core/hooks/use-issues-actions.tsx (4)

48-48: Importing workspaceDraftIssueActions

The addition of workspaceDraftIssueActions integrates well with the existing actions.


65-66: Adding WORKSPACE_DRAFT case to the switch statement

Including EIssuesStoreType.WORKSPACE_DRAFT ensures that the correct actions are returned for workspace draft issues.


758-762: Consistent dependency arrays in useCallback hooks

Similar to fetchIssues, verify that all useCallback hooks include all necessary dependencies, such as specific functions from issues.

Review the dependency arrays of all useCallback hooks in this hook to ensure completeness. Consider using ESLint's exhaustive-deps rule to automate this verification.


746-748: Handle potential absence of globalViewId

In the useWorkspaceDraftIssueActions hook, globalViewId is derived from useParams(). Ensure that the absence of globalViewId is appropriately handled if it's essential for any operations.

Confirm whether globalViewId is required in this context and add necessary checks or remove it if unnecessary.

Comment on lines +11 to +20
export const WorkspaceDraftIssuesLoader: FC<TWorkspaceDraftIssuesLoader> = (props) => {
const { items = 14 } = props;
return (
<div className="relative h-full w-full">
{[...Array(items)].map((_, index) => (
<ListLoaderItemRow key={index} />
))}
</div>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider enhancing accessibility and customization options.

While the component effectively renders a loading state, consider the following enhancements:

  1. Improve accessibility by adding an aria-label to the container div:
-    <div className="relative h-full w-full">
+    <div className="relative h-full w-full" aria-label="Loading workspace draft issues">
  1. To increase flexibility, you might want to allow customization of individual ListLoaderItemRow components. This could be achieved by accepting a render prop:
type TWorkspaceDraftIssuesLoader = {
  items?: number;
  renderItem?: (index: number) => React.ReactNode;
};

export const WorkspaceDraftIssuesLoader: FC<TWorkspaceDraftIssuesLoader> = (props) => {
  const { items = 14, renderItem } = props;
  return (
    <div className="relative h-full w-full" aria-label="Loading workspace draft issues">
      {Array.from({ length: items }).map((_, index) => (
        renderItem ? renderItem(index) : <ListLoaderItemRow key={index} />
      ))}
    </div>
  );
};

This change would allow users of the component to customize the appearance of individual loader items if needed, while still providing a default implementation.

Comment on lines +153 to 155
print(limit, "limit")
if cursor.value != limit:
results = results[-(limit + 1) :]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove debug print and review slicing logic

  1. The print statement on line 153 should be removed before merging to production.

  2. The modification to the slicing logic on lines 154-155 needs careful review:

    if cursor.value != limit:
        results = results[-(limit + 1):]

    This change might lead to unexpected behavior if cursor.value is significantly different from limit. It could potentially return fewer results than expected or cause issues with pagination consistency.

Consider removing the print statement and reverting the slicing logic to its previous implementation unless there's a specific reason for this change that's not apparent from the context provided.

@@ -761,7 +761,7 @@
):
"""Paginate the request"""
per_page = self.get_per_page(request, default_per_page, max_per_page)

print(per_page, "per_page")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace debug prints with proper logging

There are two print statements added for debugging purposes:

  1. Line 764: print(per_page, "per_page")
  2. Line 791: print(per_page, "per_page 2")

These should be removed or replaced with proper logging before merging to production.

Replace the print statements with appropriate logging:

import logging

logger = logging.getLogger(__name__)

# ... (in the paginate method)
logger.debug(f"Initial per_page value: {per_page}")

# ... (before calling paginator.get_result)
logger.debug(f"per_page value before get_result: {per_page}")

This approach allows for better control over log levels and output in different environments.

Also applies to: 791-791

return allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid unnecessary .toString() on workspaceSlug

The workspaceSlug variable is already a string returned from useParams(), so calling .toString() is unnecessary and could lead to errors if workspaceSlug is undefined.

Consider removing the .toString() call:

     EUserPermissionsLevel.PROJECT,
-    workspaceSlug.toString(),
+    workspaceSlug,
     projectId
📝 Committable suggestion

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

Suggested change
workspaceSlug.toString(),
workspaceSlug,

Comment on lines +23 to +31
(projectId: string | undefined) => {
if (!projectId) return false;
return allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
projectId
);
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential undefined values for workspaceSlug

There is no check to ensure that workspaceSlug is defined before using it in canEditProperties. If workspaceSlug can be undefined, this may lead to runtime errors.

Consider adding a check for workspaceSlug:

     (projectId: string | undefined) => {
+      if (!workspaceSlug) return false;
       if (!projectId) return false;
       return allowPermissions(
📝 Committable suggestion

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

Suggested change
(projectId: string | undefined) => {
if (!projectId) return false;
return allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
projectId
);
},
(projectId: string | undefined) => {
if (!workspaceSlug) return false;
if (!projectId) return false;
return allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
projectId
);
},

Comment on lines +239 to +240
if (isDraft) await draftIssues.updateIssue(workspaceSlug.toString(), data.id, payload);
else if (updateIssue) await updateIssue(payload.project_id, data.id, payload);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Modify condition to allow updating draft issues without a project ID.

In handleUpdateIssue, the condition if (!workspaceSlug || !payload.project_id || !data?.id) return; can prevent updating draft issues when payload.project_id is undefined. Since draft issues may not have a project ID, adjust the condition to accommodate this scenario.

Apply this diff to adjust the condition:

-    if (!workspaceSlug || !payload.project_id || !data?.id) return;
+    if (!workspaceSlug || (!payload.project_id && !isDraft) || !data?.id) return;

This ensures that draft issues can be updated even if payload.project_id is not specified.

Committable suggestion was skipped due to low confidence.

Comment on lines +756 to +757
[workspaceSlug, issues]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure all dependencies are included in useCallback

In the dependency array of the fetchIssues useCallback, issues.fetchIssues should be included to ensure that the callback updates appropriately when issues.fetchIssues changes.

Update the dependency array:

-[workspaceSlug, issues]
+[workspaceSlug, issues.fetchIssues]
📝 Committable suggestion

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

Suggested change
[workspaceSlug, issues]
);
[workspaceSlug, issues.fetchIssues]
);

Comment on lines +787 to +792
async (workspaceSlug: string, issueId: string, data: Partial<TIssue>) => {
if (!workspaceSlug || !issueId || !data) return;
return await issues.moveToIssues(workspaceSlug, issueId, data);
},
[issues]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor moveToIssue function parameter

The moveToIssue function accepts workspaceSlug as a parameter, which is unnecessary since workspaceSlug is already available in the scope. Additionally, to maintain consistency with other functions, consider removing workspaceSlug from the parameters.

Refactor the function as follows:

-async (workspaceSlug: string, issueId: string, data: Partial<TIssue>) => {
+async (issueId: string, data: Partial<TIssue>) => {
   if (!workspaceSlug || !issueId || !data) return;
   return await issues.moveToIssues(workspaceSlug, issueId, data);
},

Ensure to update the dependency array and any calls to this function accordingly.

Committable suggestion was skipped due to low confidence.

Comment on lines +794 to +805
const updateFilters = useCallback(
async (
projectId: string,
filterType: EIssueFilterType,
filters: IIssueFilterOptions | IIssueDisplayFilterOptions | IIssueDisplayProperties | TIssueKanbanFilters
) => {
filters = filters as IIssueFilterOptions | IIssueDisplayFilterOptions | IIssueDisplayProperties;
if (!globalViewId || !workspaceSlug) return;
return await issuesFilter.updateFilters(workspaceSlug, filterType, filters);
},
[globalViewId, workspaceSlug, issuesFilter]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Eliminate unnecessary projectId parameter in updateFilters

The updateFilters function includes a projectId parameter that is not utilized within the function. Removing this parameter will streamline the function signature.

Apply this change to remove the unused projectId parameter:

-async (
-  projectId: string,
   filterType: EIssueFilterType,
   filters: IIssueFilterOptions | IIssueDisplayFilterOptions | IIssueDisplayProperties | TIssueKanbanFilters
 ) => {
   if (!globalViewId || !workspaceSlug) return;
   return await issuesFilter.updateFilters(workspaceSlug, filterType, filters);
},

Committable suggestion was skipped due to low confidence.

Comment on lines +744 to +819
const useWorkspaceDraftIssueActions = () => {
// router
const { workspaceSlug: routerWorkspaceSlug, globalViewId: routerGlobalViewId } = useParams();
const workspaceSlug = routerWorkspaceSlug?.toString();
const globalViewId = routerGlobalViewId?.toString();
// store hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.WORKSPACE_DRAFT);
const fetchIssues = useCallback(
async (loadType: TLoader, options: IssuePaginationOptions) => {
if (!workspaceSlug) return;
return issues.fetchIssues(workspaceSlug.toString(), loadType, options);
},
[workspaceSlug, issues]
);

const fetchNextIssues = useCallback(async () => {
if (!workspaceSlug) return;
return issues.fetchNextIssues(workspaceSlug.toString());
}, [workspaceSlug, issues]);

const createIssue = useCallback(
async (projectId: string | undefined | null, data: Partial<TIssue>) => {
if (!workspaceSlug || !projectId) return;
return await issues.createWorkspaceDraftIssue(workspaceSlug, data);
},
[issues, workspaceSlug]
);
const updateIssue = useCallback(
async (projectId: string | undefined | null, issueId: string, data: Partial<TIssue>) => {
if (!workspaceSlug || !projectId) return;
return await issues.updateWorkspaceDraftIssue(workspaceSlug, issueId, data);
},
[issues, workspaceSlug]
);
const removeIssue = useCallback(
async (projectId: string | undefined | null, issueId: string) => {
if (!workspaceSlug || !projectId) return;
return await issues.deleteWorkspaceDraftIssue(workspaceSlug, issueId);
},
[issues, workspaceSlug]
);

const moveToIssue = useCallback(
async (workspaceSlug: string, issueId: string, data: Partial<TIssue>) => {
if (!workspaceSlug || !issueId || !data) return;
return await issues.moveToIssues(workspaceSlug, issueId, data);
},
[issues]
);

const updateFilters = useCallback(
async (
projectId: string,
filterType: EIssueFilterType,
filters: IIssueFilterOptions | IIssueDisplayFilterOptions | IIssueDisplayProperties | TIssueKanbanFilters
) => {
filters = filters as IIssueFilterOptions | IIssueDisplayFilterOptions | IIssueDisplayProperties;
if (!globalViewId || !workspaceSlug) return;
return await issuesFilter.updateFilters(workspaceSlug, filterType, filters);
},
[globalViewId, workspaceSlug, issuesFilter]
);

return useMemo(
() => ({
fetchIssues,
fetchNextIssues,
createIssue,
updateIssue,
removeIssue,
updateFilters,
moveToIssue,
}),
[fetchIssues, fetchNextIssues, createIssue, updateIssue, removeIssue, updateFilters, moveToIssue]
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused parameter projectId in functions

In the useWorkspaceDraftIssueActions hook, the functions createIssue, updateIssue, and removeIssue accept projectId as a parameter, but it is not used within these functions. Removing the unused projectId parameter will clean up the code and prevent potential confusion.

Apply this diff to remove the unused projectId parameter:

-async (projectId: string | undefined | null, data: Partial<TIssue>) => {
+async (data: Partial<TIssue>) => {
   if (!workspaceSlug) return;
   return await issues.createWorkspaceDraftIssue(workspaceSlug, data);
},

Repeat the same change for updateIssue and removeIssue functions.

Committable suggestion was skipped due to low confidence.

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.

5 participants