refactor: space app barrel exports#7573
Conversation
WalkthroughReplaced many barrel exports with direct module imports, converted numerous value imports to TypeScript type-only imports, added ThemeProvider at the app root (removed from StoreProvider), and made a few small API/identifier changes (IIssueProperties expanded, IssuesPage → ViewsPage). Runtime behavior largely unchanged. Changes
Sequence Diagram(s)sequenceDiagram
participant NextApp as Next.js App
participant AppProvider as AppProvider
participant Theme as ThemeProvider
participant Store as StoreProvider
participant I18n as TranslationProvider
participant Toast as ToastProvider
participant Instance as InstanceProvider
NextApp->>AppProvider: Render
AppProvider->>Theme: Wrap (themes: light/dark, default: system)
Theme->>Store: Wrap
Store->>I18n: Wrap
I18n->>Toast: Wrap
Toast->>Instance: Wrap
Instance-->>NextApp: Children
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 11
🔭 Outside diff range comments (13)
apps/space/core/store/profile.store.ts (1)
111-136: Optimistic update rollback is broken; missing state update on success.
- currentUserProfileData references this.data (same object). You optimistically mutate this.data before the API call, so on failure your “rollback” attempts to restore from a mutated snapshot—no real rollback occurs.
- On success, you don’t update this.data with the server response (userProfile), leaving state potentially stale or partially updated.
Fix by taking a deep snapshot before mutation, restoring that snapshot on failure, and committing the server response on success.
@@ - updateUserProfile = async (data: Partial<TUserProfile>) => { - const currentUserProfileData = this.data; + updateUserProfile = async (data: Partial<TUserProfile>) => { + // take a deep snapshot for rollback + const snapshot = cloneDeep(this.data); try { - if (currentUserProfileData) { - Object.keys(data).forEach((key: string) => { - const userKey: keyof TUserProfile = key as keyof TUserProfile; - if (this.data) set(this.data, userKey, data[userKey]); - }); - } + Object.keys(data).forEach((key: string) => { + const userKey: keyof TUserProfile = key as keyof TUserProfile; + if (this.data) set(this.data, userKey, data[userKey]); + }); const userProfile = await this.userService.updateProfile(data); - return userProfile; + // commit server state to the store + this.data = userProfile; + return userProfile; } catch (_error) { - if (currentUserProfileData) { - Object.keys(currentUserProfileData).forEach((key: string) => { - const userKey: keyof TUserProfile = key as keyof TUserProfile; - if (this.data) set(this.data, userKey, currentUserProfileData[userKey]); - }); - } + // rollback to snapshot + this.data = snapshot; runInAction(() => { this.error = { status: "user-profile-update-error", message: "Failed to update user profile", }; }); } };Additionally, import cloneDeep:
import set from "lodash/set"; +import cloneDeep from "lodash/cloneDeep";apps/space/core/components/issues/issue-layouts/kanban/kanban-group.tsx (1)
6-13: RefineisPaginatingcheck and confirmKanbanIssueBlocksListexport
- Named export confirmed:
apps/space/core/components/issues/issue-layouts/kanban/blocks-list.tsx exportsexport const KanbanIssueBlocksList: React.FC<IssueBlocksListProps> = …- TLoader includes
undefinedand string states ("init-loader" | "mutation" | "pagination" | "loaded"). Using!!getIssueLoader(...)treats"loaded"as truthy, disabling the IntersectionObserver even when not paginating.- In kanban-group.tsx (around the
getIssueLoadercall), replace:Or, if you need to cover multiple loading phases:- const isPaginating = !!getIssueLoader(groupId, subGroupId); + const loaderState = getIssueLoader(groupId, subGroupId); + const isPaginating = loaderState === "pagination";const isLoading = ["init-loader", "mutation", "pagination"].includes(loaderState);apps/space/core/store/user.store.ts (1)
116-118: Fix Axios error handling: useerror.response?.status(noterror.status).
AxiosErrorexposes status onresponse?.status. The current condition will never match and may leave stale user data.Apply this diff:
- if (error instanceof AxiosError && error.status === 401) { + if (error instanceof AxiosError && error.response?.status === 401) { this.data = undefined; }apps/space/core/components/issues/navbar/user-avatar.tsx (1)
76-79: Fix display name fallback using first and last names correctly.Currently uses
first_nametwice and can yield"undefined undefined", masking better fallbacks.Apply this diff:
- {currentUser?.display_name || - `${currentUser?.first_name} ${currentUser?.first_name}` || - currentUser?.email || - "User"} + {currentUser?.display_name || + [currentUser?.first_name, currentUser?.last_name].filter(Boolean).join(" ") || + currentUser?.email || + "User"}apps/space/core/hooks/store/use-issue.ts (1)
1-11: Remove Remaining “@/hooks/store” Barrel Imports and ExportsWe still have numerous imports of the old hooks‐store barrel and its index exports. Please:
- Delete the barrel entry point (e.g.
ce/hooks/store/index.ts) and anyexport * from "…/hooks/store"statements.- Replace every
import { … } from "@/hooks/store"with direct imports from each hook’s module (e.g.
import { useAppTheme } from "ce/hooks/use-app-theme";).- No value imports of
IIssueStorewere found – continue to import it as a type only:
import type { IIssueStore } from "@/store/issue.store";.apps/space/core/hooks/store/use-issue-filter.ts (1)
9-9: Fix incorrect hook name in error messageThe thrown error references useUserProfile instead of useIssueFilter.
Apply this diff:
- if (context === undefined) throw new Error("useUserProfile must be used within StoreProvider"); + if (context === undefined) throw new Error("useIssueFilter must be used within StoreProvider");apps/space/core/components/issues/reactions/issue-vote-reactions.tsx (2)
124-126: Possible runtime error: missing optional chaining on actor_detailsUpvotes use actor_details?.display_name but downvotes don’t. If actor_details is undefined, this will throw.
Apply this diff:
- {allDownVotes - .map((r) => r.actor_details.display_name) + {allDownVotes + .map((r) => r.actor_details?.display_name) .splice(0, VOTES_LIMIT) .join(", ")}
52-67: Ensure isSubmitting is reset on errorsIf add/remove vote rejects, isSubmitting remains true and the buttons stay disabled. Wrap with try/finally.
Apply this diff:
const handleVote = async (e: any, voteValue: 1 | -1) => { if (!issueId) return; - setIsSubmitting(true); - - const actionPerformed = votes?.find((vote) => vote.actor_details?.id === user?.id && vote.vote === voteValue); - - if (actionPerformed) await issueDetailsStore.removeIssueVote(anchor, issueId); - else { - await issueDetailsStore.addIssueVote(anchor, issueId, { - vote: voteValue, - }); - } - - setIsSubmitting(false); + setIsSubmitting(true); + try { + const actionPerformed = votes?.find((vote) => vote.actor_details?.id === user?.id && vote.vote === voteValue); + if (actionPerformed) { + await issueDetailsStore.removeIssueVote(anchor, issueId); + } else { + await issueDetailsStore.addIssueVote(anchor, issueId, { vote: voteValue }); + } + } finally { + setIsSubmitting(false); + } };apps/space/core/components/issues/issue-layouts/properties/labels.tsx (1)
59-61: Stray quote in className produces an invalid classThere’s an extra double-quote at the end of the className template, resulting in a trailing " character in the class list.
Apply this diff:
- <div - className={`flex h-full flex-shrink-0 items-center rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs cursor-not-allowed" - `} - > + <div className="flex h-full flex-shrink-0 items-center rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs cursor-not-allowed">apps/space/core/store/publish/publish_list.store.ts (1)
21-31: Avoid implicit any: type the service field
publishServiceis declared without a type and initialized in the constructor, which can lead to an implicit any. Type it explicitly for clarity and stricter checks.Apply this diff:
- publishService; + publishService: SitesProjectPublishService;apps/space/core/store/label.store.ts (1)
43-53: Type the accumulator to avoid any[]/never[] inferenceWithout an annotation,
currLabelsmay infer toany[]ornever[]depending on tsconfig, which is brittle. Type it explicitly.- const currLabels = []; + const currLabels: IIssueLabel[] = [];apps/space/core/components/issues/peek-overview/side-peek-view.tsx (1)
43-43: Fix Tailwind arbitrary height value (h-[1] → h-px)Tailwind arbitrary values require units; h-[1] won’t resolve. Use h-px (or h-[1px]) to render a 1px divider.
- <div className="my-5 h-[1] w-full border-t border-custom-border-200" /> + <div className="my-5 h-px w-full border-t border-custom-border-200" />apps/space/core/components/issues/issue-layouts/properties/all-properties.tsx (1)
34-39: Remove unused min/max date computationminDate and maxDate are computed then never used. This is dead code and adds noise.
- const minDate = getDate(issue.start_date); - minDate?.setDate(minDate.getDate()); - - const maxDate = getDate(issue.target_date); - maxDate?.setDate(maxDate.getDate()); + // removed unused min/max date computations
🧹 Nitpick comments (28)
apps/space/core/store/module.store.ts (4)
67-67: Log message references the wrong entity (“members”).This store handles modules; the error message should say “modules” to avoid confusion during ops/debugging.
[Suggest fix below.]- console.error("Failed to fetch members:", error); + console.error("Failed to fetch modules:", error);
44-54: Tighten return typing in getModulesByIds.Type inference currently yields any[] for currModules. Make the type explicit for better safety and editor tooling.
- getModulesByIds = (moduleIds: string[]) => { - const currModules = []; + getModulesByIds = (moduleIds: string[]) => { + const currModules: TPublicModule[] = [];
56-70: Add an explicit return type to fetchModules.Annotating the return type clarifies intent and guards against accidental signature drift.
- fetchModules = async (anchor: string) => { + fetchModules = async (anchor: string): Promise<TPublicModule[]> => {
1-1: Avoid lodash.set for simple key assignment and drop the import.Using direct assignment is clearer and slightly faster for flat keys. This also lets you remove the lodash/set import.
-import set from "lodash/set";- for (const issueModule of modulesResponse) { - set(this.moduleMap, [issueModule.id], issueModule); - } + for (const issueModule of modulesResponse) { + this.moduleMap[issueModule.id] = issueModule; + }Also applies to: 62-63
apps/space/core/components/editor/embeds/mentions/user.tsx (1)
37-37: Drop unnecessary optional chaining after null-check.userDetails is already checked (Line 20), so optional chaining adds noise.
- @{userDetails?.member__display_name} + @{userDetails.member__display_name}apps/space/core/store/state.store.ts (1)
25-38: Prefer constructor parameter properties to reduce boilerplate.You can drop the explicit field + manual assignment and use a parameter property for
rootStore.Apply this diff:
- rootStore: CoreRootStore; - - constructor(_rootStore: CoreRootStore) { + constructor(public rootStore: CoreRootStore) { makeObservable(this, { // observables states: observable, // computed sortedStates: computed, // fetch action fetchStates: action, }); this.stateService = new SitesStateService(); - this.rootStore = _rootStore; }apps/space/core/store/user.store.ts (1)
180-182: Method isasyncbut doesn’t await anything.Either drop
async/Promise return type or make it actually async. Keeping it sync is simpler.Apply this diff:
- signOut = async (): Promise<void> => { - this.store.reset(); - }; + signOut = (): void => { + this.store.reset(); + };apps/space/core/components/issues/navbar/layout-selection.tsx (2)
49-52: Return null from map callback for clarityReturning
undefinedis rendered as nothing, butnullis the conventional React sentinel and silences potential lint warnings.- if (!layoutOptions[layout.key]) return; + if (!layoutOptions[layout.key]) return null;
57-58: Use strict equality (===) for comparisonsPrefer strict equality to avoid unintended coercions.
- className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${ - activeLayout == layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : "" + className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${ + activeLayout === layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : "" }`}- <IssueLayoutIcon - layout={layout.key} - className={`size-3.5 ${activeLayout == layout.key ? "text-custom-text-100" : "text-custom-text-200"}`} - /> + <IssueLayoutIcon + layout={layout.key} + className={`size-3.5 ${activeLayout === layout.key ? "text-custom-text-100" : "text-custom-text-200"}`} + />Also applies to: 63-63
apps/space/core/components/issues/issue-layouts/list/block.tsx (1)
65-65: Redundant condition can be simplifiedNo need to double-check
displayPropertieswhen already using optional chaining.- {displayProperties && displayProperties?.key && ( + {displayProperties?.key && (apps/space/core/hooks/store/use-state.ts (1)
9-9: Fix the thrown error message to match the hook nameThe hook is
useStates, but the error message saysuseState. Minor clarity fix.- if (context === undefined) throw new Error("useState must be used within StoreProvider"); + if (context === undefined) throw new Error("useStates must be used within StoreProvider");apps/space/core/components/issues/peek-overview/comment/add-comment.tsx (1)
71-71: Follow-up on TODO: handle unauthenticated users on submitYou already have
useUser; we can wire a redirect to login when!currentUseron Enter or disable the editor/submit affordance. I can implement this in a follow-up patch if desired.apps/space/core/components/issues/reactions/issue-vote-reactions.tsx (1)
83-87: Nit: prefer slice over splice for non-mutating truncationUse slice(0, VOTES_LIMIT) to avoid mutating arrays and to signal intent more clearly.
Apply this diff:
- {allUpVotes - .map((r) => r.actor_details?.display_name) - .splice(0, VOTES_LIMIT) - .join(", ")} + {allUpVotes + .map((r) => r.actor_details?.display_name) + .slice(0, VOTES_LIMIT) + .join(", ")} - {allDownVotes - .map((r) => r.actor_details?.display_name) - .splice(0, VOTES_LIMIT) - .join(", ")} + {allDownVotes + .map((r) => r.actor_details?.display_name) + .slice(0, VOTES_LIMIT) + .join(", ")}Also applies to: 125-127
apps/space/core/components/issues/issue-layouts/properties/labels.tsx (1)
41-41: Remove redundant key on inner divThe list key on Tooltip is sufficient; the nested div’s key is unnecessary.
Apply this diff:
- <div - key={label?.id} + <div className={`flex overflow-hidden h-full max-w-full flex-shrink-0 items-center rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs`} >apps/space/app/views/[anchor]/layout.tsx (1)
10-10: Confirm intent: file-based sub-barrel for publish hooks vs. explicit module importsOur search shows numerous imports still reference the publish “barrel” via:
import { usePublish, usePublishList } from "@/hooks/store/publish";Even though there’s no
index.tsunderhooks/store/publish, direct modules exist at:
apps/space/core/hooks/store/publish/use-publish.tsapps/space/core/hooks/store/publish/use-publish-list.tsIf your goal is to remove all barrels in the space app, update these imports to the explicit paths:
- import { usePublish, usePublishList } from "@/hooks/store/publish"; + import { usePublish } from "@/hooks/store/publish/use-publish"; + import { usePublishList } from "@/hooks/store/publish/use-publish-list";Otherwise—if you intend to keep the file-based barrel (
publish.tsinhooks/store)—no change is needed.apps/space/core/hooks/store/use-instance.ts (1)
9-9: Incorrect error message: mentions useUserProfile in useInstance hookMinor copy/paste issue in the thrown error. It should reference useInstance.
Apply this change:
- if (context === undefined) throw new Error("useUserProfile must be used within StoreProvider"); + if (context === undefined) throw new Error("useInstance must be used within StoreProvider");apps/space/core/store/publish/publish_list.store.ts (3)
5-5: Use type-only import for TProjectPublishSettingsIt’s only used as a type. Switching to
import typeavoids creating a runtime import.-import { TProjectPublishSettings } from "@plane/types"; +import type { TProjectPublishSettings } from "@plane/types";
14-15: Unify parameter naming: pageId vs anchorThe interface uses
pageId, the implementation usesanchor. For consistency and readability, unify the names.- fetchPublishSettings: (pageId: string) => Promise<TProjectPublishSettings>; + fetchPublishSettings: (anchor: string) => Promise<TProjectPublishSettings>;Also applies to: 38-38
41-43: Prefer direct assignment over lodash/set for a flat mapYou’re setting a single flat key. Direct assignment is simpler and avoids an extra dependency at runtime.
- if (response.anchor) { - set(this.publishMap, [response.anchor], new PublishStore(this.rootStore, response)); - } + if (response.anchor) { + this.publishMap[response.anchor] = new PublishStore(this.rootStore, response); + }If you apply this, also remove the lodash/set import at the top:
-import set from "lodash/set";apps/space/core/store/label.store.ts (1)
59-61: Optional: replace lodash/set with direct assignmentKeys are flat, so lodash/set is unnecessary here too.
- for (const label of labelsResponse) { - set(this.labelMap, [label.id], label); - } + for (const label of labelsResponse) { + this.labelMap[label.id] = label; + }If you apply this, you can drop the lodash/set import at the top as well:
-import set from "lodash/set";apps/space/core/store/publish/publish.store.ts (3)
3-9: Make all @plane/types imports type-onlyThese are purely types; marking as
import typereduces runtime overhead.-import { +import type { IWorkspaceLite, TProjectDetails, TPublishEntityType, TProjectPublishSettings, TProjectPublishViewProps, } from "@plane/types";
93-95: Nit: drop optional chaining onthis
thisis never undefined here; optional chaining on it is redundant.- return this?.workspace_detail?.slug ?? undefined; + return this.workspace_detail?.slug;
41-44: Private field is unused; mark intent or rename to avoid lint warnings
private storeis not referenced. If it’s intentionally kept for future use, consider renaming with a leading underscore and making it readonly to satisfy common lint rules.- constructor( - private store: CoreRootStore, - publishSettings: TProjectPublishSettings - ) { + constructor( + private readonly _store: CoreRootStore, + publishSettings: TProjectPublishSettings + ) {apps/space/core/components/issues/peek-overview/side-peek-view.tsx (1)
9-9: Use a type-only import for IIssueTo avoid unnecessary runtime imports and stay consistent with other files in this PR, import IIssue as a type.
-import { IIssue } from "@/types/issue"; +import type { IIssue } from "@/types/issue";apps/space/core/components/issues/issue-layouts/properties/all-properties.tsx (2)
14-14: Switch IIssue to a type-only importIIssue is a type; importing it at runtime is unnecessary. Use a type-only import to reduce bundle size and be consistent with the rest of the refactor.
-import { IIssue } from "@/types/issue"; +import type { IIssue } from "@/types/issue";
13-13: Correct comment categoryThis section is not hooks; it contains types. Minor, but helps maintain consistency when navigating files.
-//// hooks +// typesapps/space/core/components/issues/navbar/controls.tsx (1)
41-41: Remove unused setPeekId to avoid unnecessary re-renderssetPeekId is destructured but never used. Also appears in the effect deps. Remove both.
- const { setPeekId } = useIssueDetails(); + // const { setPeekId } = useIssueDetails();- setPeekId,Also applies to: 98-99
apps/space/core/components/issues/issue-layouts/root.tsx (1)
58-74: Guard against unsupported layouts or add a fallbackOnly "list" and "kanban" are rendered here. If publishSettings.view_props allows "calendar", "gantt", or "spreadsheet", the UI will render no layout. Confirm upstream guarantees or add a fallback to a supported layout.
Possible minimal fallback:
{activeLayout && ( <div className="relative flex h-full w-full flex-col overflow-hidden"> @@ - {activeLayout === "kanban" && ( + {activeLayout === "kanban" && ( <div className="relative mx-auto h-full w-full p-5"> <IssueKanbanLayoutRoot anchor={anchor} /> </div> )} + {!["list", "kanban"].includes(activeLayout) && ( + <div className="p-5 text-sm text-custom-text-300">Selected view is not available.</div> + )} </div> )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (103)
apps/space/app/issues/[anchor]/client-layout.tsx(1 hunks)apps/space/app/issues/[anchor]/page.tsx(1 hunks)apps/space/app/page.tsx(1 hunks)apps/space/app/provider.tsx(2 hunks)apps/space/app/views/[anchor]/layout.tsx(1 hunks)apps/space/app/views/[anchor]/page.tsx(3 hunks)apps/space/ce/components/issue-layouts/root.tsx(1 hunks)apps/space/ce/components/navbar/index.tsx(1 hunks)apps/space/core/components/account/auth-forms/auth-root.tsx(1 hunks)apps/space/core/components/account/auth-forms/index.ts(0 hunks)apps/space/core/components/account/index.ts(0 hunks)apps/space/core/components/account/user-logged-in.tsx(1 hunks)apps/space/core/components/common/index.ts(0 hunks)apps/space/core/components/editor/embeds/index.ts(0 hunks)apps/space/core/components/editor/embeds/mentions/user.tsx(1 hunks)apps/space/core/components/editor/index.ts(0 hunks)apps/space/core/components/editor/lite-text-editor.tsx(1 hunks)apps/space/core/components/editor/rich-text-editor.tsx(1 hunks)apps/space/core/components/editor/toolbar.tsx(1 hunks)apps/space/core/components/instance/index.ts(0 hunks)apps/space/core/components/issues/filters/applied-filters/root.tsx(1 hunks)apps/space/core/components/issues/filters/applied-filters/state.tsx(1 hunks)apps/space/core/components/issues/filters/helpers/index.ts(0 hunks)apps/space/core/components/issues/filters/index.ts(0 hunks)apps/space/core/components/issues/filters/labels.tsx(1 hunks)apps/space/core/components/issues/filters/priority.tsx(1 hunks)apps/space/core/components/issues/filters/root.tsx(1 hunks)apps/space/core/components/issues/filters/selection.tsx(1 hunks)apps/space/core/components/issues/filters/state.tsx(1 hunks)apps/space/core/components/issues/index.ts(0 hunks)apps/space/core/components/issues/issue-layouts/index.ts(0 hunks)apps/space/core/components/issues/issue-layouts/issue-layout-HOC.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/kanban/block.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/kanban/default.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/kanban/index.ts(0 hunks)apps/space/core/components/issues/issue-layouts/kanban/kanban-group.tsx(2 hunks)apps/space/core/components/issues/issue-layouts/kanban/swimlanes.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/list/base-list-root.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/list/block.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/list/default.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/list/index.ts(0 hunks)apps/space/core/components/issues/issue-layouts/properties/all-properties.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/properties/due-date.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/properties/index.ts(0 hunks)apps/space/core/components/issues/issue-layouts/properties/labels.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/properties/state.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/root.tsx(1 hunks)apps/space/core/components/issues/issue-layouts/with-display-properties-HOC.tsx(1 hunks)apps/space/core/components/issues/navbar/controls.tsx(1 hunks)apps/space/core/components/issues/navbar/index.ts(0 hunks)apps/space/core/components/issues/navbar/layout-selection.tsx(1 hunks)apps/space/core/components/issues/navbar/root.tsx(1 hunks)apps/space/core/components/issues/navbar/user-avatar.tsx(1 hunks)apps/space/core/components/issues/peek-overview/comment/add-comment.tsx(1 hunks)apps/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx(1 hunks)apps/space/core/components/issues/peek-overview/comment/comment-reactions.tsx(1 hunks)apps/space/core/components/issues/peek-overview/comment/index.ts(0 hunks)apps/space/core/components/issues/peek-overview/full-screen-peek-view.tsx(1 hunks)apps/space/core/components/issues/peek-overview/header.tsx(1 hunks)apps/space/core/components/issues/peek-overview/index.ts(0 hunks)apps/space/core/components/issues/peek-overview/issue-activity.tsx(1 hunks)apps/space/core/components/issues/peek-overview/issue-details.tsx(1 hunks)apps/space/core/components/issues/peek-overview/issue-properties.tsx(1 hunks)apps/space/core/components/issues/peek-overview/issue-reaction.tsx(1 hunks)apps/space/core/components/issues/peek-overview/layout.tsx(1 hunks)apps/space/core/components/issues/peek-overview/side-peek-view.tsx(1 hunks)apps/space/core/components/issues/reactions/index.ts(0 hunks)apps/space/core/components/issues/reactions/issue-emoji-reactions.tsx(1 hunks)apps/space/core/components/issues/reactions/issue-vote-reactions.tsx(1 hunks)apps/space/core/components/ui/not-found.tsx(0 hunks)apps/space/core/components/views/auth.tsx(1 hunks)apps/space/core/hooks/store/index.ts(0 hunks)apps/space/core/hooks/store/publish/use-publish-list.ts(1 hunks)apps/space/core/hooks/store/publish/use-publish.ts(1 hunks)apps/space/core/hooks/store/use-cycle.ts(1 hunks)apps/space/core/hooks/store/use-instance.ts(1 hunks)apps/space/core/hooks/store/use-issue-details.tsx(1 hunks)apps/space/core/hooks/store/use-issue-filter.ts(1 hunks)apps/space/core/hooks/store/use-issue.ts(1 hunks)apps/space/core/hooks/store/use-label.ts(1 hunks)apps/space/core/hooks/store/use-member.ts(1 hunks)apps/space/core/hooks/store/use-module.ts(1 hunks)apps/space/core/hooks/store/use-state.ts(1 hunks)apps/space/core/hooks/store/use-user-profile.ts(1 hunks)apps/space/core/hooks/store/use-user.ts(1 hunks)apps/space/core/lib/instance-provider.tsx(1 hunks)apps/space/core/lib/store-provider.tsx(1 hunks)apps/space/core/store/cycle.store.ts(1 hunks)apps/space/core/store/helpers/base-issues.store.ts(2 hunks)apps/space/core/store/instance.store.ts(1 hunks)apps/space/core/store/issue-detail.store.ts(1 hunks)apps/space/core/store/issue-filters.store.ts(1 hunks)apps/space/core/store/issue.store.ts(1 hunks)apps/space/core/store/label.store.ts(1 hunks)apps/space/core/store/members.store.ts(1 hunks)apps/space/core/store/module.store.ts(1 hunks)apps/space/core/store/profile.store.ts(1 hunks)apps/space/core/store/publish/publish.store.ts(1 hunks)apps/space/core/store/publish/publish_list.store.ts(1 hunks)apps/space/core/store/state.store.ts(1 hunks)apps/space/core/store/user.store.ts(1 hunks)
💤 Files with no reviewable changes (19)
- apps/space/core/components/common/index.ts
- apps/space/core/components/account/index.ts
- apps/space/core/components/issues/peek-overview/comment/index.ts
- apps/space/core/components/instance/index.ts
- apps/space/core/components/ui/not-found.tsx
- apps/space/core/components/issues/issue-layouts/list/index.ts
- apps/space/core/components/issues/reactions/index.ts
- apps/space/core/components/issues/navbar/index.ts
- apps/space/core/components/issues/filters/helpers/index.ts
- apps/space/core/components/editor/index.ts
- apps/space/core/components/issues/index.ts
- apps/space/core/hooks/store/index.ts
- apps/space/core/components/editor/embeds/index.ts
- apps/space/core/components/issues/peek-overview/index.ts
- apps/space/core/components/issues/issue-layouts/kanban/index.ts
- apps/space/core/components/issues/issue-layouts/properties/index.ts
- apps/space/core/components/account/auth-forms/index.ts
- apps/space/core/components/issues/filters/index.ts
- apps/space/core/components/issues/issue-layouts/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/space/ce/components/issue-layouts/root.tsx (2)
apps/space/core/store/publish/publish.store.ts (1)
PublishStore(21-117)apps/space/core/components/ui/not-found.tsx (1)
PageNotFound(8-25)
apps/space/app/provider.tsx (2)
packages/i18n/src/context/index.tsx (1)
TranslationProvider(15-19)apps/space/core/lib/instance-provider.tsx (1)
InstanceProvider(22-73)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript)
- GitHub Check: Build and lint web apps
- GitHub Check: Build and lint web apps
🔇 Additional comments (92)
apps/space/core/store/members.store.ts (1)
5-6: LGTM: Type-only imports correctly reduce runtime dependencies.Converting these imports to type-only is appropriate since both
TPublicMemberandCoreRootStoreare only used for type annotations in this file. This aligns with the broader refactoring to minimize runtime imports.apps/space/core/hooks/store/use-issue-details.tsx (1)
5-5: LGTM: Type-only import reduces runtime dependencies.Converting
IIssueDetailStoreto a type-only import is correct since it's only used for the return type annotation. This optimization removes unnecessary runtime dependencies without affecting functionality.apps/space/core/components/issues/issue-layouts/with-display-properties-HOC.tsx (1)
3-4: LGTM: Type-only import optimization implemented correctly.Converting
IIssueDisplayPropertiesto a type-only import is appropriate since it's only used in interface definitions and type annotations. This reduces the runtime bundle size without affecting functionality.apps/space/core/store/issue-filters.store.ts (1)
8-18: LGTM: Comprehensive type-only imports optimization.Converting all these type definitions to type-only imports is excellent practice:
IssuePaginationOptions,TIssueParamsfrom@plane/typesCoreRootStorefrom the root store- Various issue filter types from local types
All these symbols are only used for type annotations and interface definitions, making type-only imports the correct choice for reducing runtime dependencies.
apps/space/core/components/views/auth.tsx (1)
4-7: LGTM: Direct imports replace barrel exports effectively.The refactoring successfully eliminates barrel exports by importing components directly from their specific modules:
AuthRootfrom@/components/account/auth-formsPoweredByfrom@/components/common/powered-byThe addition of the "local imports" comment also improves code organization and readability.
apps/space/core/hooks/store/use-member.ts (1)
5-5: Type-only import is correct and reduces runtime coupling.Switching IIssueMemberStore to a type-only import matches the refactor goals and avoids unnecessary runtime dependencies. Hook logic remains sound.
apps/space/core/store/module.store.ts (1)
6-8: Type-only imports LGTM.Converting TPublicModule and CoreRootStore to type-only imports aligns with the anti-barrel refactor and reduces runtime dependencies without changing behavior.
apps/space/core/components/editor/embeds/mentions/user.tsx (1)
5-6: Direct hook imports (no barrel) are correct and align with PR goals.This removes the barrel dependency and keeps the component’s runtime behavior unchanged.
apps/space/core/hooks/store/use-user-profile.ts (1)
5-5: Type-only import LGTM.Matches the refactor pattern; hook behavior remains unchanged.
apps/space/core/store/profile.store.ts (1)
7-7: Type-only import for CoreRootStore is correct.This avoids pulling the class at runtime where it's only used as a type.
apps/space/core/lib/store-provider.tsx (1)
34-34: ThemeProvider removal confirmed – single app-level wrapper in place
- Verified a single
<ThemeProvider>import and usage in apps/space/app/provider.tsx, configured withthemes={["light","dark"]},defaultTheme="system", andenableSystem.- No other
import { ThemeProvider }occurrences under apps/space.All good to merge.
apps/space/core/store/instance.store.ts (1)
7-7: Good use of type-only import to drop unnecessary runtime dependency.Converting CoreRootStore to a type-only import tightens the module graph and avoids accidental side-effects at runtime. No functional changes introduced.
apps/space/core/store/cycle.store.ts (1)
6-6: Type-only import for CoreRootStore is appropriate here.CoreRootStore is used purely for typing (property and ctor param). This reduces runtime imports without changing behavior.
apps/space/core/components/issues/issue-layouts/issue-layout-HOC.tsx (1)
2-6: Confirmed: LogoSpinner is a named export
- In apps/space/core/components/common/logo-spinner.tsx you have
export const LogoSpinner = …
so importing{ LogoSpinner }is correct.import type { TLoader }remains valid.No changes needed here.
apps/space/core/store/state.store.ts (1)
9-9: Type-only import is appropriate here; avoids unnecessary runtime linkage.CoreRootStore is only used for typing; using
import typetrims runtime deps and helps break cycles. No runtime usage detected in this file.apps/space/core/components/editor/rich-text-editor.tsx (2)
4-6: Good use of type-only imports for editor types.This keeps the emitted JS lean while preserving type safety.
9-11: No remaining barrel imports detected; refactor completeA repository-wide search confirmed there are no bare
@/store,@/hooks, or@/componentsimports underapps/space. All imports now reference specific modules, aligning with the “no barrels” objective—no further action needed.apps/space/core/store/user.store.ts (1)
10-10: Type-only import is correct and reduces runtime coupling.No runtime reliance on
CoreRootStoreas a value is present here, so this change is safe.apps/space/core/components/issues/navbar/user-avatar.tsx (1)
18-18: Granular hook import LGTM.Moving from the barrel to
@/hooks/store/use-usermatches the PR goal and should avoid unintended deps.apps/space/core/components/issues/issue-layouts/properties/state.tsx (1)
9-9: Hook import path update is correct.Direct import from
@/hooks/store/use-stateremoves reliance on the barrel without changing behavior.apps/space/core/components/issues/issue-layouts/properties/due-date.tsx (1)
11-11: Switched to module-specific hook import — LGTMImporting
useStatesfrom its dedicated module is consistent with removing barrel exports and should improve clarity and treeshaking.apps/space/core/components/issues/filters/applied-filters/root.tsx (1)
8-8: Module-specificuseIssueFilterimport — looks goodThis is consistent with the PR-wide refactor away from store barrels. Types are already imported as type-only below — nice touch.
apps/space/core/components/editor/toolbar.tsx (1)
5-5: Type-only imports for editor types — good for bundle sizeKeeping
ToolbarMenuItemandEditorRefApias type-only imports avoids pulling type-only symbols at runtime while preserving DX.apps/space/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx (1)
11-11: GranularuseIssueimport — aligns with barrel removalDirectly targeting the hook module reduces coupling to the store’s surface. No other functional changes observed here.
apps/space/core/components/issues/filters/root.tsx (1)
15-15: LGTM! Import path updated correctly.The import path change from a barrel export to a direct module path aligns with the PR objective of removing barrel exports. This improves build performance and tree-shaking capabilities.
apps/space/core/components/issues/peek-overview/header.tsx (1)
12-12: LGTM! Import path refactored to explicit module.The import path update from
@/hooks/storeto@/hooks/store/use-issue-detailsfollows the barrel export removal pattern consistently applied across the PR.apps/space/core/components/issues/filters/applied-filters/state.tsx (1)
9-9: LGTM! Import path updated to direct module reference.The change from
@/hooks/storeto@/hooks/store/use-stateis consistent with the PR's objective of removing barrel exports and makes the dependency more explicit.apps/space/core/components/issues/peek-overview/layout.tsx (2)
8-8: LGTM! Hook import path updated correctly.The migration from barrel export to direct module path
@/hooks/store/use-issue-detailsimproves build optimization and follows the consistent pattern throughout this refactor.
10-11: LGTM! Local imports now use explicit relative paths.Converting from barrel exports to direct relative imports (
./full-screen-peek-viewand./side-peek-view) improves bundler tree-shaking and makes dependencies more transparent.apps/space/core/hooks/store/publish/use-publish.ts (1)
5-5: LGTM! Converted to type-only import.Converting
PublishStoreto a type-only import is an excellent optimization. Since this is only used for type annotations and not runtime code, this reduces the bundle size and prevents unnecessary module loading at runtime.apps/space/ce/components/navbar/index.tsx (1)
1-1: ConfirmPublishStoreExport and Import UsageOur check shows that
PublishStoreis exported as a class (a runtime value) in
apps/space/core/store/publish/publish.store.ts. Usingimport type { PublishStore } from "@/store/publish/publish.store";will strip out the runtime import entirely. Please verify that in
apps/space/ce/components/navbar/index.tsxyou only usePublishStoreas a type (e.g. for props or type annotations).
If you ever instantiate it or access its static members at runtime, switch back to a regular import:- import type { PublishStore } from "@/store/publish/publish.store"; + import { PublishStore } from "@/store/publish/publish.store";apps/space/core/hooks/store/publish/use-publish-list.ts (1)
5-5: The existing verification didn’t locate theRootStoreclass or thepublishListproperty on it, so I can’t confirm thatStoreContext.publishListimplementsIPublishListStore. Please verify manually:
- Confirm where
RootStoreis declared and that it defines apublishList: IPublishListStoremember.- Ensure the
StoreProviderin apps/space/core/lib/store-provider.tsx passes aRootStoreinstance (withpublishList) via the context.- Check that
publishListon the context value matches the shape ofIPublishListStore.apps/space/core/components/issues/peek-overview/comment/comment-reactions.tsx (1)
15-16: Direct module imports look goodSwitching away from "@/hooks/store" to precise modules improves clarity and avoids barrel coupling.
apps/space/core/components/issues/reactions/issue-emoji-reactions.tsx (1)
12-13: Granular hook imports are consistent with the PR’s goalsDirectly importing from the hook modules is cleaner and avoids accidental re-exports.
apps/space/core/hooks/store/use-issue.ts (1)
5-5: Type-only import is correct and avoids unnecessary runtime dependencySwitching to
import type { IIssueStore }is the right move here. Keeps the hook tree-shakeable and avoids pulling the store module at runtime. The rest of the hook remains correct.apps/space/core/components/issues/navbar/layout-selection.tsx (1)
14-14: Direct hook import path aligns with barrel removalImporting
useIssueFilterfrom its dedicated module is consistent with the PR’s refactor and keeps dependencies explicit.apps/space/core/components/issues/issue-layouts/list/block.tsx (1)
16-18: Granular hook imports look goodSwitching to explicit module imports (
publish,use-issue-details) keeps dependencies clear and meets the “remove barrel exports” goal without changing behavior.apps/space/core/hooks/store/use-state.ts (1)
5-5: Type-only import is correct here as wellGood consistency with other hooks; avoids runtime import of the store type.
apps/space/core/components/issues/peek-overview/comment/add-comment.tsx (1)
14-16: Granular hook imports approvedExplicitly importing
usePublish,useIssueDetails, anduseUsermatches the refactor’s direction and keeps module boundaries clean.apps/space/core/hooks/store/use-issue-filter.ts (2)
5-5: Good change: type-only import avoids unintended runtime dependencySwitching IIssueFilterStore to a type-only import is correct and reduces bundle weight.
5-5: Import path verified:issue-filters.store.tsis correctThe interface
IIssueFilterStoreis defined inapps/space/core/store/issue-filters.store.ts, and bothroot.store.tsanduse-issue-filter.tsimport from"./issue-filters.store"/"@/store/issue-filters.store". No changes are needed.apps/space/core/components/issues/reactions/issue-vote-reactions.tsx (1)
12-13: LGTM: granular hook importsDirect module imports (instead of barrel) match the PR’s direction and reduce accidental bloat.
apps/space/core/components/issues/issue-layouts/properties/labels.tsx (1)
8-8: LGTM: direct hook importMoving useLabel to a direct module import is consistent with the barrel-removal refactor.
apps/space/core/hooks/store/use-module.ts (1)
5-5: Good change: type-only importUsing import type for IIssueModuleStore prevents an unnecessary runtime import and aligns with TS best practices.
apps/space/core/hooks/store/use-user.ts (1)
5-5: Good change: type-only importUsing import type for IUserStore is correct and matches the refactor direction.
apps/space/core/hooks/store/use-cycle.ts (1)
5-5: Type-only import is correct and preferable here.Avoids pulling runtime code for types and keeps the hook tree-shakeable. No behavioral changes.
apps/space/core/components/issues/issue-layouts/list/default.tsx (1)
14-18: Granular hook imports: ✅Consistent with the refactor and avoids the store barrel. No functional changes.
apps/space/core/components/issues/filters/state.tsx (1)
9-12: Local helper imports and granular state hook: ✅Cleaner module boundaries and no runtime behavior change. Good move.
apps/space/app/views/[anchor]/layout.tsx (1)
6-7: Direct component imports from common — LGTMSwitching away from the common barrel to explicit module paths for LogoSpinner and PoweredBy aligns with the PR’s objective and reduces accidental bundle bloat.
apps/space/app/page.tsx (2)
5-6: Barrel-free imports for account, common, and store hooks — LGTMSwapping to "@/components/account/user-logged-in", "@/components/common/logo-spinner", and "@/hooks/store/use-user" is consistent with the refactor and avoids the prior barrels.
Also applies to: 9-9
7-7: Barrel import confirmed—no update neededThe import from
"@/components/views"resolves toapps/space/core/components/views/index.ts, which still exists and re-exportsAuthViewfrom./auth. No change required here.apps/space/core/hooks/store/use-instance.ts (1)
5-5: Type-only import for store interface — LGTMUsing a type-only import eliminates an unnecessary runtime dependency, aligning with the broader refactor.
apps/space/core/components/issues/filters/selection.tsx (1)
7-10: Type-only and explicit local imports — LGTM; verify filter key type alignmentThe type-only import for issue types and replacing the local barrel with direct imports improves clarity and reduces runtime overhead. One thing to double-check: is TIssueFilterKeys guaranteed to be a subset of keyof IIssueFilterOptions? It’s used with includes(filter), where filter is keyof IIssueFilterOptions. A mismatch would cause TS friction.
If needed, you can tighten the types to reflect the relationship:
- Option A (type guard):
const isFilterEnabled = (filter: keyof IIssueFilterOptions): filter is TIssueFilterKeys => layoutDisplayFiltersOptions.includes(filter as TIssueFilterKeys);
- Option B (broaden prop type to match usage):
type Props = { // ... layoutDisplayFiltersOptions: (keyof IIssueFilterOptions)[]; };apps/space/core/components/issues/issue-layouts/list/base-list-root.tsx (1)
9-9: Direct import for useIssue hook — LGTMMoving from the store barrel to "@/hooks/store/use-issue" aligns with the refactor intent without affecting behavior.
apps/space/core/store/publish/publish_list.store.ts (1)
8-8: Good switch to type-only import for CoreRootStoreThis removes an unnecessary runtime dependency and aligns with the PR’s goal. No behavior change.
apps/space/core/store/label.store.ts (2)
5-5: Good: type-only import for IIssueLabelThis keeps types compile-time only and removes unnecessary runtime imports.
7-7: Good: type-only import for CoreRootStoreConsistent with the PR-wide pattern; no runtime impact.
apps/space/core/components/issues/peek-overview/issue-details.tsx (1)
3-3: Path refactors look good
- RichTextEditor import now points to the concrete module.
- IssueReactions switched to a local relative import.
These are aligned with removing barrels.
Also applies to: 7-8
apps/space/core/store/publish/publish.store.ts (1)
11-11: Good: type-only import for CoreRootStoreRemoves a runtime import while preserving typing.
apps/space/core/components/account/user-logged-in.tsx (1)
7-10: Imports refactor aligns with barrel removalDirect module paths for PoweredBy, UserAvatar, and useUser look correct and keep behavior unchanged.
apps/space/core/store/helpers/base-issues.store.ts (1)
11-21: Type-only imports are correct and reduce runtime couplingConverting these to
import typecleanly erases them at emit time and aligns with the refactor’s intent. No runtime references depend on these, so this is safe.Also applies to: 23-24
apps/space/core/store/issue-detail.store.ts (1)
10-13: Good switch to type-only imports for store and issue typesThese are used purely for typing; moving to
import typeavoids unnecessary runtime edges without affecting behavior.apps/space/core/store/issue.store.ts (1)
4-4: Type-only imports are appropriate and reduce runtime bundle sizeSwitching IssuePaginationOptions, TLoader, CoreRootStore, and IBaseIssuesStore to type-only imports is correct here, since these symbols are used only in type positions. Keeping BaseIssuesStore as a value import preserves runtime behavior. LGTM.
Also applies to: 6-6, 8-8
apps/space/core/components/issues/peek-overview/full-screen-peek-view.tsx (1)
4-4: Good move away from barrels; explicit local module imports + type-only IIssueReplacing the peek-overview barrel with direct local imports improves clarity and avoids accidental deep dependencies. Converting IIssue to a type-only import is also correct.
Also applies to: 7-12
apps/space/core/lib/instance-provider.tsx (1)
11-12: No changes required: named exports verifiedAll four modules export their symbols as named (no default), so the imports in apps/space/core/lib/instance-provider.tsx are correct and will compile at runtime.
Locations verified:
- apps/space/core/components/common/logo-spinner.tsx:
export const LogoSpinner- apps/space/core/components/instance/instance-failure-view.tsx:
export const InstanceFailureView- apps/space/core/hooks/store/use-instance.ts:
export const useInstance- apps/space/core/hooks/store/use-user.ts:
export const useUserapps/space/core/hooks/store/use-label.ts (1)
5-5: Type-only import for IIssueLabelStore is correctThe hook only uses the type in its signature; making it type-only removes an unnecessary runtime import. Looks good.
apps/space/core/components/issues/issue-layouts/kanban/swimlanes.tsx (1)
16-20: LGTM! Clean import path refactoring.The migration from barrel exports to individual module imports improves tree-shaking and makes dependencies more explicit.
apps/space/core/components/account/auth-forms/auth-root.tsx (2)
22-22: LGTM! Consistent with the granular import pattern.The hook import refactoring aligns well with the broader PR objective to remove barrel exports.
30-36: LGTM! Proper import organization and locality.The restructuring to use local relative imports improves module boundaries and reduces coupling. The addition of the "local imports" comment section enhances code organization.
apps/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx (2)
11-12: LGTM! Improved module specificity.The migration from barrel imports to direct component paths enhances tree-shaking and makes the dependency graph more explicit.
16-18: LGTM! Granular hook imports.The refactoring to individual hook modules aligns perfectly with the PR's objective to eliminate barrel exports and improves build optimization.
apps/space/core/components/issues/filters/labels.tsx (1)
4-10: LGTM! Consistent refactoring pattern.The changes align well with the PR objectives:
- Local relative imports for FilterHeader and FilterOption improve module boundaries
- Type-only import for IIssueLabel enhances type safety and build optimization
- Clear separation between plane imports and local imports with appropriate comments
apps/space/app/provider.tsx (2)
4-4: LGTM! ThemeProvider addition at the root level.Adding ThemeProvider import to enable theme management at the application root.
19-27: LGTM! Proper provider hierarchy established.The ThemeProvider is correctly positioned as the outermost wrapper with appropriate configuration:
- Supports both light and dark themes
- Uses system theme as default with
enableSystemenabled- Maintains the existing provider hierarchy as nested children
This change complements the removal of ThemeProvider from StoreProvider, establishing a cleaner separation of concerns.
apps/space/app/views/[anchor]/page.tsx (4)
6-6: LGTM: Direct import path improves module clarity.The change from barrel export to direct import path follows the PR's objective of removing barrel exports and makes dependencies more explicit.
8-8: LGTM: Hook import path refactored correctly.The direct import from the publish module aligns with the barrel export removal strategy.
18-18: Component rename from IssuesPage to ViewsPage is appropriate.The rename better reflects the component's purpose as it handles views rather than just issues. The function logic remains unchanged.
37-37: Export updated correctly to match component rename.The default export properly reflects the component name change from IssuesPage to ViewsPage.
apps/space/core/components/issues/navbar/root.tsx (3)
3-3: Good addition of explicit React FC import.Adding the explicit FC import improves type clarity and follows TypeScript best practices.
7-7: LGTM: Direct ProjectLogo import path.The move from barrel export to direct import path improves module dependency clarity.
9-11: Excellent use of type-only import for PublishStore.Converting to a type-only import reduces runtime dependencies since PublishStore is only used for typing purposes in this component. The addition of the "local imports" comment also improves code organization.
apps/space/core/components/issues/peek-overview/issue-activity.tsx (3)
7-7: Good addition of plane imports section comment.The comment helps organize imports and follows the new import structure pattern established in this refactor.
10-11: LGTM: Direct component imports replace barrel exports.The explicit imports from specific comment component files improve module resolution and align with the PR's objective of removing barrel exports.
14-16: Hook imports refactored correctly.The direct imports from specific hook modules replace the previous barrel imports, improving dependency clarity and following the refactor pattern.
apps/space/core/components/issues/filters/priority.tsx (2)
5-8: Well-organized import sections with explicit plane imports.The addition of the "plane imports" comment and explicit ISSUE_PRIORITY_FILTERS import improves code organization and makes dependencies clearer.
9-11: Local imports properly separated from barrel exports.The direct imports of FilterHeader and FilterOption from specific helper modules replace barrel exports and improve module dependency clarity.
apps/space/ce/components/issue-layouts/root.tsx (2)
2-2: Excellent use of type-only import for PublishStore.Since PublishStore is only used for typing the
publishSettingsparameter and the component doesn't actually use the props at runtime, the type-only import is perfect here. This reduces runtime bundle size and clarifies that this is purely for type checking.
9-9: Good practice: Prefixing unused parameter with underscore.Renaming
propsto_propscorrectly indicates that the parameter is intentionally unused, which aligns with the component's behavior of always renderingPageNotFoundregardless of props.apps/space/core/components/issues/peek-overview/side-peek-view.tsx (1)
4-14: Barrel-to-local import refactor looks goodDirect local imports and granular hook path improve tree-shaking and reduce coupling. This aligns with the PR objective.
apps/space/core/components/issues/issue-layouts/properties/all-properties.tsx (1)
5-7: Good move to type-only and local property block imports
- type-only import for IIssueDisplayProperties is correct.
- Replacing barrel imports with local property blocks reduces tight coupling and is aligned with the PR’s intent.
Also applies to: 15-21
apps/space/core/components/issues/navbar/controls.tsx (1)
11-21: Granular hook imports and local component imports LGTMSwitching from barrels to direct paths reduces coupling and is consistent with the PR scope. Type-only imports for PublishStore and TIssueLayout are also correct.
apps/space/core/components/issues/issue-layouts/root.tsx (1)
10-19: Import and type-only refactor aligns with PR goals
- Using granular store hooks and type-only PublishStore is correct.
- Local layout root imports (kanban/list) avoid central barrels and clarify dependencies.
| import { LogoSpinner } from "@/components/common/logo-spinner"; | ||
| import { PoweredBy } from "@/components/common/powered-by"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Replace remaining barrel imports with file-level modules
Great move on de-barreling most imports. Two spots still import from folder-level barrels. To fully meet the PR objective and improve tree-shaking, import from the concrete modules.
-import { IssuesNavbarRoot } from "@/components/issues/navbar";
+import { IssuesNavbarRoot } from "@/components/issues/navbar/root";
...
-import { usePublish, usePublishList } from "@/hooks/store/publish";
+import { usePublish } from "@/hooks/store/publish/use-publish";
+import { usePublishList } from "@/hooks/store/publish/use-publish-list";Check repo-wide for remaining barrels for these modules and confirm granular modules exist:
Also applies to: 9-13
🏁 Script executed:
#!/bin/bash
# 1) Find residual imports from "@/components/issues/navbar" (likely index barrel)
rg -n $'from\\s+[\'"]@/components/issues/navbar[\'"]' -S || true
# 2) Find residual imports from "@/hooks/store/publish" (likely index barrel)
rg -n $'from\\s+[\'"]@/hooks/store/publish[\'"]' -S || true
# 3) Ensure the granular files exist
fd -a --hidden --follow --strip-cwd-prefix $'apps/space/core/components/issues/navbar/root.tsx\napps/space/core/hooks/store/publish/use-publish.ts\napps/space/core/hooks/store/publish/use-publish-list.ts' \
--exec bash -lc 'for f; do [[ -f "$f" ]] && echo "FOUND $f" || echo "MISSING $f"; done' _Length of output: 2180
#!/usr/bin/env bash
# Verify existence of granular module files
for file in \
apps/space/core/components/issues/navbar/root.tsx \
apps/space/core/hooks/store/publish/use-publish.ts \
apps/space/core/hooks/store/publish/use-publish-list.ts; do
if [[ -f "$file" ]]; then
echo "FOUND $file"
else
echo "MISSING $file"
fi
done#!/usr/bin/env bash
# Verify that the granular module files exist
for file in \
apps/space/core/components/issues/navbar/root.tsx \
apps/space/core/hooks/store/publish/use-publish.ts \
apps/space/core/hooks/store/publish/use-publish-list.ts; do
if [[ -f "$file" ]]; then
echo "FOUND $file"
else
echo "MISSING $file"
fi
done#!/usr/bin/env bash
# Verify that the concrete modules exist for replacing barrel imports
FILES=(
"apps/space/core/components/issues/navbar/root.tsx"
"apps/space/core/hooks/store/publish/use-publish.ts"
"apps/space/core/hooks/store/publish/use-publish-list.ts"
)
for f in "${FILES[@]}"; do
if [[ -f "$f" ]]; then
echo "FOUND: $f"
else
echo "MISSING: $f"
fi
done#!/usr/bin/env bash
# Locate granular module files to confirm replacement targets
fd 'components/issues/navbar/root.tsx' -t f
fd 'hooks/store/publish/use-publish.ts' -t f
fd 'hooks/store/publish/use-publish-list.ts' -t f#!/usr/bin/env bash
# Check that the target module files exist for replacing barrel imports
FILES=(
"apps/space/core/components/issues/navbar/root.tsx"
"apps/space/core/hooks/store/publish/use-publish.ts"
"apps/space/core/hooks/store/publish/use-publish-list.ts"
)
for f in "${FILES[@]}"; do
if [[ -f "$f" ]]; then
echo "FOUND: $f"
else
echo "MISSING: $f"
fi
doneReplace all remaining barrel imports for issues/navbar and hooks/store/publish
We still have multiple occurrences of barrel imports that need to switch to the concrete modules to complete the de-barreling effort and improve tree-shaking:
• apps/space/app/issues/[anchor]/client-layout.tsx
- import { IssuesNavbarRoot } from "@/components/issues/navbar";
- import { usePublish, usePublishList } from "@/hooks/store/publish";
• apps/space/app/views/[anchor]/page.tsx
- import { usePublish } from "@/hooks/store/publish";
• apps/space/app/issues/[anchor]/page.tsx
- import { usePublish } from "@/hooks/store/publish";
• apps/space/app/views/[anchor]/layout.tsx
- import { usePublish, usePublishList } from "@/hooks/store/publish";
(And similarly in core components under apps/space/core/components/issues/...)
Please update each to:
-import { IssuesNavbarRoot } from "@/components/issues/navbar";
+import { IssuesNavbarRoot } from "@/components/issues/navbar/root";
-import { usePublish, usePublishList } from "@/hooks/store/publish";
+import { usePublish } from "@/hooks/store/publish/use-publish";
+import { usePublishList } from "@/hooks/store/publish/use-publish-list";Before applying, verify these files exist in the apps/space/core/… directory:
- components/issues/navbar/root.tsx
- hooks/store/publish/use-publish.ts
- hooks/store/publish/use-publish-list.ts
This will complete the PR objective and ensure all barrel imports are replaced.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/space/app/issues/[anchor]/client-layout.tsx around lines 6-7, replace
the barrel imports with concrete module imports: import IssuesNavbarRoot from
"apps/space/core/components/issues/navbar/root"; import usePublish from
"apps/space/core/hooks/store/publish/use-publish"; import usePublishList from
"apps/space/core/hooks/store/publish/use-publish-list"; before changing, verify
the files exist at apps/space/core/components/issues/navbar/root.tsx and
apps/space/core/hooks/store/publish/use-publish.ts and use-publish-list.ts, then
update the other listed files similarly (apps/space/app/views/[anchor]/page.tsx,
apps/space/app/issues/[anchor]/page.tsx,
apps/space/app/views/[anchor]/layout.tsx) to import the specific hooks from
those concrete paths.
| import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts"; | ||
| // hooks | ||
| import { usePublish, useLabel, useStates } from "@/hooks/store"; | ||
| import { usePublish } from "@/hooks/store/publish"; | ||
| import { useLabel } from "@/hooks/store/use-label"; | ||
| import { useStates } from "@/hooks/store/use-state"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify named export path and consider importing directly from root to avoid the folder barrel.
If the goal is to eliminate barrels, import the component directly from its module file.
Apply this minimal change if root.tsx exports IssuesLayoutsRoot:
-import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts";
+import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts/root";Also validate that IssuesLayoutsRoot is a named export in the module:
🏁 Script executed:
#!/bin/bash
# Check that IssuesLayoutsRoot is exported (named or default)
rg -n "export .*IssuesLayoutsRoot|export \\{[^}]*IssuesLayoutsRoot" -A 2Length of output: 381
🏁 Script executed:
#!/bin/bash
# List all files directly under the issue-layouts directory
find apps/space/core/components/issues/issue-layouts -maxdepth 1 -type fLength of output: 453
🏁 Script executed:
#!/bin/bash
# Check if IssuesLayoutsRoot is re-exported in the barrel file
rg -n "IssuesLayoutsRoot" -A 5 apps/space/core/components/issues/issue-layouts/index.tsLength of output: 87
🏁 Script executed:
#!/bin/bash
# Display the contents of the barrel file to verify exports
sed -n '1,200p' apps/space/core/components/issues/issue-layouts/index.tsLength of output: 96
Import IssuesLayoutsRoot directly from its module
Since apps/space/core/components/issues/issue-layouts/index.ts merely re-exports from root.tsx, you can avoid the folder barrel by importing the component straight from its source file:
• In apps/space/app/issues/[anchor]/page.tsx, update the import:
-import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts";
+import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts/root";This makes the dependency explicit and removes the indirection through the barrel.
📝 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.
| import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts"; | |
| // hooks | |
| import { usePublish, useLabel, useStates } from "@/hooks/store"; | |
| import { usePublish } from "@/hooks/store/publish"; | |
| import { useLabel } from "@/hooks/store/use-label"; | |
| import { useStates } from "@/hooks/store/use-state"; | |
| import { IssuesLayoutsRoot } from "@/components/issues/issue-layouts/root"; | |
| // hooks | |
| import { usePublish } from "@/hooks/store/publish"; | |
| import { useLabel } from "@/hooks/store/use-label"; | |
| import { useStates } from "@/hooks/store/use-state"; |
🤖 Prompt for AI Agents
In apps/space/app/issues/[anchor]/page.tsx around lines 7 to 11, the file
imports IssuesLayoutsRoot from the folder barrel
"@/components/issues/issue-layouts"; change that import to reference the actual
source file by importing directly from "@/components/issues/issue-layouts/root"
(keep the named import IssuesLayoutsRoot) so the module depends on the concrete
implementation rather than the re-exporting index barrel.
| // local imports | ||
| import { EditorMentionsRoot } from "./embeds/mentions"; | ||
| import { IssueCommentToolbar } from "./toolbar"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Imports correctly de-barreled; verify local paths resolve
Switching to local module imports for mentions and toolbar aligns with the PR goal and avoids barrel side effects.
Run this to ensure there are no remaining editor barrel imports and that these local modules exist:
🏁 Script executed:
#!/bin/bash
# 1) Check for residual editor barrel imports
rg -n $'from\\s+[\'"]@/components/editor[\'"]|from\\s+[\'"]@/components/editor/' -S || true
# 2) Confirm the local files referenced here exist
fd -a --hidden --follow --strip-cwd-prefix $'apps/space/core/components/editor/embeds/mentions.tsx\napps/space/core/components/editor/toolbar.tsx' \
--exec bash -lc 'for f; do [[ -f "$f" ]] && echo "FOUND $f" || echo "MISSING $f"; done' _Length of output: 3204
🏁 Script executed:
#!/bin/bash
# 1) Check for any remaining @/components/editor barrel imports within apps/space
rg -n "from\s+['\"]@/components/editor(/|['\"])" --glob "apps/space/**/*" || true
# 2) Confirm the local modules referenced by lite-text-editor.tsx actually exist
for f in \
apps/space/core/components/editor/embeds/mentions.tsx \
apps/space/core/components/editor/toolbar.tsx; do
if [[ -f "$f" ]]; then
echo "FOUND $f"
else
echo "MISSING $f"
fi
doneLength of output: 1108
Missing local module & residual barrel imports detected
The import in apps/space/core/components/editor/lite-text-editor.tsx:
import { EditorMentionsRoot } from "./embeds/mentions";points to apps/space/core/components/editor/embeds/mentions.tsx, which does not exist. Please either:
- Add the missing embeds/mentions.tsx module
- Or correct the import path to the actual file location
Additionally, there are still editor imports using the @/components/editor alias under apps/space:
- apps/space/core/components/issues/peek-overview/comment/add-comment.tsx
- apps/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx
- apps/space/core/components/issues/peek-overview/issue-details.tsx
Please update these to match the new file structure or confirm they resolve correctly.
🤖 Prompt for AI Agents
In apps/space/core/components/editor/lite-text-editor.tsx around lines 10-12 the
import "import { EditorMentionsRoot } from \"./embeds/mentions\";" points to a
non-existent file; either create
apps/space/core/components/editor/embeds/mentions.tsx exporting
EditorMentionsRoot or change the import to the correct relative path where
EditorMentionsRoot actually lives. Also audit and update the remaining
barrel/alias imports under apps/space that still use "@/components/editor" in
these files:
apps/space/core/components/issues/peek-overview/comment/add-comment.tsx,
apps/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx,
and apps/space/core/components/issues/peek-overview/issue-details.tsx — replace
the alias with the new relative paths or adjust the barrel exports so they
resolve correctly.
| import { IssueEmojiReactions } from "@/components/issues/reactions/issue-emoji-reactions"; | ||
| import { IssueVotes } from "@/components/issues/reactions/issue-vote-reactions"; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use granular hook import; avoid leftover publish barrel
The reactions components are correctly imported from their files. However, usePublish still comes from the publish index, which goes against the de-barreling objective. Import the hook directly from its module.
Apply:
-import { usePublish } from "@/hooks/store/publish";
+import { usePublish } from "@/hooks/store/publish/use-publish";Also applies to: 9-9
🤖 Prompt for AI Agents
In apps/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx
(around lines 6-7 and line 9), replace the indirect import of usePublish from
the publish barrel with a direct import from the specific module that exports
the hook (i.e., update the import path to the hook's file instead of
"@/components/publish" or similar); ensure the other reaction component imports
remain unchanged and run a quick TypeScript build to verify the new path is
correct.
| import { IssueVotes } from "@/components/issues/reactions/issue-vote-reactions"; | ||
| // hooks | ||
| import { usePublish } from "@/hooks/store"; | ||
| import { usePublish } from "@/hooks/store/publish"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
AI summary mismatch: code still uses publish index
The AI summary states usePublish was moved to .../publish/use-publish.ts, but this file imports from .../publish (index). Please align the code with the stated direction.
Verify there is no index.ts re-export under the publish hook directory and that the granular file exists:
🏁 Script executed:
#!/bin/bash
# Look for an index in any publish hook directory that might re-export hooks
fd -a --hidden --follow 'hooks/store/publish' | while read -r d; do
if [[ -d "$d" ]]; then
if [[ -f "$d/index.ts" || -f "$d/index.tsx" ]]; then
echo "Found potential barrel: $d/index.ts*"
rg -n "export\\s+\\*|export\\s+\\{.*usePublish.*\\}" "$d/index.ts" "$d/index.tsx" 2>/dev/null || true
fi
fi
done
# Ensure granular file exists
fd -a --hidden --follow 'use-publish.ts' | rg -n 'hooks/store/publish' -n || echo "Granular use-publish.ts not found under hooks/store/publish"Length of output: 201
Align usePublish import to the granular hook file
The usePublish hook now lives in hooks/store/publish/use-publish.ts and there is no barrel (index.ts) under that directory. Update the import in:
• apps/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx (line 9)
- import { usePublish } from "@/hooks/store/publish";
+ import { usePublish } from "@/hooks/store/publish/use-publish";📝 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.
| import { usePublish } from "@/hooks/store/publish"; | |
| import { usePublish } from "@/hooks/store/publish/use-publish"; |
🤖 Prompt for AI Agents
In apps/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx
around line 9, the import path for usePublish must be updated because the hook
now lives in hooks/store/publish/use-publish.ts and there is no barrel export;
change the import from "@/hooks/store/publish" to
"@/hooks/store/publish/use-publish" (keep the same named import syntax: {
usePublish }) so the file imports directly from the new module path.
| import { useCycle } from "@/hooks/store/use-cycle"; | ||
| import { useLabel } from "@/hooks/store/use-label"; | ||
| import { useMember } from "@/hooks/store/use-member"; | ||
| import { useModule } from "@/hooks/store/use-module"; | ||
| import { useStates } from "@/hooks/store/use-state"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Granular hook imports replacing the store barrel look good.
This aligns with the PR objective and reduces accidental side-effects/cycles from barrels.
Run this quick scan to catch any remaining barrel usages so the refactor is complete and consistent:
🏁 Script executed:
#!/bin/bash
# Find remaining barrel imports to replace with granular module paths
set -euo pipefail
echo "Scanning for store barrel imports..."
rg -n -S $'from\\s+[\'"]@/hooks/store[\'"]' || true
echo "Scanning for issues components barrel imports..."
rg -n -S $'from\\s+[\'"]@/components/issues[\'"]' || true
echo "Scanning for old filters helpers barrel imports..."
rg -n -S $'from\\s+[\'"]@/components/issues/filters/helpers[\'"]' || trueLength of output: 103301
Replace remaining barrel imports in the codebase
I ran the scan and found numerous leftover barrel imports that need to be updated to granular paths:
-
@/hooks/storebarrels (hundreds of hits) in files like
• apps/web/core/components/account/deactivate-account-modal.tsx:12
• apps/web/core/components/onboarding/header.tsx:13
• apps/web/core/components/command-palette/command-palette.tsx:16
…and many more acrossapps/web/coreandapps/web/ce. -
@/components/issuesbarrels (dozens of hits) in files like
• apps/web/core/store/issue/issue-details/relation.store.ts:9
• apps/web/core/components/common/filters/created-at.tsx:7
• apps/web/core/components/workspace/sidebar/quick-actions.tsx:11
…and many more. -
No occurrences of the old
@/components/issues/filters/helpersbarrel remain.
Next steps:
• Replace each import { … } from "@/hooks/store"; with the exact hook path, e.g.
import { useUser } from "@/hooks/store/use-user";
• Replace each import { … } from "@/components/issues"; with the specific component paths, e.g.
import FilterHeader from "@/components/issues/filters/FilterHeader";
This will complete the refactor and ensure we avoid unintended side-effects from barrel imports.
🤖 Prompt for AI Agents
In apps/space/core/components/issues/issue-layouts/kanban/default.tsx around
lines 16-20 the file imports multiple hooks from the barrel "@/hooks/store";
replace each barrel import with its granular path (e.g., import useCycle from
"@/hooks/store/use-cycle", useLabel from "@/hooks/store/use-label", useMember
from "@/hooks/store/use-member", useModule from "@/hooks/store/use-module",
useStates from "@/hooks/store/use-state") so each hook is imported from its
exact file; also scan the file for any other barrel imports (including
"@/components/issues") and replace them with their specific component paths
accordingly.
| import { IssuePeekOverview } from "@/components/issues/peek-overview"; | ||
| // hooks |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Potential remaining barrel import: peek-overview index
This still imports from "@/components/issues/peek-overview" which likely resolves to an index barrel. To fully meet the “remove all barrel exports” objective, switch to a concrete module (e.g., root component file) if available.
Run this to locate the concrete module for IssuePeekOverview:
If a concrete file is found (e.g., peek-overview/root.tsx), prefer:
- import { IssuePeekOverview } from "@/components/issues/peek-overview/root";
🏁 Script executed:
#!/bin/bash
# Find where IssuePeekOverview is declared and the file that exports it.
rg -n -A2 -F "export const IssuePeekOverview" --glob '!**/dist/**'
rg -n -A2 -F "export default IssuePeekOverview" --glob '!**/dist/**'
# Find index files that re-export it (potential barrels).
fd -a --glob "index.{ts,tsx}" | xargs -I{} rg -n -F "IssuePeekOverview" {}Length of output: 1781
🏁 Script executed:
#!/bin/bash
# List any index barrel files in the peek-overview directories for space and web apps
echo "Space peek-overview directory index files:"
fd -t f -g "apps/space/core/components/issues/peek-overview/index.ts*"
echo "Web peek-overview directory index files:"
fd -t f -g "apps/web/core/components/issues/peek-overview/index.ts*"Length of output: 329
Specify concrete path for IssuePeekOverview import
The import from "@/components/issues/peek-overview" currently relies on an implicit barrel that doesn’t exist. You should point directly to the file where IssuePeekOverview is declared:
• In apps/space/core/components/issues/issue-layouts/root.tsx (lines 8–9)
Change:
- import { IssuePeekOverview } from "@/components/issues/peek-overview";
+ import { IssuePeekOverview } from "@/components/issues/peek-overview/layout";📝 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.
| import { IssuePeekOverview } from "@/components/issues/peek-overview"; | |
| // hooks | |
| import { IssuePeekOverview } from "@/components/issues/peek-overview/layout"; | |
| // hooks |
🤖 Prompt for AI Agents
In apps/space/core/components/issues/issue-layouts/root.tsx around lines 8–9,
the import uses a non-existent barrel "@/components/issues/peek-overview" —
replace it with the concrete file path that directly exports IssuePeekOverview
(the exact .tsx/.ts file that declares and exports that component, e.g.
"@/components/issues/peek-overview/IssuePeekOverview" or
"@/components/issues/peek-overview/index.tsx"); update the import statement to
reference that specific file and ensure the named/default export matches the
import.
| import { usePublish } from "@/hooks/store"; | ||
| // plane imports | ||
| import { RichTextEditor } from "@/components/editor/rich-text-editor"; | ||
| import { usePublish } from "@/hooks/store/publish"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Potential leftover barrel: import usePublish from directory index
@/hooks/store/publish may still be an index barrel. To fully meet the “remove barrels” objective, import the concrete module directly (assuming it exists).
Proposed change:
-import { usePublish } from "@/hooks/store/publish";
+import { usePublish } from "@/hooks/store/publish/use-publish";Run this script to verify the concrete file path and detect any barrel index remaining:
🏁 Script executed:
#!/bin/bash
# Verify if a barrel export exists and if a concrete file is available
set -euo pipefail
echo "Finding concrete use-publish module..."
fd -t f -a 'use-publish.*' | sed 's/^/ - /'
echo "Checking if an index barrel exists under hooks/store/publish..."
fd -t f -a 'hooks/store/publish/index.*' | sed 's/^/ - /'Length of output: 570
Update import to concrete module path
The usePublish hook lives in a standalone file—there’s no index barrel under hooks/store/publish. Update the import to point directly at use-publish.ts:
• File: apps/space/core/components/issues/peek-overview/issue-details.tsx (line 4)
-import { usePublish } from "@/hooks/store/publish";
+import { usePublish } from "@/hooks/store/publish/use-publish";📝 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.
| import { usePublish } from "@/hooks/store/publish"; | |
| import { usePublish } from "@/hooks/store/publish/use-publish"; |
🤖 Prompt for AI Agents
In apps/space/core/components/issues/peek-overview/issue-details.tsx around line
4, the import currently references the barrel path "hooks/store/publish" but the
hook is exported from a standalone file; update the import to point directly to
the concrete module file (use-publish.ts) by changing the import path to the
file's relative path (e.g., "@/hooks/store/publish/use-publish") so the module
resolves correctly.
| import { usePublish } from "@/hooks/store/publish"; | ||
| import { useStates } from "@/hooks/store/use-state"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Granular store hook imports replace barrel — looks good; verify no stragglers
Direct module imports for usePublish and useStates align with the PR goal and reduce accidental coupling/tree size.
Run this repo-wide check to ensure there are no remaining imports from the store barrel and to spot any leftover re-export barrels:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Searching for leftover barrel imports from '@/hooks/store'…"
rg -n -S $'from\\s+[\"\\\']@/hooks/store[\"\\\']' || echo "OK: No direct imports from '@/hooks/store' found."
echo
echo "Checking if a store barrel still re-exports anything…"
rg -n -S '^export\s+\*\s+from' -g '**/hooks/store/index.ts' || echo "OK: No re-exports found in hooks/store/index.ts (or file absent)."
echo
echo "Scanning for re-export barrels under apps/space/**/hooks/**/index.ts…"
rg -n -S '^export\s+\*\s+from' -g 'apps/space/**/hooks/**/index.ts' || echo "OK: No re-export barrels under hooks."
echo
echo "Scanning for any remaining barrel-style re-exports across space app index files…"
rg -n -S '^export\s+\*\s+from' -g 'apps/space/**/index.ts' || echo "OK: No barrel-style re-exports detected in index files."Length of output: 5693
Remaining store hook barrels detected — please remove or refactor
Our scan confirms no direct imports from the old @/hooks/store barrel in apps/space, but found these lingering re-export barrels for store hooks that undermine tree-shaking and granular imports:
- apps/space/core/hooks/store/publish/index.ts
- apps/space/ce/hooks/store/index.ts
- apps/space/ee/hooks/store/index.ts
Please remove or refactor these so that consumers import hooks directly (e.g. import { usePublish } from '…/use-publish') rather than via an intermediate index.ts.
🤖 Prompt for AI Agents
In apps/space/core/components/issues/peek-overview/issue-properties.tsx around
lines 17-18, the file imports store hooks via barrel re-exports which prevents
tree-shaking; change the two imports to point directly at the hook modules (e.g.
replace "@/hooks/store/publish" with the direct path to the publish hook file,
and "@/hooks/store/use-state" with the direct use-state hook file), remove or
refactor the three barrel index files listed
(apps/space/core/hooks/store/publish/index.ts,
apps/space/ce/hooks/store/index.ts, apps/space/ee/hooks/store/index.ts) so no
code re-exports hooks, and update any other consumers to use the same
direct-path imports; run the build/linters to confirm no broken imports remain.
| // components | ||
| import { IssueEmojiReactions } from "@/components/issues/reactions/issue-emoji-reactions"; | ||
| import { IssueVotes } from "@/components/issues/reactions/issue-vote-reactions"; | ||
| // hooks | ||
| import { usePublish } from "@/hooks/store"; | ||
| import { usePublish } from "@/hooks/store/publish"; | ||
| import useIsInIframe from "@/hooks/use-is-in-iframe"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Confirm granular component and hook exports after barrel removal
- IssueEmojiReactions and IssueVotes are now imported from their concrete files; ensure they are exported as named exports with these exact identifiers.
- usePublish is imported from "@/hooks/store/publish"; confirm this path resolves to an index.ts exporting usePublish, or change to the concrete file (e.g., "@/hooks/store/publish/use-publish") consistently.
Use this script to validate the exports:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking reactions components:"
fd -a 'issue-emoji-reactions.tsx' | while read -r f; do
echo "--- $f"
rg -n 'export\s+default|export\s+(const|function|class)\s+IssueEmojiReactions|export\s*\{[^}]*IssueEmojiReactions' "$f" || true
done
fd -a 'issue-vote-reactions.tsx' | while read -r f; do
echo "--- $f"
rg -n 'export\s+default|export\s+(const|function|class)\s+IssueVotes|export\s*\{[^}]*IssueVotes' "$f" || true
done
echo
echo "Checking usePublish export path:"
# Prefer index.ts re-export, otherwise ensure use-publish.ts exports it
fd -a 'apps/space/core/hooks/store/publish' -t d || true
fd -a 'apps/space/core/hooks/store/publish/index.ts' || true
fd -a 'use-publish.ts' | while read -r f; do
echo "--- $f"
rg -n 'export\s+default|export\s+(const|function)\s+usePublish|export\s*\{[^}]*usePublish' "$f" || true
doneLength of output: 2225
Fix missing barrel export for usePublish
-
The
IssueEmojiReactionsandIssueVotescomponents are correctly exported as named exports. -
The
usePublishhook isn’t re-exported via anindex.tsinhooks/store/publish, so the import path@/hooks/store/publishwill fail to resolve.Update the import in
apps/space/core/components/issues/peek-overview/issue-reaction.tsx:- import { usePublish } from "@/hooks/store/publish"; + import { usePublish } from "@/hooks/store/publish/use-publish";
-
Alternatively, if you’d prefer to keep the directory import, add an
index.tsunder
apps/space/core/hooks/store/publish:export { usePublish } from "./use-publish";
🤖 Prompt for AI Agents
In apps/space/core/components/issues/peek-overview/issue-reaction.tsx around
lines 2 to 7, the import for usePublish currently points to
"@/hooks/store/publish" but that directory lacks a barrel export; either change
the import to reference the actual file (e.g.
"@/hooks/store/publish/use-publish") or add an index.ts under
apps/space/core/hooks/store/publish that re-exports usePublish (export {
usePublish } from "./use-publish") so the current path resolves.
Description
This PR removes all the barrel exports from the space app.
Type of Change
Summary by CodeRabbit
New Features
Refactor
Chores