Skip to content

Commit eeb43b8

Browse files
Search and results work for all HomeItems
1 parent a05c129 commit eeb43b8

File tree

6 files changed

+373
-222
lines changed

6 files changed

+373
-222
lines changed

src/components/HomeSearchBar.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import Fuse from 'fuse.js'
2+
import { useEffect, useRef, useState } from 'react'
3+
import { useHotkeys } from 'react-hotkeys-hook'
4+
5+
import { CustomIcon } from '@src/components/CustomIcon'
6+
7+
import type { Project } from '@src/lib/project'
8+
import type { Prompt } from '@src/machines/mlEphantManagerMachine'
9+
10+
export type HomeItem = Project | Prompt
11+
export type HomeItems = Project[] | Prompt[]
12+
13+
export const areHomeItemsProjects = (items: HomeItems): items is Project[] => {
14+
const item = items[0]
15+
return item !== undefined && 'path' in item
16+
}
17+
18+
export const areHomeItemsPrompts = (items: HomeItems): items is Prompt[] => {
19+
const item = items[0]
20+
return item !== undefined && typeof item.prompt === 'string'
21+
}
22+
23+
export function useHomeSearch(initialSearchResults: HomeItems) {
24+
const [query, setQuery] = useState('')
25+
const [searchResults, setSearchResults] = useState<HomeItems>(initialSearchResults)
26+
27+
useEffect(() => {
28+
setSearchResults(initialSearchResults)
29+
}, [initialSearchResults])
30+
31+
const searchAgainst = (items: HomeItems) => (queryRequested: string) => {
32+
const nameKeyToMatchAgainst = areHomeItemsProjects(items) ? 'name' : 'prompt'
33+
34+
const fuse = new Fuse(items, {
35+
keys: [{ name: nameKeyToMatchAgainst, weight: 0.7 }],
36+
includeScore: true,
37+
})
38+
39+
const results = fuse.search(queryRequested).map((result) => result.item)
40+
41+
// On an empty query, we consider that matching all items.
42+
setSearchResults(queryRequested.length > 0 ? results : items)
43+
setQuery(queryRequested)
44+
}
45+
46+
return {
47+
searchAgainst,
48+
searchResults,
49+
query,
50+
}
51+
}
52+
53+
export function HomeSearchBar({
54+
onChange,
55+
}: {
56+
onChange: (query: string) => void
57+
}) {
58+
const inputRef = useRef<HTMLInputElement>(null)
59+
useHotkeys(
60+
'Ctrl+.',
61+
(event) => {
62+
event.preventDefault()
63+
inputRef.current?.focus()
64+
},
65+
{ enableOnFormTags: true }
66+
)
67+
68+
return (
69+
<div className="relative group">
70+
<div className="flex items-center gap-2 py-0.5 pl-0.5 pr-2 rounded border-solid border border-primary/10 dark:border-chalkboard-80 focus-within:border-primary dark:focus-within:border-chalkboard-30">
71+
<CustomIcon
72+
name="search"
73+
className="w-5 h-5 rounded-sm bg-primary/10 dark:bg-transparent text-primary dark:text-chalkboard-10 group-focus-within:bg-primary group-focus-within:text-chalkboard-10"
74+
/>
75+
<input
76+
ref={inputRef}
77+
onChange={(event) => onChange(event.target.value)}
78+
className="w-full text-sm bg-transparent focus:outline-none selection:bg-primary/20 dark:selection:bg-primary/40 dark:focus:outline-none"
79+
placeholder="Search (Ctrl+.)"
80+
autoCapitalize="off"
81+
autoComplete="off"
82+
autoCorrect="off"
83+
spellCheck="false"
84+
/>
85+
</div>
86+
</div>
87+
)
88+
}

src/components/ProjectSearchBar.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/components/PromptCard.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface PromptCardProps {}
2+
3+
export const PromptCard = (props: PromptCardProps) => {
4+
return <div>yo</div>
5+
}

