Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add sidebar to the task page#19628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
BrunoQuaresma wants to merge11 commits intomainfrombq/19573
Closed

feat: add sidebar to the task page#19628

BrunoQuaresma wants to merge11 commits intomainfrombq/19573

Conversation

BrunoQuaresma
Copy link
Collaborator

Closes#19573

Demo:

Screen.Recording.2025-08-28.at.17.11.08.mov

Goals:

  • The goal of this PR is not have a perfect sidebar yet, but setup the basics so we can iterate on improvements.
    • Being able to navigate between tasks easily
    • Filter tasks by user

@BrunoQuaresmaBrunoQuaresma requested a review froma teamAugust 28, 2025 20:13
@BrunoQuaresmaBrunoQuaresma self-assigned thisAug 28, 2025
@BrunoQuaresmaBrunoQuaresma requested review fromParkreiner and removed request fora teamAugust 28, 2025 20:13
@BrunoQuaresmaBrunoQuaresma requested a review froma teamAugust 29, 2025 12:12
@brettkolodny
Copy link
Contributor

A few questions:

  1. A silly question because I haven't done dev on this part of the app yet, how do I get to this locally? Do we have some docs on how to set up tasks for development?.
  2. Is there an RFC or some greater discussion about the features being added here? I.e. how important is being able to switch users on this page? It's taking up a good chunk of vertical realestate but I don't 100% understand the use case here. Do we expect people to be collaborating often between tasks?
  3. I understand we aren't striving for perfection, but is this going to be immediately user facing? I think there are a lot of small improvements we can make to improve the UI/UX here so we don't need to worry about it in the immediate future. Happy to help here in that regard.

@BrunoQuaresma
Copy link
CollaboratorAuthor

A silly question because I haven't done dev on this part of the app yet, how do I get to this locally? Do we have some docs on how to set up tasks for development?.

@BrunoQuaresma
Copy link
CollaboratorAuthor

BrunoQuaresma commentedAug 29, 2025
edited
Loading

@brettkolodny

  1. To easily have access to tasks, you can run the FE pointing to our dogfood deployment that is already setup for that.Here are the docs.
  2. There is no RFC, we are iterating very fast on this based on customer feedback.
  3. Task is on Beta, and IMO, it is an improvement from the existent UI, so other improvements can be done later on or right after this PR gets merged.

Copy link
Contributor

@brettkolodnybrettkolodny left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Without doing a deep dive I see a bunch of stuff that need some more attention:

  • "use client"; Isn't this for fullstack frameworks? I don't think it does anything here
  • Do we need auseMobile hook? I feel like this could be accomplished all within CSS
  • The folderLayotuSidebar is misspelled
  • TheuseQuery inUsersCombobox has no error handling
  • Cookies seem like a strange choice for controlling the sidebar state. Is there a reason we couldn't do this with React state?
  • I could be wrong but a lot of theseuseMemos anduseCallbacks don't seem to be necessary, but I need to look more into them first

This isn't my final review but I wanted to flag these issues, and also get some feedback from someone with more frontend experience like@Parkreiner to take a look at as well

@BrunoQuaresma
Copy link
CollaboratorAuthor

BrunoQuaresma commentedAug 29, 2025
edited
Loading

@brettkolodny most of these points are related to shadcn component implementation provided by them. To make it easier in the future to upgrade/update them, I would leave them as they are.

About the other topics:

  • The folder LayotuSidebar is misspelled ✅
  • The useQuery in UsersCombobox has no error handling ❓
    • What action would you recommend to improve the UX?

@brettkolodny
Copy link
Contributor

brettkolodny commentedAug 29, 2025
edited
Loading

The useQuery in UsersCombobox has no error handling ❓
What action would you recommend to improve the UX?

It seems like a common action within the code base would be to show an error

most of these points are related to shadcn component implementation provided by them. To make it easier in the future to upgrade/update them, I would leave them as they are.

Gotcha! I'd want to hear someone else's thoughts on this. I generally enjoy shad's smaller components but for something this large the implementation seems odd... I'm curious what their rationale is for doing it this way, and whether or not we should just wholesale add it to the code base or if something similar is possible. Especially if this is the only place we're using this sidebar.

Task is on Beta, and IMO, it is an improvement from the existent UI, so other improvements can be done later on or right after this PR gets merged.

