@@ -5,7 +5,7 @@ import { scopedProjectKey, scopeProjectRef } from "@t3tools/client-runtime/envir
55import { isScratchProject } from "@t3tools/client-runtime/state/projects" ;
66import { FolderPlusIcon } from "lucide-react" ;
77import { useAtomValue } from "@effect/atom-react" ;
8- import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
8+ import { useEffect , useRef , useState } from "react" ;
99
1010import { openCommandPalette } from "~/commandPaletteBus" ;
1111import { shortcutLabelForCommand } from "~/keybindings" ;
@@ -72,68 +72,43 @@ export function DraftHeroHeadline({
7272 const getComposerDraft = useComposerDraftStore ( ( store ) => store . getComposerDraft ) ;
7373 const applyStickyState = useComposerDraftStore ( ( store ) => store . applyStickyState ) ;
7474 const setModelSelection = useComposerDraftStore ( ( store ) => store . setModelSelection ) ;
75- const openAddProject = useCallback ( ( ) => openCommandPalette ( { open : "add-project" } ) , [ ] ) ;
75+ const openAddProject = ( ) => openCommandPalette ( { open : "add-project" } ) ;
7676 const { scratchEnvironmentId, scratchWorkspaceRootFor, openScratchProject } = useScratchProject ( ) ;
7777 const openProjectDraft = useNewThreadHandler ( ) ;
7878 const keybindings = useAtomValue ( primaryServerKeybindingsAtom ) ;
79+ const [ pickerOpen , setPickerOpen ] = useState ( false ) ;
80+ const [ pickerQuery , setPickerQuery ] = useState ( "" ) ;
81+ const pickerFilter = useComboboxFilter ( ) ;
7982
80- const environmentLabelById = useMemo (
81- ( ) =>
82- new Map (
83- environments . map ( ( environment ) => [ environment . environmentId , environment . label ] as const ) ,
84- ) ,
85- [ environments ] ,
83+ const environmentLabelById = new Map (
84+ environments . map ( ( environment ) => [ environment . environmentId , environment . label ] as const ) ,
8685 ) ;
87- const projectGroups = useMemo (
88- ( ) =>
89- sortLogicalProjectsForSidebar (
90- buildSidebarProjectSnapshots ( {
91- projects,
92- settings : projectGroupingSettings ,
93- primaryEnvironmentId,
94- resolveEnvironmentLabel : ( environmentId ) =>
95- environmentLabelById . get ( environmentId ) ?? null ,
96- } ) ,
97- threads ,
98- projectSortOrder ,
99- ) ,
100- [
101- environmentLabelById ,
102- primaryEnvironmentId ,
103- projectGroupingSettings ,
104- projectSortOrder ,
86+ const projectGroups = sortLogicalProjectsForSidebar (
87+ buildSidebarProjectSnapshots ( {
10588 projects,
106- threads ,
107- ] ,
108- ) ;
109- const showProjectEnvironments = useMemo (
110- ( ) => projectGroupsSpanEnvironments ( projectGroups ) ,
111- [ projectGroups ] ,
112- ) ;
113- const environmentMachineById = useMemo (
114- ( ) =>
115- new Map (
116- environments . map (
117- ( environment ) =>
118- [
119- environment . environmentId ,
120- resolveEnvironmentMachineKind ( environment . serverConfig ) ,
121- ] as const ,
122- ) ,
123- ) ,
124- [ environments ] ,
89+ settings : projectGroupingSettings ,
90+ primaryEnvironmentId,
91+ resolveEnvironmentLabel : ( environmentId ) => environmentLabelById . get ( environmentId ) ?? null ,
92+ } ) ,
93+ threads ,
94+ projectSortOrder ,
12595 ) ;
126- const projectPickerEntries = useMemo (
127- ( ) =>
128- buildSidebarProjectPickerEntries ( {
129- groups : projectGroups ,
130- preferredProjectRef : activeProjectRef ,
131- } ) ,
132- [ activeProjectRef , projectGroups ] ,
96+ const showProjectEnvironments = projectGroupsSpanEnvironments ( projectGroups ) ;
97+ const environmentMachineById = new Map (
98+ environments . map (
99+ ( environment ) =>
100+ [
101+ environment . environmentId ,
102+ resolveEnvironmentMachineKind ( environment . serverConfig ) ,
103+ ] as const ,
104+ ) ,
133105 ) ;
134- const projectEntryByKey = useMemo (
135- ( ) => new Map ( projectPickerEntries . map ( ( entry ) => [ entry . group . projectKey , entry ] as const ) ) ,
136- [ projectPickerEntries ] ,
106+ const projectPickerEntries = buildSidebarProjectPickerEntries ( {
107+ groups : projectGroups ,
108+ preferredProjectRef : activeProjectRef ,
109+ } ) ;
110+ const projectEntryByKey = new Map (
111+ projectPickerEntries . map ( ( entry ) => [ entry . group . projectKey , entry ] as const ) ,
137112 ) ;
138113 const activeProjectGroup =
139114 activeProjectRef === null
@@ -148,13 +123,9 @@ export function DraftHeroHeadline({
148123 const hasResolvedProject = activeProjectTitle !== null ;
149124 const canChooseProject = projectPickerEntries . length > 0 ;
150125 const shouldShowProjectMenu = canChooseProject ;
151- const menuEntries = useMemo (
152- ( ) =>
153- projectPickerEntries . filter (
154- ( { targetProject } ) =>
155- ! isScratchProject ( targetProject , scratchWorkspaceRootFor ( targetProject . environmentId ) ) ,
156- ) ,
157- [ projectPickerEntries , scratchWorkspaceRootFor ] ,
126+ const menuEntries = projectPickerEntries . filter (
127+ ( { targetProject } ) =>
128+ ! isScratchProject ( targetProject , scratchWorkspaceRootFor ( targetProject . environmentId ) ) ,
158129 ) ;
159130 const activeProject =
160131 activeProjectRef === null
@@ -171,25 +142,19 @@ export function DraftHeroHeadline({
171142 const isScratchDraft =
172143 activeProject !== null && isScratchProject ( activeProject , scratchWorkspaceRoot ) ;
173144
174- const pickerItems = useMemo < readonly PickerItem [ ] > (
175- ( ) => [
176- ...menuEntries . map ( ( { group } ) => ( { value : group . projectKey , label : group . displayName } ) ) ,
177- { value : ADD_PROJECT_VALUE , label : "Add project" } ,
178- ] ,
179- [ menuEntries ] ,
180- ) ;
181- const [ pickerOpen , setPickerOpen ] = useState ( false ) ;
182- const [ pickerQuery , setPickerQuery ] = useState ( "" ) ;
183- const pickerFilter = useComboboxFilter ( ) ;
184- const filteredPickerItems = useMemo ( ( ) => {
185- const query = pickerQuery . trim ( ) ;
186- if ( query . length === 0 ) return pickerItems ;
187- return pickerItems . filter (
188- ( item ) =>
189- item . value !== ADD_PROJECT_VALUE &&
190- pickerFilter . contains ( item , query , ( candidate ) => candidate . label ) ,
191- ) ;
192- } , [ pickerFilter , pickerItems , pickerQuery ] ) ;
145+ const pickerItems : readonly PickerItem [ ] = [
146+ ...menuEntries . map ( ( { group } ) => ( { value : group . projectKey , label : group . displayName } ) ) ,
147+ { value : ADD_PROJECT_VALUE , label : "Add project" } ,
148+ ] ;
149+ const pickerSearch = pickerQuery . trim ( ) ;
150+ const filteredPickerItems =
151+ pickerSearch . length === 0
152+ ? pickerItems
153+ : pickerItems . filter (
154+ ( item ) =>
155+ item . value !== ADD_PROJECT_VALUE &&
156+ pickerFilter . contains ( item , pickerSearch , ( candidate ) => candidate . label ) ,
157+ ) ;
193158 const selectedPickerItem = pickerItems . find ( ( item ) => item . value === activeProjectKey ) ?? null ;
194159
195160 // The picker can change the draft's target while the no-project home is
0 commit comments