-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat(webapp): redesign the side menu project and organization menus #4066
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 8 commits
c6138e3
f2e8a0e
440023b
d7c6af0
3aa2886
e9fe1d0
f2a3cbe
8e37da9
2fe465c
8f99e6a
f593730
d5c39f5
24557d8
0b0f66d
26aa1be
6d701ab
347fabe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| area: webapp | ||
| type: improvement | ||
| --- | ||
|
|
||
| Restructure the side menu's top-left and project/organization navigation: | ||
|
|
||
| - Add a new "Project" section above the "Environment" section with a popover | ||
| that lists the org's projects (folder icon + checkmark for the selected one) | ||
| and a "New project" item at the bottom. | ||
| - The top-left menu now shows the organization (avatar + org name, no | ||
| project/diagonal divider) and its popover is a clean list of org-level items | ||
| (Settings, Usage, Billing with plan badge, Billing alerts, Team, Private | ||
| connections, Roles, SSO, Vercel integration, Slack integration, Switch | ||
| organization, then Account and Logout) using the same icons and links as the | ||
| organization settings side menu. | ||
|
|
||
| The org loader now exposes whether the RBAC and SSO plugins are installed so the | ||
| side menu can gate the Roles and SSO items the same way the settings side menu | ||
| does. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -89,17 +89,17 @@ export function EnvironmentSelector({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "overflow-hidden transition-all duration-200", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isCollapsed ? "max-w-0 opacity-0" : "max-w-[16px] opacity-100" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isCollapsed ? "max-w-0 opacity-0" : "max-w-[16px] opacity-0 group-hover:opacity-100" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <DropdownIcon className="size-4 min-w-4 text-text-dimmed transition group-hover:text-text-bright" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </PopoverTrigger> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={environmentFullTitle(environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={`${environmentFullTitle(environment)} environment`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| side="right" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sideOffset={8} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hidden={!isCollapsed} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| delayDuration={isCollapsed ? 0 : 500} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buttonClassName="!h-8" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| asChild | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| disableHoverableContent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -196,10 +196,6 @@ function Branches({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments: SideMenuEnvironment[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentEnvironment: SideMenuEnvironment; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const organization = useOrganization(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const project = useProject(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const environment = useEnvironment(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { urlForEnvironment } = useEnvironmentSwitcher(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const navigation = useNavigation(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isMenuOpen, setMenuOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const timeoutRef = useRef<NodeJS.Timeout | null>(null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -231,23 +227,6 @@ function Branches({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, 150); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const activeBranches = branchEnvironments.filter((env) => env.archivedAt === null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const state = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments.length === 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? "no-branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : activeBranches.length === 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? "no-active-branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : "has-branches"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only surface the active environment's archived-branch item in the submenu it | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // actually belongs to. Both Development and Preview render this component, so | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // without the parent check an archived dev branch would leak into the Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // submenu (and vice-versa). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const currentBranchIsArchived = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| environment.archivedAt !== null && environment.parentEnvironmentId === parentEnvironment.id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const envTextClassName = environmentTextClassName(parentEnvironment); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Popover onOpenChange={(open) => setMenuOpen(open)} open={isMenuOpen}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} className="flex"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -273,88 +252,134 @@ function Branches({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMouseEnter={handleMouseEnter} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMouseLeave={handleMouseLeave} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col gap-1 p-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {currentBranchIsArchived && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={environment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={urlForEnvironment(environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchesPopoverContent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parentEnvironment={parentEnvironment} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments={branchEnvironments} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentEnvironment={currentEnvironment} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </PopoverContent> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Popover> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * The inner content of the branches popover (branch list, empty states, and the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * "Manage branches" footer). Shared by the dropdown's hover submenu (`Branches`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * and the side-menu segmented control's Preview popover. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function BranchesPopoverContent({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parentEnvironment, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentEnvironment, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parentEnvironment: SideMenuEnvironment; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments: SideMenuEnvironment[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentEnvironment: SideMenuEnvironment; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const organization = useOrganization(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const project = useProject(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const environment = useEnvironment(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { urlForEnvironment } = useEnvironmentSwitcher(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const activeBranches = branchEnvironments.filter((env) => env.archivedAt === null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const state = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branchEnvironments.length === 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? "no-branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : activeBranches.length === 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? "no-active-branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : "has-branches"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only surface the active environment's archived-branch item in the submenu it | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // actually belongs to. Both Development and Preview render this component, so | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // without the parent check an archived dev branch would leak into the Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // submenu (and vice-versa). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const currentBranchIsArchived = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| environment.archivedAt !== null && environment.parentEnvironmentId === parentEnvironment.id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const envTextClassName = environmentTextClassName(parentEnvironment); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col gap-1 p-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {currentBranchIsArchived && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={environment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={urlForEnvironment(environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className={cn("block w-full", envTextClassName)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {environment.branchName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Badge variant="extra-small">Archived</Badge> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall className={cn("size-4 shrink-0", envTextClassName)} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isSelected={environment.id === currentEnvironment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {state === "has-branches" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {branchEnvironments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((env) => env.archivedAt === null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map((env) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={env.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={urlForEnvironment(env)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className={cn("block w-full", envTextClassName)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {environment.branchName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {env.branchName ?? DEFAULT_DEV_BRANCH} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Badge variant="extra-small">Archived</Badge> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall className={cn("size-4 shrink-0", envTextClassName)} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isSelected={environment.id === currentEnvironment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {state === "has-branches" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {branchEnvironments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((env) => env.archivedAt === null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map((env) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={env.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={urlForEnvironment(env)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className={cn("block w-full", envTextClassName)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {env.branchName ?? DEFAULT_DEV_BRANCH} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn("size-4 shrink-0", envTextClassName)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isSelected={env.id === currentEnvironment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn("size-4 shrink-0", envTextClassName)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : state === "no-branches" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex max-w-sm flex-col gap-1 p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center gap-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall className={cn("size-4", envTextClassName)} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Header2>Create your first branch</Header2> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph spacing variant="small"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Branches are a way to test new features in isolation before merging them into the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| main environment. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph variant="small"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Branches are only available when using <V4Badge inline /> or above. Read our{" "} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| more. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex max-w-sm flex-col gap-1 p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph variant="extra-small">All branches are archived.</Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isSelected={env.id === currentEnvironment.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : state === "no-branches" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex max-w-sm flex-col gap-1 p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center gap-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BranchEnvironmentIconSmall className={cn("size-4", envTextClassName)} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Header2>Create your first branch</Header2> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph spacing variant="small"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Branches are a way to test new features in isolation before merging them into the main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| environment. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph variant="small"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Branches are only available when using <V4Badge inline /> or above. Read our{" "} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn more. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="border-t border-charcoal-700 p-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {parentEnvironment.type === "DEVELOPMENT" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={branchesDevPath(organization, project, environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="Manage dev branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leadingIconClassName="text-text-dimmed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={branchesPath(organization, project, environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="Manage preview branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leadingIconClassName="text-text-dimmed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex max-w-sm flex-col gap-1 p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Paragraph variant="extra-small">All branches are archived.</Paragraph> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </PopoverContent> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Popover> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="border-t border-charcoal-700 p-1"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {parentEnvironment.type === "DEVELOPMENT" ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={branchesDevPath(organization, project, environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="Manage dev branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leadingIconClassName="text-text-dimmed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopoverMenuItem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to={branchesPath(organization, project, environment)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="Manage preview branches" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leadingIconClassName="text-text-dimmed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+360
to
+375
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Exported BranchesPopoverContent relies on useEnvironment() for the manage-branches link, which may break in future reuse contexts The newly exported Was this helpful? React with 👍 or 👎 to provide feedback.
Comment on lines
+360
to
+375
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Footer links use the wrong environment for the URL.
🐛 Proposed fix {parentEnvironment.type === "DEVELOPMENT" ? (
<PopoverMenuItem
- to={branchesDevPath(organization, project, environment)}
+ to={branchesDevPath(organization, project, parentEnvironment)}
title="Manage dev branches"
icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />}
leadingIconClassName="text-text-dimmed"
/>
) : (
<PopoverMenuItem
- to={branchesPath(organization, project, environment)}
+ to={branchesPath(organization, project, parentEnvironment)}
title="Manage preview branches"
icon={<Cog8ToothIcon className="size-4 text-text-dimmed" />}
leadingIconClassName="text-text-dimmed"
/>
)}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚩 EnvironmentSelector tooltip now visible in all contexts, not just collapsed sidebar
The old code used
hidden={!isCollapsed}to completely suppress the tooltip when the sidebar was expanded. The new code atapps/webapp/app/components/navigation/EnvironmentSelector.tsx:121replaces this withdelayDuration={isCollapsed ? 0 : 500}, meaning the tooltip is now always visible (immediately when collapsed, after 500ms when expanded). This changes behavior for the three other consumers ofEnvironmentSelectoroutside the side menu (BlankStatePanels.tsx:303,BlankStatePanels.tsx:582, and the limits route at line 284), whereisCollapseddefaults tofalse. Previously those tooltips were completely hidden; now they appear after 500ms on hover. This is arguably better UX but is an implicit behavioral change to those other call sites.Was this helpful? React with 👍 or 👎 to provide feedback.