Honestly I still want to see some more thought put into this UI. I'm immediately seeing some things that could be improved in terms of spacing, and placement. I'll follow up in a few minutes with an example improvement. While I understand that it's better than what we have I worry about adding "design debt". There are a lot of places in the app currently that need some love and I'd rather have things in a baseline state that we're happy to shit to customers

@brettkolodny
Copy link
Contributor

This is really only touching the sidebar but to me this already feels cleaner

CleanShot.2025-08-29.at.14.17.37.mp4

Some other notes though

  • currently there isn't really a way to get back to the rest of Coder (the Coder icon in the sidebar doesn't lead anywhere)
  • Is keeping the normal top nav taking up too much space? Losing it for just this screen is strange IMO. Maybe a better UX for this page would be a full screen modal so users don't lose the context of the page they were on. If that's the case I think we could also lose the nav bar and keep the old page. Happy to expand on this as well

@brettkolodny
Copy link
Contributor

brettkolodny commentedAug 29, 2025
edited
Loading

I played around a bit to get this page inside the DashboardLayout and I think it has enough vertical space, and also just feels much more like a proper part of the app. Though still need to think of a way to get back to the normal Tasks page in an intuitive way

CleanShot 2025-08-29 at 14 31 31@2x

And if you want to optimize the preview's vertical space you can move the top bar to just the sidebar
CleanShot 2025-08-29 at 14 42 35@2x

@jaaydenh
Copy link
Contributor

  1. Regarding the tasks being full-screen, I can imagine this could be beneficial for users working heavily in tasks to have as much screen space as possible. It would be good to confirm if fullscreen is intentioal and how the user enters/exists tasks.

  2. Placement of the user picker: For me it feels better to have this in the sidebar as Bruno has it instead of at the top inline with the icon to open and close the sidebar. This matches existing design patterns in other AI apps with collapsing sidebars and limiting the UI that exists at the top of the sidebar will make it easier to reduce the size of the sidebar.

  3. Regarding shadcn, one of the main reasons to use it is to be able to move faster without having to re-invent entire components.

@brettkolodny
Copy link
Contributor

brettkolodny commentedAug 29, 2025
edited
Loading

@jaaydenh

It would be good to confirm if fullscreen is intentioal and how the user enters/exists tasks.

Yeah agreed, if it's going to be full screen we need the story about entering and leaving the state needs to be better.

Placement of the user picker: For me it feels better to have this in the sidebar as Bruno has it instead of at the top inline with the icon to open and close the sidebar. This matches existing design patterns in other AI apps with collapsing sidebars and limiting the UI that exists at the top of the sidebar will make it easier to reduce the size of the sidebar.

IMO the spacing is awkward, but maybe making that and making the user picker full width would fix some of my initial pullback. But also what I have above is still collapsible I just forgot to take a video of that. But either way if y'all feel strongly that this is the way to go then that's fine

Regarding shadcn, one of the main reasons to use it is to be able to move faster without having to re-invent entire components.

I get that, but I think in this sense maybe it's a bit overkill? I've made similar components from scratch before with a lot of success, and they were more flexible/simpler than this. This sidebar component is very opinionated and seems better suited for entire application navigation. If we just want something that can collapse that should be pretty easy to do, I do similar things in the Dynamic Parameters playground

Copy link
Member

@ParkreinerParkreiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm really concerned about some of these code changes, and I wasn't able to get Git authenticated properly when using the Dogfood backend with the dev frontend, so I wasn't able to test this yet

I'm just throwing out comments for what sticks out to me from glancing at the code, but I'm happy to pair with you on Tuesday so that we can get you unstuck. At the very least, I think we should be swapping inuseEffectEvent to avoid some subscription behavior

};