src/lib/prompt.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import type { Models } from '@kittycad/lib'
2+
3+
export type Prompt = Models['TextToCad_Type']
4+
5+
// export interface TextToCad_type {
6+
// code?: string;
7+
// completed_at?: string;
8+
// created_at: string;
9+
// error?: string;
10+
// feedback?: MlFeedback_type;
11+
// id: Uuid_type;
12+
// kcl_version?: string;
13+
// model: TextToCadModel_type;
14+
// model_version: string;
15+
// output_format: FileExportFormat_type;
16+
// outputs: {
17+
// [key: string]: string;
18+
// };
19+
// prompt: string;
20+
// started_at?: string;
21+
// status: ApiCallStatus_type;
22+
// updated_at: string;
23+
// user_id: Uuid_type;
24+
// }
25+
// export interface TextToCadCreateBody_type {
26+
// kcl_version?: string;
27+
// project_name?: string;
28+
// prompt: string;
29+
// }
30+
// export interface TextToCadIteration_type {
31+
// code: string;
32+
// completed_at?: string;
33+
// created_at: string;
34+
// error?: string;
35+
// feedback?: MlFeedback_type;
36+
// id: Uuid_type;
37+
// model: TextToCadModel_type;
38+
// model_version: string;
39+
// original_source_code: string;
40+
// prompt?: string;
41+
// source_ranges: SourceRangePrompt_type[];
42+
// started_at?: string;
43+
// status: ApiCallStatus_type;
44+
// updated_at: string;
45+
// user_id: Uuid_type;
46+
// }
47+
// export interface TextToCadIterationBody_type {
48+
// kcl_version?: string;
49+
// original_source_code: string;
50+
// project_name?: string;
51+
// prompt?: string;
52+
// source_ranges: SourceRangePrompt_type[];
53+
// }
54+
// export interface TextToCadMultiFileIteration_type {
55+
// completed_at?: string;
56+
// created_at: string;
57+
// error?: string;
58+
// feedback?: MlFeedback_type;
59+
// id: Uuid_type;
60+
// kcl_version?: string;
61+
// model: TextToCadModel_type;
62+
// model_version: string;
63+
// outputs: {
64+
// [key: string]: string;
65+
// };
66+
// project_name?: string;
67+
// prompt?: string;
68+
// source_ranges: SourceRangePrompt_type[];
69+
// started_at?: string;
70+
// status: ApiCallStatus_type;
71+
// updated_at: string;
72+
// user_id: Uuid_type;
73+
// }
74+
// export interface TextToCadMultiFileIterationBody_type {
75+
// kcl_version?: string;
76+
// project_name?: string;
77+
// prompt?: string;
78+
// source_ranges: SourceRangePrompt_type[];
79+
// }
80+
// export interface TextToCadResultsPage_type {
81+
// items: TextToCad_type[];
82+
// next_page?: string;
83+
// }
84+
85+
export const generateFakeSubmittedPrompt = () => ({
86+
code: Math.random().toString(),
87+
completed_at: Math.random().toString(),
88+
created_at: Math.random().toString(),
89+
error: Math.random().toString(),
90+
// declare type MlFeedback_type = 'thumbs_up' | 'thumbs_down' | 'accepted' | 'rejected';
91+
feedback: undefined,
92+
id: Math.random().toString(),
93+
kcl_version: Math.random().toString(),
94+
// export declare type TextToCadModel_type = 'cad' | 'kcl' | 'kcl_iteration'; model : 'kcl',
95+
model_version: Math.random().toString(),
96+
// export declare type FileExportFormat_type = 'fbx' | 'glb' | 'gltf' | 'obj' | 'ply' | 'step' | 'stl';
97+
output_format: 'glb',
98+
outputs: {
99+
[Math.random().toString()]: Math.random().toString(),
100+
},
101+
prompt: Math.random().toString(),
102+
started_at: Math.random().toString(),
103+
// declare type ApiCallStatus_type = 'queued' | 'uploaded' | 'in_progress' | 'completed' | 'failed';
104+
status: 'completed',
105+
updated_at: Math.random(),
106+
// declare type ApiTokenUuid_type = string;
107+
user_id: Math.random().toString(),
108+
})

src/machines/mlEphantManagerMachine.ts

