[PE-182] refactor: pages' components and store for scalability#6283
[PE-182] refactor: pages' components and store for scalability#6283
Conversation
WalkthroughThis pull request introduces comprehensive changes across multiple files, focusing on refactoring type definitions and improving type safety for pages, editors, and search functionalities. The modifications primarily involve updating type imports, restructuring page-related types, and enhancing the handling of page configurations and permissions. Key changes include introducing Changes
Sequence DiagramsequenceDiagram
participant Client
participant PageStore
participant PageService
participant PageInstance
Client->>PageStore: Request Page Data
PageStore->>PageService: Fetch Page Details
PageService-->>PageStore: Return Page Data
PageStore->>PageInstance: Create Page Instance
PageInstance-->>PageStore: Initialize Page
PageStore-->>Client: Return Page Instance
Suggested Labels
Suggested Reviewers
Poem
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command 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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (20)
web/core/components/pages/editor/title.tsx (1)
37-47: Enhanced read-only rendering.
UsinggetPageName(title)in read-only mode ensures a standardized display of the title. The conditional class for!titleis a neat UI cue for missing titles. Consider adding fallback text (e.g. "Untitled") if you need to differentiate between "empty but user-provided" and "null/undefined" cases.web/core/components/pages/editor/page-root.tsx (2)
11-18: Consolidate imports if necessary
The grouped import from"@/components/pages"is clear. If these components are frequently imported together, this approach is fine. Otherwise, consider separating them into more focused imports to limit confusion for new contributors.
76-78: Consider using await over promise chaining
While promise chaining with.then()is valid, usingasync/awaitconsistently may improve readability and error handling.web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx (2)
23-30: Store & service dependencies
Importing hooks (useProjectPage,useProjectPages,useWorkspace) and creating new service instances (WorkspaceService,FileService,ProjectPageService,ProjectPageVersionService) indicates a well-structured approach. Avoid duplicating service objects unnecessarily if possible.
68-94: Comprehensive pageRootHandlers
This block defines creation, version fetching, fetchEntity, description updates, and redirection logic. The approach cleans up the main component. Consider adding stronger error-handling or loading states for each handler.web/core/store/pages/project-page.ts (1)
8-10: Root store references
Dependency onRootStorefrom@/plane-web/store/root.storecan be powerful. Keep an eye on potential circular references if other modules import this file.web/core/components/pages/editor/editor-body.tsx (1)
70-91: Issue embed & mentions
UtilizingissueEmbedPropsandfetchMentionsfor direct editor integration is a good approach. Confirm performance under heavy usage or large data sets.web/core/store/pages/base-page.ts (5)
Line range hint
10-33: Consider splitting large type definitions for maintainability.
TBasePagecontains a substantial number of properties and actions. Splitting it into smaller, domain-specific interfaces or separate modules could improve maintainability and readability.
65-65: Class-based approach forBasePageis acceptable.
Consider verifying if a functional or hook-based approach might align better with the rest of the store patterns, but this is fine for certain use cases.
115-115: Team assignment.
this.team = page?.team || undefined;is fine. If the team is essential, consider a fallback or error scenario.
254-254: Return value fromupdateis awaited.
Returningawaitcan be redundant but is sometimes used for clarity. If not strictly needed, you could simplify toreturn this.services.update(currentPage).
371-371: Return early if missingid.
If archiving is crucial, consider more descriptive logging or an error message to ensure transparency ifthis.idis unexpectedly undefined.web/core/hooks/store/pages/use-page.ts (1)
12-12: Returning an empty object for nopageId.
Consider logging or an explicit fallback to avoid silent no-op in consumer code.packages/types/src/pages.d.ts (2)
18-19: Optional Project IDs and New Team Field
Makingproject_idsoptional and introducingteamprovide flexibility but might introduce null-handling complexities in consuming code. Review all references to ensure null-safe usage.
69-70: Formatting Nitpick
Ensure code formatting is consistent. Even if these lines only reflect minor layout adjustments, maintain uniform whitespace and end-of-file newlines for clarity.packages/types/src/search.d.ts (1)
9-9: Streamlined TSearchEntities
Removing suffixes from entity names ("cycle_mention", etc.) makes them more concise. Ensure references to these entity strings elsewhere are updated to match the new naming.web/core/components/pages/modals/delete-page-modal.tsx (2)
26-26: Ensure consistent null checks
Verifying bothpageandpage.idis good, but consider whether checkingpage?.idalone is sufficient. Ifpageis undefined,page?.idalso remains undefined.
28-28: Destructure additional fields as needed
You are already destructuringidandname. If more page properties are utilized, destructure them here for cleaner references.web/core/components/pages/dropdowns/quick-actions.tsx (1)
63-63: Error catch without parameter.
Capturing errors silently without logging or re-throwing is acceptable if no debug or user-facing details are needed, but consider at least logging the error for troubleshooting.web/core/store/root.store.ts (1)
85-85: Document the type casting rationale.Consider adding a code comment explaining why
ProjectPageStorerequiresRootStoreinstead ofCoreRootStoreand the safety of this type casting.+ // ProjectPageStore requires RootStore for access to web-specific store features this.projectPages = new ProjectPageStore(this as unknown as RootStore);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (34)
packages/editor/src/core/types/editor.ts(2 hunks)packages/types/src/pages.d.ts(3 hunks)packages/types/src/search.d.ts(2 hunks)packages/utils/src/editor.ts(0 hunks)packages/utils/src/index.ts(0 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx(3 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx(3 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(list)/page.tsx(1 hunks)web/ce/components/pages/editor/ai/ask-pi-menu.tsx(1 hunks)web/ce/components/pages/editor/ai/menu.tsx(1 hunks)web/ce/components/pages/extra-actions.tsx(1 hunks)web/ce/hooks/use-issue-embed.tsx(1 hunks)web/core/components/pages/dropdowns/edit-information-popover.tsx(1 hunks)web/core/components/pages/dropdowns/quick-actions.tsx(3 hunks)web/core/components/pages/editor/editor-body.tsx(3 hunks)web/core/components/pages/editor/header/extra-options.tsx(1 hunks)web/core/components/pages/editor/header/mobile-root.tsx(1 hunks)web/core/components/pages/editor/header/options-dropdown.tsx(1 hunks)web/core/components/pages/editor/header/root.tsx(1 hunks)web/core/components/pages/editor/page-root.tsx(4 hunks)web/core/components/pages/editor/title.tsx(3 hunks)web/core/components/pages/list/block-item-action.tsx(3 hunks)web/core/components/pages/list/block.tsx(2 hunks)web/core/components/pages/list/root.tsx(2 hunks)web/core/components/pages/modals/delete-page-modal.tsx(1 hunks)web/core/components/pages/version/editor.tsx(1 hunks)web/core/hooks/store/pages/use-page.ts(1 hunks)web/core/hooks/use-collaborative-page-actions.tsx(2 hunks)web/core/hooks/use-favorite-item-details.tsx(2 hunks)web/core/services/page/project-page.service.ts(2 hunks)web/core/store/pages/base-page.ts(18 hunks)web/core/store/pages/project-page.store.ts(8 hunks)web/core/store/pages/project-page.ts(1 hunks)web/core/store/root.store.ts(2 hunks)
💤 Files with no reviewable changes (2)
- packages/utils/src/index.ts
- packages/utils/src/editor.ts
🔇 Additional comments (134)
web/core/components/pages/editor/title.tsx (3)
11-11: Good import usage for handling page names.
Bringing in getPageName centralizes the logic for displaying page titles. This approach helps maintain consistent naming conventions across the codebase.
18-18: Careful with optional title in external calls.
Changing title from string to string | undefined is valid for scenarios in which the title may be missing. However, verify that all external references correctly handle the optional nature of title to avoid potential runtime issues.
76-79: Safe optional chaining for title length.
Using title?.length and short-circuit logic to style the text when title is longer than 255 characters is a robust approach since it prevents runtime errors when title is undefined. Good job!
web/core/components/pages/editor/page-root.tsx (10)
7-7: Ensure proper usage of imported types
The import of TDocumentPayload, TPage, and TPageVersion appears aligned with the new approach. If TPage is gradually replaced by TPageInstance throughout the project, verify consistent usage in other parts of the code.
24-25: New import referencing TPageInstance
Introducing TPageInstance from @/store/pages/base-page is consistent with the new store-based pattern. This should help unify how pages are managed.
26-34: Handler merging with editor handlers
Exporting TPageRootHandlers as an intersection (& TEditorBodyHandlers) is a clean way to ensure that all necessary page and editor operations are grouped. Just be sure each handler is tested and that error states propagate properly.
35-35: Alias type
export type TPageRootConfig = TEditorBodyConfig; is a straightforward alias. It helps maintain naming consistency at the PageRoot level.
38-40: Updated prop definitions
Using the new config, handlers, and page props ensures a more modular interface. This structure should facilitate easier testing and incremental feature addition.
45-45: Destructuring props
Destructuring at the top level is good for maintainability. Ensure that future additions to props have default values or are handled gracefully.
58-58: Metadata extraction
Pulling access, description_html, name, and isContentEditable directly off page is clear and concise. Ensure the logic handles any undefined states if page is uninitialized.
62-62: Mapping fallback hooks to new handlers
Providing handlers.fetchDescriptionBinary and handlers.updateDescription to the fallback logic is a straightforward way to centralize data access.
Also applies to: 64-64
116-117: Passing version-handling methods
Exposing fetchAllVersions and fetchVersionDetails to the overlay matches the new modular design. Make sure response data is validated and edge cases are handled.
133-133: Prop forwarding
The config, handlers, and workspaceSlug props are forwarded to child components. This is consistent with the updated architecture; verify these props are optional or mandatory where used.
Also applies to: 138-138, 141-141
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx (9)
3-14: Imports for React hooks and plane types
Combining React, type definitions, and UI helpers is a reasonable grouping. Confirm no unused imports remain after refactoring.
19-19: Importing PageRoot
Introducing PageRoot from @/components/pages aligns with the new centralized page structure. Good step toward component reusability.
21-21: Editor handler utilities
Using getEditorFileHandlers clarifies file upload logic for the editor. Make sure external service dependencies remain consistent.
31-34: Service instantiation
Instantiating services once at the top-level can be beneficial for scoping. Confirm no memory leaks or stale data issues if these services rely on ephemeral states.
39-45: Utilizing store hooks
Pulling data via useProjectPages() and useProjectPage() is consistent with the refactor. Confirm that these hooks handle loading and error states properly at all usage sites.
46-53: fetchEntityCallback
Uses useCallback to wrap the search entity function with the correct workspace and project IDs. Good approach for memoizing. Verify all error states are handled.
55-55: Retrieving file size constraints
useFileSize() presumably fetches or calculates max file size. Ensure large file uploads are gracefully handled.
95-123: pageRootConfig
Encapsulating file handling and webhook parameters in pageRootConfig is a clean approach. This ensures PageRoot remains generic yet configurable.
153-158: Utilizing
Passing config, handlers, page, and workspaceSlug through props clarifies the contract between parent and child. Great for maintainability and testability.
web/core/store/pages/project-page.ts (10)
1-3: MobX and mobx-utils
Importing computed from mobx and computedFn from mobx-utils is consistent with advanced MobX usage. Validate correct usage to avoid unintended re-renders.
4-5: Page-based type references
Using TPage from "@plane/types" indicates alignment with the new typed approach. Check for any leftover references to older page interfaces.
6-7: Constants
EPageAccess and EUserPermissions are likely used to handle role-based or access-based logic for pages. Confirm enumerations remain consistent throughout the codebase.
11-12: ProjectPageService
Maintaining a dedicated instance of projectPageService ensures a single source for project page API calls. Watch for concurrency or shared state issues if multiple pages update simultaneously.
14-15: BasePage + TPageInstance
This file references a base page class, ensuring consistent behaviors. Confirm it properly integrates with TPageInstance so typed properties remain in sync.
16-17: TProjectPage
Re-exporting TProjectPage from TPageInstance is a neat approach for project-specific logic layers.
18-65: ProjectPage constructor and base setup
The constructor merges store references with the existing BasePage structure and wires up every operation (update, lock, archive, etc.) with projectPageService. Thorough error checking for each field is a strong practice; just ensure these calls handle network or concurrency failures gracefully.
67-82: getHighestRoleAcrossProjects
Using a MobX computedFn to find the user’s highest role across projects is efficient. Double-check edge cases if the user belongs to no projects or if this.project_ids is empty.
84-157: Permission-based getters and content edit logic
All these computed getters (e.g., canCurrentUserEditPage, canCurrentUserLockPage, etc.) are well-defined for role-based access. Combining page states (isLocked, archived_at) with user permissions is a robust approach. Keep an eye on performance if these checks are triggered frequently.
159-163: Computed redirection link
getRedirectionLink returning a computed path is user-friendly. Ensure the path remains valid if slug or project IDs change mid-session.
web/core/components/pages/editor/editor-body.tsx (13)
9-9: File handling extension
Introducing TFileHandler in your editor environment helps unify file-related operations. Confirm that any file errors surface correctly in the UI.
14-15: New plane types
TSearchEntityRequestPayload, TSearchResponse, and TWebhookConnectionQueryParams are integrated to expand mention and hook functionalities. Great for an extensible editor.
17-17: Row import
The Row component from @plane/ui presumably standardizes layout. No issues found.
24-24: Using user store
useUser() retrieves current user data. Ensure all user-based logic gracefully handles the scenario when no user is found (anonymous or logged out).
33-34: TPageInstance
Replacing older page interfaces with TPageInstance ensures consistency with the new store approach.
35-42: Define TEditorBodyConfig & TEditorBodyHandlers
Your approach to encapsulate file operations and entity fetching in separate types organizes responsibilities clearly. Keep each extension minimal to avoid confusion.
45-45: Expose the config prop
Including config in the component’s props ensures you can pass in file handlers and other fetch operations as needed.
50-51: Centralized handlers
By referencing handlers: TEditorBodyHandlers, PageEditorBody can remain lean, delegating business logic to external definitions.
53-53: Reading TPageInstance
Ensuring the new page type is used consistently helps keep it aligned with the store.
57-66: Destructuring props
The code destructures config, handlers, and more. This pattern is neat for readability, but you might consider inline default values if props can be null or undefined.
102-102: Memo for getAIMenu
Memoizing the AI menu generator should help performance. Good approach if it’s expensive to create.
138-138: Realtime config release
Make sure you handle potential fallback if window.location or environment variables are not set. The try-catch is a good safeguard.
178-178: FileHandler and Editor
Passing fileHandler={config.fileHandler} is simpler than manually re-initializing. This approach also keeps everything consistent with your new type definitions.
web/core/store/pages/project-page.store.ts (9)
11-12: RootStore reference
Shifting from CoreRootStore to RootStore indicates a more consolidated approach. Double-check for leftover references to CoreRootStore to avoid confusion.
17-17: Import ProjectPage
Integrating the newly introduced ProjectPage type ensures consistency with your refactored store structure.
26-26: Use of TProjectPage
Replacing Record<string, IPage> with Record<string, TProjectPage> in the store data fosters a strongly typed approach that is consistent with the new model.
35-35: pageById now returns TProjectPage
This shift to returning TProjectPage | undefined helps unify downstream logic expecting the new page type.
52-52: Data structure updated
Using Record<string, TProjectPage> ensures each page is stored as a specialized instance. This approach can streamline further expansions (e.g., project-specific features).
63-63: Constructor references
Now referencing private store: RootStore. Check for any leftover references to CoreRootStore that might cause confusion or break code.
189-189: Creating ProjectPage instances
Wrapping each page object with new ProjectPage is consistent. Verify no memory leaks or cyclical dependencies in the store.
222-222: Updating page references
Replacing an existing page in this.data with a new ProjectPage instance is a safe approach but watch out for state transitions if the old instance was in use.
255-255: Creating a new page
Similarly, new pages are instantiated as ProjectPage, providing immediate typed benefits. Confirm UI reacts properly on newly created pages.
web/core/store/pages/base-page.ts (22)
7-8: Minor housekeeping for plane web store import.
No issues with adding a comment and importing the RootStore.
35-45: Permissions abstraction is clear.
The TBasePagePermissions keeps permission-related flags neatly organized. Good approach for separation of concerns.
46-57: Service layer definition looks good.
Having TBasePageServices clearly separate from state definitions is a clean design.
58-61: Custom getRedirectionLink approach is well-structured.
This ensures a consistent contract for retrieving navigation links.
63-64: Hook signature is well-defined.
TUsePage ensures consistent usage of the page instance across the application.
82-83: Project IDs usage.
project_ids is optional. Ensure external code paths handle null/undefined.
90-91: Explicit services property is useful.
Centralizing service calls here fosters maintainability.
95-95: rootStore referencing is consistent.
No issues noted.
97-99: Constructor signature is coherent.
Receives store, page data, and services for initialization. Design stands out as straightforward.
167-168: Explicit assignment for this.services.
No issues. Consistent with constructor injection principles.
173-174: Auto-update reaction for name changes.
Good approach, ensuring asynchronous updates. Consider the impact of potential concurrency or multiple updates in quick succession.
210-210: Including team in asJSON.
Maintains data completeness, consistent with other properties.
286-286: Delegating description updates to services.
Short and neat. Good error handling with fallback.
303-303: Making page public.
Service call is straightforward. The existing error fallback is clear.
322-322: Making page private.
Similar approach to makePublic, no issues found.
341-341: Locking functionality.
Proper error handling. Confirm that concurrency issues are handled if multiple lock requests occur.
358-358: Unlocking functionality.
Mirrors the lock approach effectively.
381-381: Awaiting services.archive()
Implementation is consistent, reassigning archived_at once the service completes.
406-406: Calling services.restore()
Symmetry with archive() includes error fallback as well. Good consistent design.
417-417: Updating page logo.
Keeps logic straightforward. Good usage of runInAction after the service call.
429-431: Add to favorites dependencies.
Checks for workspaceSlug and this.id are important. Please confirm usage of projectId is optional or always required for your logic.
456-457: Remove from favorites dependencies.
Same comment as above; verifying required IDs is crucial for safe operation.
web/ce/components/pages/extra-actions.tsx (3)
1-2: Import usage.
TPageInstance import from base-page is consistent with your new structure.
4-6: Type definition for TPageHeaderExtraActionsProps.
Defining a dedicated props interface is neat and helps keep the component self-describing.
8-8: Functional component signature is appropriate.
Returns null for now, but usage can be extended.
web/core/hooks/store/pages/use-page.ts (3)
4-5: Switch from IPage to TUsePage.
Adopting the new type for the hook fosters more consistency with your refactored data model.
6-6: New type import for TProjectPage.
Matching the updated code structure is coherent with the other type changes.
8-8: Renamed to useProjectPage.
Better naming that explicitly indicates the scope of usage.
web/core/components/pages/list/root.tsx (3)
8-8: Added useProjectPage to store hooks import.
Well-aligned with the new refactor. Minimizes props duplication.
17-17: Simplified props by removing projectId & workspaceSlug.
Keeps the component's responsibilities narrower. Good reusability.
27-27: Passing useProjectPage to PageListBlock.
This pattern is effective in modularizing data fetching logic.
web/core/components/pages/list/block.tsx (6)
14-14: TUsePage import.
Consistent with the new typed hook system.
18-18: Simplified prop structure with pageId & usePage.
Passing a direct hook reference is an interesting approach to keep the block decoupled from global store details.
22-22: Destructuring reveals a more explicit usage of usePage.
Enables a narrower contract for the block.
26-26: Declaration of page = usePage(pageId).
Clear approach to retrieve the page instance using the hook.
28-29: Direct extraction from the page object.
name, logo_props, and getRedirectionLink usage is consistent with the new TPageInstance.
43-43: itemLink referencing getRedirectionLink().
This ensures consistent routing logic. Good change, removing manual link forging.
web/core/components/pages/editor/header/mobile-root.tsx (3)
2-2: Removed References to Unused Editor Types
The import now only includes EditorRefApi and no longer references other editor types. Make sure that all removed editor-related types were indeed unused to keep dependencies minimal and maintain clarity.
9-9: Introduced TPageInstance
Importing TPageInstance solidifies the new base page model. Confirm this type is fully compatible with all existing data flows to prevent runtime type mismatches.
15-15: Refactored Prop Type to TPageInstance
Changing from IPage to TPageInstance aligns with the newly consolidated base page approach. Ensure all usage of this component respects the revised prop.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(list)/page.tsx (1)
54-54: Removed Redundant Workspace/Project Props
<PagesListRoot> no longer needs workspaceSlug and projectId. Verify that these props are no longer required for the component’s operation. If they’re still needed downstream, reintroduce them or handle them within the <PagesListRoot> component.
packages/types/src/pages.d.ts (3)
29-29: Extended Sort Key
"opened_at" has been added to the TPageFiltersSortKey. Confirm that all relevant filtering or sorting logic now properly handles "opened_at".
63-63: No Direct Changes Observed
The line shows only a closing brace for TPageVersion. No functional changes are visible here.
71-76: New TWebhookConnectionQueryParams
This type defines structure for webhook connections with optional projectId and teamId. Validate that all endpoints or services expecting these fields handle missing values gracefully.
packages/types/src/search.d.ts (1)
63-67: Renamed Search Response Properties
Properties such as cycle_mention → cycle unify naming conventions. Double-check any code that expects the old keys to avoid undefined references.
web/core/components/pages/modals/delete-page-modal.tsx (3)
10-11: Use consistent naming for hooks imports
Importing useEventTracker and useProjectPages is fine, but ensure consistent naming across the codebase for easy recognition and usage.
14-14: Adjust prop naming if it’s meant to align with other components
Changing from pageId to page is a good approach. Verify all dependent components are updated accordingly to avoid confusion or naming contradictions.
20-20: Simplify prop destructuring
This line is clear and concise. Confirm all references (e.g., previous variables or hooks) are fully removed to avoid confusion.
web/core/components/pages/editor/header/root.tsx (2)
11-11: Adopt standardized type imports
Replacing IPage with TPageInstance aligns with the new refactoring. Ensure that the removed import for IPage is cleaned up to prevent confusion.
17-17: Keep prop definitions consistent with usage
Switching to page: TPageInstance centralizes the page object. Verify that the rest of the component’s logic (e.g., extension or editing) consistently uses the new type.
web/core/hooks/use-favorite-item-details.tsx (2)
11-11: Check for potential collisions with hook imports
Using useProjectPage in place of usePage is a meaningful rename. Confirm that references to the old hook have been removed throughout the codebase.
26-26: Ensure robust null fallback
favoriteItemId ?? "" correctly prevents passing undefined into useProjectPage. Confirm that useProjectPage gracefully handles empty strings to avoid unexpected behavior.
web/core/components/pages/dropdowns/edit-information-popover.tsx (2)
12-12: Validate complete removal of IPage import
Ensure the old IPage import is fully removed to maintain clarity in this file and avoid overshadowed types.
15-15: Maintain type alignment in the entire code path
page: TPageInstance is consistent with the new approach across the codebase. Confirm that child components or related props are changed as well.
web/core/components/pages/list/block-item-action.tsx (5)
14-15: Use of new imports is consistent.
The introduction of useMember and TPageInstance aligns well with the updated props types below. Ensure that all references to imported members are valid throughout the file.
18-18: Single prop for the entire page.
Switching to a single page prop of type TPageInstance reduces prop clutter and centralizes page data. Confirm that any required page fields are guaranteed to exist on TPageInstance.
23-23: Destructuring new prop.
Destructuring page and parentRef looks straightforward.
35-35: Verify if fallback is needed for getRedirectionLink.
If getRedirectionLink can occasionally be undefined, consider adding defensive checks or a fallback URL.
96-96: Properly passing pageLink.
Using getRedirectionLink() directly for pageLink is clean and consistent with the refactored approach.
web/core/components/pages/editor/header/extra-options.tsx (2)
16-16: Import aligns with new page structure.
The import of TPageInstance fits the broader refactor to unify page types.
21-21: Updated prop type is consistent.
Switching from IPage to TPageInstance aligns this component with the rest of the codebase.
web/core/hooks/use-collaborative-page-actions.tsx (2)
2-5: Revised imports for plane editor & UI.
The updated import statements keep the references coherent and maintain type safety with the newly introduced TPageInstance.
Also applies to: 7-8
20-23: Refined hook signature.
Changing the second parameter from IPage to TPageInstance aligns with the refactoring. Make sure all references through page methods (like lock, archive, etc.) match the new type definition accurately.
web/core/components/pages/dropdowns/quick-actions.tsx (3)
12-12: Consistent page imports.
Importing TPageInstance continues the unification of page-related types across the app.
15-15: Adopting TPageInstance prop.
Replacing IPage with TPageInstance promotes type consistency. Ensure that any removed or optional properties are still accessible when needed.
107-107: Passing the full page object to delete modal.
This direct approach removes the need for a separate ID prop, improving clarity and consistency across the codebase.
web/ce/components/pages/editor/ai/ask-pi-menu.tsx (1)
19-19: Ensure consistency after removing projectId from props.
The removal of projectId from props looks good. Verify that no leftover references or dependencies rely on this prop. Ensure all callers and sub-components that previously used projectId have been updated accordingly.
web/core/components/pages/version/editor.tsx (1)
33-36: Use of object destructuring for useIssueEmbed is a clear improvement.
Switching from separate function parameters to an object for useIssueEmbed and getReadOnlyEditorFileHandlers yields a more readable and maintainable API. Ensure that all consumer code aligns with this updated structure, and that optional fields (like projectId) are handled where necessary.
packages/editor/src/core/types/editor.ts (1)
3-6: Added import for TWebhookConnectionQueryParams.
This import is consistent with the real-time query parameters usage below and helps improve type safety. Confirm that all references to this type align with the definitions in @plane/types to avoid type mismatches.
web/core/components/pages/editor/header/options-dropdown.tsx (2)
31-31: Switched from IPage to TPageInstance import.
Renaming the type clarifies the structure needed for the page prop. Ensure all references in this file and related files have also been updated to avoid type conflicts.
36-36: Type change for the page prop improves consistency with the new base page model.
By defining the page prop as TPageInstance, the component now aligns with the updated centralized base page structure. This change preserves the new design's goal of reducing code duplication.
web/core/services/page/project-page.service.ts (2)
50-54: Restricting updateAccess parameter to Pick<TPage, "access"> improves type safety
This change ensures only the relevant property is updated. It's a good practice to keep APIs restrictive to prevent accidental overwrites.
154-154: Renamed updateDescriptionYJS to updateDescription
The rename makes the method name more generic and aligns with the actual functionality. The direct error throw is clear and consistent.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (2)
18-18: Use useProjectPage instead of usePage
Switching to useProjectPage likely centralizes project-specific logic. Verify that all references previously calling usePage still work as intended with the new hook.
172-172: Pass page prop to <PageDetailsHeaderExtraActions />
Providing the page object explicitly allows the component to manage its own state more effectively. Confirm that the component properly handles null or undefined page values.
web/ce/components/pages/editor/ai/menu.tsx (1)
61-61: Removed projectId from Props
This simplifies the component’s dependencies. Confirm that removing projectId does not break other functionalities that rely on project context.
web/ce/hooks/use-issue-embed.tsx (3)
3-4: Added new imports for search response types
Importing TSearchEntityRequestPayload and TSearchResponse provides better type definitions for search-related operations. Good step toward structured data handling.
8-12: Introduced TIssueEmbedHookProps
This typed object clarifies optional props, ensuring better type safety and maintainability. Excellent for extension or partial use.
15-15: Refactored useIssueEmbed signature
Using a single props parameter instead of multiple arguments improves function readability and paves the way for easily adding new parameters in the future.
web/core/store/root.store.ts (1)
85-85: Verify the type casting approach between CoreRootStore and RootStore.
The type casting this as unknown as RootStore is used consistently for projectPages, issue, and state stores. While this works, it might hide potential type incompatibilities.
Let's verify the relationship between these store types:
Also applies to: 115-115
✅ Verification successful
Let me gather more information about the store types and their relationships.
Let me gather one final piece of information about the ProjectPageStore.
Type casting between CoreRootStore and RootStore is safe and consistent
The type casting approach is verified to be correct and safe based on the following findings:
RootStoreproperly extendsCoreRootStorein all implementations (web/ce, space/ce, admin/ce)- The type casting pattern
this as unknown as RootStoreis consistently used for stores that require the extended functionality ofRootStore - Only specific stores (issue, state, projectPages) use this casting, while others use the base
CoreRootStore, indicating intentional design - The casting is necessary because these stores need access to features specific to the extended
RootStoreclass while being initialized in theCoreRootStoreconstructor
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the inheritance relationship between CoreRootStore and RootStore
# and find similar patterns in other stores.
# Search for RootStore class definition and its relationship with CoreRootStore
ast-grep --pattern 'class RootStore extends CoreRootStore {
$$$
}'
# Find other stores using similar type casting pattern
rg -A 2 'as unknown as RootStore' --type ts
Length of output: 2648
Script:
#!/bin/bash
# Check the CoreRootStore definition and its relationship with stores
ast-grep --pattern 'class CoreRootStore {
$$$
}'
# Find the ProjectPageStore constructor definition
ast-grep --pattern 'class ProjectPageStore {
$$$
constructor($_) {
$$$
}
$$$
}'
# Check if there are any other stores using CoreRootStore type
rg "CoreRootStore" --type ts -B 2 -A 2
Length of output: 47865
Script:
#!/bin/bash
# Find the ProjectPageStore implementation and its constructor
rg -B 5 -A 10 "class ProjectPageStore" --type ts
Length of output: 1296
| queryParams: { | ||
| [key: string]: string; | ||
| }; | ||
| queryParams: TWebhookConnectionQueryParams; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Refined queryParams to TWebhookConnectionQueryParams for better type coverage.
Replacing a generic key-value object with TWebhookConnectionQueryParams ensures a more explicit contract for real-time connections. Verify that any code passing a generic object to realtimeConfig.queryParams has been updated to match the required fields.
Description
This PR refactors the pages' components, store and instance by generalizing them for scalability-
page-rootandeditor-bodycomponents which accept all theconfigsandhandlersas props and can be used to implement page like behavior anywhere.projectIdreceived as a prop.Type of Change
Summary by CodeRabbit
New Features
TWebhookConnectionQueryParams,TPageInstance, andTProjectPage.PageRootcomponent with new handlers for managing page operations.DeletePageModalto receive apageobject directly instead ofpageId.Bug Fixes
Refactor
usePagetouseProjectPage.Chores