getTasks=async(filter:TasksFilter):Promise<Task[]>=>{
getTasks=async(filter:TasksFilter={}):Promise<Task[]>=>{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Is there a reason why this has a default parameter? There's nothing in the type information to indicate that the filter could ever be undefined

@@ -0,0 +1,21 @@
import*asReactfrom"react";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'd prefer if we could importuseState anduseEffect explicitly. There's no need to import React like this in a Vite project


constMOBILE_BREAKPOINT=768;

exportfunctionuseIsMobile(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I feel like there are issues with the entire conceit behind this hook. I'm not convinced if we actually need to care whether a user is on a mobile device specifically – we should be making sure the layout is responsive to as content widths as possible

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Can we also add an explicit return value?

@@ -0,0 +1,21 @@
import*asReactfrom"react";

constMOBILE_BREAKPOINT=768;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This feels like a really arbitrary value. I know thatsome mobile devices have this width, and that this corresponds to Tailwind's defaultmd breakpoint, but how did we decide that we wanted this one specifically?

Comment on lines +6 to +8
const[isMobile,setIsMobile]=React.useState<boolean|undefined>(
undefined,
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we're always returning out a boolean, we can initialize this state with justfalse

Comment on lines +234 to +237
<SheetHeaderclassName="sr-only">
<SheetTitle>Sidebar</SheetTitle>
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
</SheetHeader>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't get the point of having specialized, stylized components, if we're just going to shove them into ansr-only container

Comment on lines +501 to +504
// Random width between 50 to 90%.
constwidth=useMemo(()=>{
return`${Math.floor(Math.random()*40)+50}%`;
},[]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We shouldn't be usinguseMemo to stabilize nondeterministic values, especially when,per the React docs, React reserves the right to throw memo results away as part of its internal scheduling

In the future, this code could cause the elements to randomly change widths on re-renders

Comment on lines +256 to +263
className={cn(
"relative w-[var(--sidebar-width)] bg-transparent transition-[width] duration-200 ease-linear",
"group-data-[collapsible=offcanvas]:w-0",
"group-data-[side=right]:rotate-180",
variant==="floating"||variant==="inset"
?"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+1rem)]"
:"group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)]",
)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Honestly, my eyes are kind of glazing over with all this Tailwind. I'm just trusting that this does what it's supposed to

<SidebarMenuButtonasChild>
<RouterLinkto="/tasks">
<SquarePenIcon/>
<span>New task</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Do we need the span here?

conststate=open ?"expanded" :"collapsed";

// biome-ignore lint/correctness/useExhaustiveDependencies: set by library author
constcontextValue=useMemo<SidebarContextProps>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This whole setup feels super, super fragile. I feel like memoizing this doesn't actually get us much:

  1. Because so many values are potentially coming from props, this value is likely going to get invalidated a ton
  2. Even if it does get invalidated, because this is part of a bunch of components that would be localized to a specific part of the page, I don't know if extra re-render from context would actually cause any meaningful problems

@brettkolodnybrettkolodny mentioned this pull requestAug 31, 2025
@brettkolodny
Copy link
Contributor

I had some time today and did someexploration of what it would look like if we were to implement the core behavior we need of the collapsible navbar ourselves. For the sake of a 1:1 comparison I kept the overall layout the same and just switched out components. Personally I think it works pretty well, and if we decide to go down this route please feel free grab any of the code!

I get using shadcn to speed up development, and I think generally their more basic components are really solid. But in the case of the collapsible sidebar I think since it's meant to be used for site-wide navigation it's both overkill and too opinionated for this page, especially since we're only using it in this one place.

@BrunoQuaresma
Copy link
CollaboratorAuthor

Hey@Parkreiner and@brettkolodny 👋

@Parkreiner I noticed most of your comments and requests are related to the shadcn implementation of the sidebar component. I’m curious about what benefits you see in adapting it to match our internal preferences. From my perspective, I’m not sure the tradeoff is worth it since we’d likely only be touching these components during upgrades. In those cases, we’d need to re-apply all our preferences or carefully cherry-pick changes, which could add a lot of overhead.

@brettkolodny If the component library we’re already using provides a sidebar abstraction, my inclination would be to lean on that rather than building something in-house. It feels like a faster and more reliable path, especially since we’d be standing on top of tools that are widely adopted and battle-tested by the community.

On the Tasks feature, since it’s still evolving and may change direction based on customer feedback, I think it makes sense to keep our focus on speed and iteration over perfect code quality right now—at least while it remains isolated. As long as the code is easy to remove later and doesn’t introduce major UX issues, I’d consider that “good enough” for this stage. We can always come back and refine it once the feature proves its value and stabilizes.

That said, these are just my thoughts and preferences. Since both of you are reviewing, I’m happy to support whichever direction you feel is best to move this forward. I won’t be able to finish it myself since I’ll be on PTO until September 14th, so I’d love your help wrapping this up in the meantime.

Wdyt?

@brettkolodny
Copy link
Contributor

If the component library we’re already using provides a sidebar abstraction, my inclination would be to lean on that rather than building something in-house. It feels like a faster and more reliable path, especially since we’d be standing on top of tools that are widely adopted and battle-tested by the community.

I get what you're saying, but like I said above I still think that in this case the shadcn component is overkill/not really intended for this use case, and building something in house is actually easy enough for the functionality you're looking for. And like I tried to demonstrate in my above comment/exploration in this case I think we can get something that matches the functionality pretty easily.

As long as the code is easy to remove later and doesn’t introduce major UX issues, I’d consider that “good enough” for this stage. We can always come back and refine it once the feature proves its value and stabilizes.

I'm going to push back on this idea a bit. I totally understand that we're moving fast and things are changing quickly but adding code just because we think it's easy to remove seems dangerous. In my experience that doesn't typically pan out, and it will live in the code base for much longer than we'd expect. I've traditionally tried to approach this balance by making sure all the code that is being added is code that I'm happy with, and the time saved comes from code I'm not adding.

All of that being said, I'm going to remove myself as a reviewer on this PR and let@Parkreiner give their input. I don't there to be too many cooks in the kitchen

@brettkolodnybrettkolodny dismissed theirstale reviewSeptember 2, 2025 16:13

Making room in the kitchen

@Parkreiner
Copy link
Member

Parkreiner commentedSep 4, 2025
edited
Loading

@BrunoQuaresma Really, really sorry for just now following up. But I guess my understanding (as someone who hasn't actually brought in a Shad component yet) was that we were going to take advantage of the vendoring Shad gives us, instead of treating it as a library with extra steps

The way I think about it is:

  • No matter where the source code came from, it's directly committed to our codebase. At that point, it's no longer an external dependency – and we need to hold it to the standards we have for the code we author ourselves
  • Given the problems I've already identified with their code in this PR alone, I don't think it's safe to take Vercel at their word and assume that their components are 100% bug-free.
  • The vendoring approach means that we can treat Shad components as a solid starting point, and then customize them to meet our organization standards and domain-specific requirements. Fundamentally, I think a Shad component that has been copy-and-pasted without any vetting should be treated on the same level as AI-hallucinated code
  • If there's a critical bug in the code and it has an obvious fix (like the subscription issue I mentioned in one of the comments), we shouldn't wait for Shad to fix it
  • Realistically, I expect most UI primitives to be mostly "solved". I don't expect Shad code to change that much across versions, so I doubt any maintenance cost from updating would actually be that high in practice
  • Shad currently has 740 open pull requests. I don't think we can count on them to address problems in a timely matter, which makes it even more important that we're proactive about fixes

I'm curious to know what@aslilac thinks, though. And while he's not involved with the frontend, I'd also love to hear if@spikecurtis has any thoughts on how Coder should approach code vendoring in general

@aslilac
Copy link
Member

my understanding when we decided to start using shadcn was that every component would be a starting point, that we would adapt it to our code style, it would be owned by us from that point forward (without concerns for "upgrading"), and that we would add and remove functionality from the base implementations freely as needed. shadcn is mostly just styles. any functional/important/bug fixing updates should be delivered by a new version of a radix package. I don't think we get much value by trying to "preserve" shadcn code.

I think of it this way: because shadcn is vendored, when we decide to use more of their code, it has to be accepted as part of our codebase through the usual avenues. a pull request, review from peers, and addressing the feedback given.

imagine if we changed the situation just slightly and the code was from stack overflow. if anyone asked in slack "can I use some code I found on slack overflow?" I think the response would be similar to the response on this pr: it's fine to use it if it fits the problem and solves it well, but we should adapt it to our code standards, we should remove bits we don't need, we should test it, and we should understand it. no one would suggest that you not alter the code you found on stack overflow just because someone might edit the answer later.

my vision of a successful transition was that in the end we would not be using shadcn, but we would be using our own component library, that we would maintain ourselves and have direct control over. shadcn would be the stepping stone, not the destination.

@github-actionsgithub-actionsbot added the staleThis issue is like stale bread. labelSep 12, 2025
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@ParkreinerParkreinerParkreiner requested changes

@brettkolodnybrettkolodnybrettkolodny left review comments

@aslilacaslilacAwaiting requested review from aslilacaslilac is a code owner

@jaaydenhjaaydenhAwaiting requested review from jaaydenh

Assignees

@BrunoQuaresmaBrunoQuaresma

Labels
staleThis issue is like stale bread.
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

tasks: add sidebar layout to tasks for easy navigation between tasks
5 participants
@BrunoQuaresma@brettkolodny@jaaydenh@Parkreiner@aslilac

[8]ページ先頭

©2009-2025 Movatter.jp