Lines changed: 1 addition & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,4 @@
1-
import type { Models } from '@kittycad/lib'
2-
3-
type Prompt = Models['TextToCad_Type']
4-
5-
// export interface TextToCad_type {
6-
// code?: string;
7-
// completed_at?: string;
8-
// created_at: string;
9-
// error?: string;
10-
// feedback?: MlFeedback_type;
11-
// id: Uuid_type;
12-
// kcl_version?: string;
13-
// model: TextToCadModel_type;
14-
// model_version: string;
15-
// output_format: FileExportFormat_type;
16-
// outputs: {
17-
// [key: string]: string;
18-
// };
19-
// prompt: string;
20-
// started_at?: string;
21-
// status: ApiCallStatus_type;
22-
// updated_at: string;
23-
// user_id: Uuid_type;
24-
// }
25-
// export interface TextToCadCreateBody_type {
26-
// kcl_version?: string;
27-
// project_name?: string;
28-
// prompt: string;
29-
// }
30-
// export interface TextToCadIteration_type {
31-
// code: string;
32-
// completed_at?: string;
33-
// created_at: string;
34-
// error?: string;
35-
// feedback?: MlFeedback_type;
36-
// id: Uuid_type;
37-
// model: TextToCadModel_type;
38-
// model_version: string;
39-
// original_source_code: string;
40-
// prompt?: string;
41-
// source_ranges: SourceRangePrompt_type[];
42-
// started_at?: string;
43-
// status: ApiCallStatus_type;
44-
// updated_at: string;
45-
// user_id: Uuid_type;
46-
// }
47-
// export interface TextToCadIterationBody_type {
48-
// kcl_version?: string;
49-
// original_source_code: string;
50-
// project_name?: string;
51-
// prompt?: string;
52-
// source_ranges: SourceRangePrompt_type[];
53-
// }
54-
// export interface TextToCadMultiFileIteration_type {
55-
// completed_at?: string;
56-
// created_at: string;
57-
// error?: string;
58-
// feedback?: MlFeedback_type;
59-
// id: Uuid_type;
60-
// kcl_version?: string;
61-
// model: TextToCadModel_type;
62-
// model_version: string;
63-
// outputs: {
64-
// [key: string]: string;
65-
// };
66-
// project_name?: string;
67-
// prompt?: string;
68-
// source_ranges: SourceRangePrompt_type[];
69-
// started_at?: string;
70-
// status: ApiCallStatus_type;
71-
// updated_at: string;
72-
// user_id: Uuid_type;
73-
// }
74-
// export interface TextToCadMultiFileIterationBody_type {
75-
// kcl_version?: string;
76-
// project_name?: string;
77-
// prompt?: string;
78-
// source_ranges: SourceRangePrompt_type[];
79-
// }
80-
// export interface TextToCadResultsPage_type {
81-
// items: TextToCad_type[];
82-
// next_page?: string;
83-
// }
84-
85-
const generateFakeSubmittedPrompt = () => ({
86-
code: Math.random().toString(),
87-
completed_at: Math.random().toString(),
88-
created_at: Math.random().toString(),
89-
error: Math.random().toString(),
90-
// declare type MlFeedback_type = 'thumbs_up' | 'thumbs_down' | 'accepted' | 'rejected';
91-
feedback: undefined,
92-
id: Math.random().toString(),
93-
kcl_version: Math.random().toString(),
94-
// export declare type TextToCadModel_type = 'cad' | 'kcl' | 'kcl_iteration'; model : 'kcl',
95-
model_version: Math.random().toString(),
96-
// export declare type FileExportFormat_type = 'fbx' | 'glb' | 'gltf' | 'obj' | 'ply' | 'step' | 'stl';
97-
output_format: 'glb',
98-
outputs: {
99-
[Math.random().toString()]: Math.random().toString(),
100-
},
101-
prompt: Math.random().toString(),
102-
started_at: Math.random().toString(),
103-
// declare type ApiCallStatus_type = 'queued' | 'uploaded' | 'in_progress' | 'completed' | 'failed';
104-
status: 'completed',
105-
updated_at: Math.random(),
106-
// declare type ApiTokenUuid_type = string;
107-
user_id: Math.random().toString(),
108-
})
1+
import type { Prompt } from '@src/lib/prompt'
1092

1103
export enum MlEphantManagerTransitionStates {
1114
GetPromptsThatCreatedProjects = 'get-prompts-that-created-projects',

0 commit comments

Comments
 (0)