Repository navigation
feat: filter tasks that are waiting for user input - #19377
Conversation
| // TODO: This is a temporary solution while the BE does not return the Task in a | ||
| // right shape with a custom name. This should be removed once the BE is fixed. |
johnstcn
left a comment
There was a problem hiding this comment.
LGTM, but deferring approval to FE domain experts.
| value?: string; | ||
| }; | ||
|
|
||
| function useUsersOptions({ query, value }: UseUsersOptionsOptions) { |
There was a problem hiding this comment.
this doesn't really need to be a hook imo. it should be a query function like we generally use, and it can take user as an argument.
There was a problem hiding this comment.
I know, but IMO, it encapsulates the intention quite well and improve the readability. It makes easier for me to know where and for what things are being used for. Eg. It is clear for me for what the useQuery and usesAuthenticated are being used for.
Unfortunately, you can't use hooks inside of regular functions, but I'm happy to change the code to use any existent convention.
There was a problem hiding this comment.
the entirety of this hook except for const { user } = useAuthenticated(); can be encapsulated in a query options function tho! and that better matches how we do it everywhere else.
Unfortunately, you can't use hooks inside of regular functions
and this is part of why I am so against custom hooks in 90% of use cases. they're viral function coloring, and should be avoided unless they are actually necessary to encapsulate stateful logic. I don't think that's the case here, as all of the logic is independent of the state.
There was a problem hiding this comment.
I think the new React docs on custom hooks are very insightful. Even they don't think people should really be making custom hooks most of the time!
| export const data = { | ||
| async createTask( | ||
| prompt: string, | ||
| userId: string, | ||
| templateVersionId: string, | ||
| presetId: string | undefined, | ||
| ): Promise<Task> { | ||
| const workspace = await API.experimental.createTask(userId, { | ||
| name: `task-${generateWorkspaceName()}`, | ||
| template_version_id: templateVersionId, | ||
| template_version_preset_id: presetId, | ||
| prompt, | ||
| }); | ||
|
|
||
| return { | ||
| workspace, | ||
| prompt, | ||
| }; | ||
| }, | ||
| }; |
There was a problem hiding this comment.
I don't understand the need for this data wrapper. why not just export the function directly?
There was a problem hiding this comment.
Because of some spyOn limitations 😢. I'm not able to make it work when doing the following:
import * as data from "./data"
spyOn(data, "createTask")Cannot spy on export "createTask". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations
But it should be temporary, since the create task API should handle that.
| }; | ||
|
|
||
| const sortSelectedFirst = (a: User) => | ||
| value && a.username === value ? -1 : 0; |
There was a problem hiding this comment.
this doesn't hand the case where a.username === a.username
There was a problem hiding this comment.
Not sure if I got it 🤔
There was a problem hiding this comment.
I can't even blame you, writing sorting functions is really unintuitive. 😅
if a.username === a.username and a.username === value you'll still return -1 when you should return 0. they're both the selected user, so you shouldn't be preferring one over the other. although I guess saying it out loud, that case probably won't ever come up except maybe in tests that don't generate unique usernames.
There was a problem hiding this comment.
Would it be ok if we let this as it is?
Co-authored-by: ケイラ <[email protected]>
Co-authored-by: ケイラ <[email protected]>
| const [firstTask, ...otherTasks] = MockTasks; | ||
| spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); | ||
| spyOn(API.experimental, "getTasks").mockResolvedValue([ | ||
| { | ||
| ...firstTask, | ||
| workspace: { | ||
| ...firstTask.workspace, | ||
| latest_app_status: { | ||
| ...firstTask.workspace.latest_app_status, | ||
| state: "idle" as const, | ||
| }, | ||
| }, | ||
| }, | ||
| ...otherTasks, | ||
| ]); |
There was a problem hiding this comment.
this might be a nice opportunity to use structuredClone to mask some noise:
| const [firstTask, ...otherTasks] = MockTasks; | |
| spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); | |
| spyOn(API.experimental, "getTasks").mockResolvedValue([ | |
| { | |
| ...firstTask, | |
| workspace: { | |
| ...firstTask.workspace, | |
| latest_app_status: { | |
| ...firstTask.workspace.latest_app_status, | |
| state: "idle" as const, | |
| }, | |
| }, | |
| }, | |
| ...otherTasks, | |
| ]); | |
| spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); | |
| const tasks = structuredClone(MockTasks); | |
| tasks[0].workspace.latest_app_status.state = "idle"; | |
| spyOn(API.experimental, "getTasks").mockResolvedValue(tasks); |
There was a problem hiding this comment.
There is an issue with that, structuredClone keep the read only structure causing an TS error.
Cannot assign to 'state' because it is a read-only property.
| spyOn(API.experimental, "getTasks").mockResolvedValue([ | ||
| { | ||
| ...firstTask, | ||
| workspace: { | ||
| ...firstTask.workspace, | ||
| latest_app_status: { | ||
| ...firstTask.workspace.latest_app_status, | ||
| state: "idle" as const, | ||
| }, | ||
| }, | ||
| // biome-ignore lint/suspicious/noExplicitAny: Testing malformed data edge cases | ||
| ] as any; | ||
| }, | ||
| ...otherTasks, | ||
| ]); |
| ); | ||
| } | ||
|
|
||
| const PillButton = ({ className, active, ...props }: PillButtonProps) => { |
There was a problem hiding this comment.
FC?
also, seems like a good candidate for a general component. might be worth moving to components/.
There was a problem hiding this comment.
seems like a good candidate for a general component.
Wdyt about waiting for more use cases using it?
| }; | ||
|
|
||
| const sortSelectedFirst = (a: User) => | ||
| value && a.username === value ? -1 : 0; |
There was a problem hiding this comment.
I can't even blame you, writing sorting functions is really unintuitive. 😅
if a.username === a.username and a.username === value you'll still return -1 when you should return 0. they're both the selected user, so you shouldn't be preferring one over the other. although I guess saying it out loud, that case probably won't ever come up except maybe in tests that don't generate unique usernames.
Co-authored-by: ケイラ <[email protected]>
Co-authored-by: ケイラ <[email protected]>
Co-authored-by: ケイラ <[email protected]>
|
@aslilac hooks refactored and other requests added. ✅ |
Closes #19324