Remove "account" dropdown', add notifications dropdown#3365
Remove "account" dropdown', add notifications dropdown#3365
Conversation
- items in the side nav can now expose an `onClick` instead of just a `to` - renamed the "activeTo" side nav item option to "displayAsActiveWhenThisRouteIsMatched" to increase my understanding - the theme hook now exposes a currentlyVisibleTheme value which is either "dark" or "light", as opposed to the existing theme value which can also be "system" – at some point we should probably make the toggle function toggle through all 3 possible values, but I'll settle for this incremental improvement for now
…st show a notification
- notification dropdown wider - move more important text earlier in the notification message - kill some passive voice in the process - put notification message in title so you can see it on hover
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📝 Documentation updates detected! New suggestion: Document dashboard notifications dropdown for invites and resource limits Tip: Enable auto-create PR in your Docs Collection to publish suggestions automatically 🤖 |
mrkaye97
left a comment
There was a problem hiding this comment.
a couple small UI things!
- I think we should put the logout button either next to or above/below the help button on the bottom of the side nav
- Small and annoying thing, but I wonder if we should nest the change theme button under general settings just for UI consistency :( Not great, hoping to improve the settings sidebar view thingy in general soon
- It'd be great if we had some way to check if you finished the initial onboarding flow (maybe we can see if you have any workers / workflows / runs already as a hack), and if you haven't completed it, then have a notification / CTA telling you to do that. then we can also remove the overview tab from the sidebar which I really dislike since it's irrelevant for 95% of cases. WDYT?
| const getThemeToDisplay = (theme: SelectableTheme): DisplayableTheme => { | ||
| if (theme === 'system') { | ||
| return window.matchMedia('(prefers-color-scheme: dark)').matches | ||
| ? 'dark' | ||
| : 'light'; |
| return ( | ||
| <DropdownMenu> | ||
| <DropdownMenuTrigger asChild> | ||
| <button |
There was a problem hiding this comment.
we should use a shadcn button here if we can (no worries if it's too much of an issue to do that while also matching the designs)
| export const useNotifications = () => { | ||
| const resourceLimits = useResourceLimitNotifications(); | ||
| const invites = useInviteNotifications(); | ||
|
|
||
| const notifications = useMemo( | ||
| () => | ||
| [...resourceLimits.notifications, ...invites.notifications].sort( | ||
| (a, b) => (b.timestamp > a.timestamp ? 1 : -1), | ||
| ), | ||
| [resourceLimits.notifications, invites.notifications], | ||
| ); | ||
|
|
There was a problem hiding this comment.
this is great 👍 should make it really easy for us to plug additional stuff
| const resourceLabels: Record<TenantResource, string> = { | ||
| [TenantResource.WORKER]: 'Total Workers', | ||
| [TenantResource.WORKER_SLOT]: 'Concurrency Slots', | ||
| [TenantResource.EVENT]: 'Events', | ||
| [TenantResource.TASK_RUN]: 'Task Runs', | ||
| [TenantResource.CRON]: 'Cron Triggers', | ||
| [TenantResource.SCHEDULE]: 'Schedule Triggers', | ||
| [TenantResource.INCOMING_WEBHOOK]: 'Incoming Webhooks', |
There was a problem hiding this comment.
small thing: as I refactor more stuff in the codebase, I've been trying to use switch statements with an exhaustiveness check for this sort of thing as opposed to a map, so we don't need to handle the not found case implicitly. e.g.:
| const resourceLabels: Record<TenantResource, string> = { | |
| [TenantResource.WORKER]: 'Total Workers', | |
| [TenantResource.WORKER_SLOT]: 'Concurrency Slots', | |
| [TenantResource.EVENT]: 'Events', | |
| [TenantResource.TASK_RUN]: 'Task Runs', | |
| [TenantResource.CRON]: 'Cron Triggers', | |
| [TenantResource.SCHEDULE]: 'Schedule Triggers', | |
| [TenantResource.INCOMING_WEBHOOK]: 'Incoming Webhooks', | |
| const resourceTypeToLabel = (resource: TenantResource): string => { | |
| switch (resource) { | |
| case ... | |
| ... | |
| default: | |
| const exhaustive: never = resource; // should never be non-never | |
| throw ... | |
| } | |
| } |
(typed this in Github, not sure if it'd compile but you get the idea :P )
There was a problem hiding this comment.
So as it is now, the type system catches it if there is any unhandled TenantResource – if you comment out any of those lines , there's a type error down at resourceLabels[limit.resource].
I think TypeScript got smarter about map key types like this at some point a little bit back.
Personally in the case where I want to assert that there should never be a default case I like to use the type system to see it earlier.
Tangentially, this doesn't change much, but I also appreciate this pattern:
const resourceLabels = {
[TenantResource.WORKER]: 'Total Workers',
[TenantResource.WORKER_SLOT]: 'Concurrency Slots',
[TenantResource.EVENT]: 'Events',
[TenantResource.TASK_RUN]: 'Task Runs',
[TenantResource.CRON]: 'Cron Triggers',
[TenantResource.SCHEDULE]: 'Schedule Triggers',
[TenantResource.INCOMING_WEBHOOK]: 'Incoming Webhooks',
} satisfies Record<TenantResource, string>because then if you comment out one of those lines, not only do you get the type error down where resourceLabels is accessed, but you also get an error right there where the mapping is defined.
I have some preference for the mapping over the switch statement as long as I can get the early warning, but it's not a big deal, I'm happy to change it if you prefer the switch statements in general.
There was a problem hiding this comment.
Ah great stuff! No, either of these is good for me, as long as we get type errors instead of runtime errors if there’s a missing case, thanks for clarifying!
| const notifications = useMemo( | ||
| () => | ||
| tenants.flatMap((tenant, i) => | ||
| (resourcePolicyQueries[i]?.data?.limits ?? []) |
There was a problem hiding this comment.
flagging b/c this always sets of alarm bells 😅 - are we sure the tenants are guaranteed to be ordered the same as the resourcePolicyQueries?
There was a problem hiding this comment.
So because the queries passed to useQueries is based on tenants.map, the indexes should be identical.
I don't particularly like this either – it reads too low-level than something I'd like to be composing here. I could override the queries.tenantResourcePolicy.get query above so that the query data includes the tenant id along with the policy results, and then use that to get the relevant tenant, but that feels a little awkward too.
I think the main thing that needs to happen is an endpoint that returns the resource policies for all tenants in one go, including their tenantIds.
There was a problem hiding this comment.
sounds good, works for me as long as it works as we intend :)
Yeah, that makes sense, though I often find the "help" area eating into the vertical space on the sidebar a bit already – I'll probably try to reduce the vertical padding, at least.
Yeah, fair enough. I can put theme under there with everything else – but maybe until a better categorization system comes along it would be okay to put everything at the top level, even if we recategorize everything soon after? Putting it behind a click doesn't do much.
I like the idea of supplanting the overview screen in the side nav – we do still force users to create a new tenant/organization if they don't have one and they don't have any invites, so until we change that they wouldn't ever see an onboarding notification for it. Maybe if they don't have an API token, we could give them an onboarding notification that takes them to a "install the CLI + add a hatchet CLI profile" page? |
For slightly nicer type-checking warnings
I'm in favor of this - let's at least give it a shot and see how it looks (we discussed a bit in Slack yesterday, because I'd proposed the same)
I feel like the simplest thing here would be to check if they have a token and maybe if they have some combination of workers / workflows / task runs and then link them to the current overview just so we don't need to rework that at all, but I agree in the future that linking to something more specific would be better |
also make the theme button not stand out so much
…tions-and-remove-account-menu
if the user has one tenant and no workflows and no api keys, show them a notification that redirects them to the onboarding screen
07 isn't relevant now, its case is covered by 05 and 08
|
The 05 Cypress test is failing in CI, but it passes on my machine. |
Description
onClickinstead of ato(href) nowNote: the resource limits for all tenants are being fetched right now, which requires a request per tenant. We should probably add an endpoint that lets you see your limits for all tenants. We could make it so that you only see notifications for limits on the current active tenant, but that seems weird to me, since the top nav/notification UI feels "global", and presumably most users are responsible for all the tenants they belong to to some degree.
Type of change
What's Changed