Skip to content

Commit 96c97ed

Browse files
feat(dashboard): Refactor header layout and update start page UI
1 parent 217ba2d commit 96c97ed

File tree

2 files changed

+66
-42
lines changed

2 files changed

+66
-42
lines changed

components/dashboard/src/menu/Menu.tsx

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { User, RoleOrPermission } from "@gitpod/public-api/lib/gitpod/v1/user_pb
2222
import { getPrimaryEmail } from "@gitpod/public-api-common/lib/user-utils";
2323
import { ConfigurationsMigrationCoachmark } from "../repositories/coachmarks/MigrationCoachmark";
2424
import { useInstallationConfiguration } from "../data/installation/installation-config-query";
25+
import { useIsDataOps } from "../data/featureflag-query";
26+
import { ProductLogo } from "../components/ProductLogo";
2527

2628
interface Entry {
2729
title: string;
@@ -34,9 +36,7 @@ export default function Menu() {
3436
const location = useLocation();
3537
const { setCurrency } = useContext(PaymentContext);
3638
const [isFeedbackFormVisible, setFeedbackFormVisible] = useState<boolean>(false);
37-
38-
const { data: installationConfig, isLoading: isInstallationConfigLoading } = useInstallationConfiguration();
39-
const isGitpodIo = isInstallationConfigLoading ? false : !installationConfig?.isDedicatedInstallation;
39+
const isDataOps = useIsDataOps();
4040

4141
useEffect(() => {
4242
const { server } = getGitpodService();
@@ -79,16 +79,24 @@ export default function Menu() {
7979
<ConfigurationsMigrationCoachmark>
8080
<OrganizationSelector />
8181
</ConfigurationsMigrationCoachmark>
82-
{/* hidden on smaller screens (in its own menu below on smaller screens) */}
83-
<div className="hidden md:block pl-2">
84-
<OrgPagesNav />
82+
{/* Mobile Only Divider and User Menu */}
83+
<div className="flex items-center md:hidden">
84+
<div className="h-6 w-px bg-gray-300 dark:bg-gray-600 mx-2" />
85+
<UserMenu user={user} className="" onFeedback={handleFeedbackFormClick} withAdminLink />
86+
</div>
87+
{/* Desktop Only Divider, User Menu, and Workspaces Nav */}
88+
<div className="hidden md:flex items-center">
89+
<div className="h-6 w-px bg-gray-300 dark:bg-gray-600 mx-2" />
90+
<UserMenu user={user} className="" onFeedback={handleFeedbackFormClick} />
91+
<div className="pl-2">
92+
<OrgPagesNav />
93+
</div>
8594
</div>
8695
</div>
8796
<div className="flex items-center w-auto" id="menu">
88-
{/* hidden on smaller screens - TODO: move to user menu on smaller screen */}
97+
{/* Right side nav - Desktop Only */}
8998
<nav className="hidden md:block flex-1">
90-
<ul className="flex flex-1 items-center justify-between text-base text-gray-500 dark:text-gray-400 space-x-2">
91-
<li className="flex-1"></li>
99+
<ul className="flex flex-1 items-center justify-end text-base text-gray-500 dark:text-gray-400 space-x-4">
92100
{user?.rolesOrPermissions?.includes(RoleOrPermission.ADMIN) && (
93101
<li className="cursor-pointer">
94102
<PillMenuItem
@@ -98,31 +106,38 @@ export default function Menu() {
98106
/>
99107
</li>
100108
)}
101-
{isGitpodIo && (
102-
<li className="cursor-pointer">
103-
<PillMenuItem name="Feedback" onClick={handleFeedbackFormClick} />
109+
{!isDataOps && (
110+
<li>
111+
<a
112+
href="/"
113+
className="flex items-center gap-x-1 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
114+
>
115+
<ProductLogo className="h-4 w-auto" />
116+
<span>Gitpod Classic</span>
117+
</a>
104118
</li>
105119
)}
106120
</ul>
107121
</nav>
108-
{/* Hide normal user menu on small screens */}
109-
<UserMenu user={user} className="hidden md:block" />
110-
{/* Show a user menu w/ admin & feedback links on small screens */}
111-
<UserMenu
112-
user={user}
113-
className="md:hidden"
114-
withAdminLink
115-
withFeedbackLink
116-
onFeedback={handleFeedbackFormClick}
117-
/>
122+
{/* Right side items - Mobile Only */}
123+
<div className="flex items-center space-x-3 md:hidden">
124+
{!isDataOps && (
125+
<a
126+
href="/"
127+
className="flex items-center gap-x-1 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
128+
>
129+
<ProductLogo className="h-4 w-auto" />
130+
<span>Gitpod Classic</span>
131+
</a>
132+
)}
133+
</div>
118134
</div>
119135
{isFeedbackFormVisible && <FeedbackFormModal onClose={onFeedbackFormClose} />}
120136
</div>
121137
</header>
122138
<Separator />
123-
{/* only shown on small screens */}
139+
{/* Mobile-only OrgPagesNav and Separator */}
124140
<OrgPagesNav className="md:hidden app-container flex justify-start py-2" />
125-
{/* only shown on small screens */}
126141
<Separator className="md:hidden" />
127142
</>
128143
);
@@ -162,10 +177,9 @@ type UserMenuProps = {
162177
user?: User;
163178
className?: string;
164179
withAdminLink?: boolean;
165-
withFeedbackLink?: boolean;
166180
onFeedback?: () => void;
167181
};
168-
const UserMenu: FC<UserMenuProps> = ({ user, className, withAdminLink, withFeedbackLink, onFeedback }) => {
182+
const UserMenu: FC<UserMenuProps> = ({ user, className, withAdminLink, onFeedback }) => {
169183
const { data: installationConfig, isLoading: isInstallationConfigLoading } = useInstallationConfiguration();
170184
const isGitpodIo = isInstallationConfigLoading ? false : !installationConfig?.isDedicatedInstallation;
171185

@@ -178,23 +192,17 @@ const UserMenu: FC<UserMenuProps> = ({ user, className, withAdminLink, withFeedb
178192
link: "/admin",
179193
});
180194
}
181-
if (withFeedbackLink && isGitpodIo) {
182-
items.push({
183-
title: "Feedback",
184-
onClick: onFeedback,
185-
});
186-
}
187195

188196
// Add a separator to the last item
189197
if (items.length > 0) {
190198
items[items.length - 1].separator = true;
191199
}
192200

193201
return items;
194-
}, [isGitpodIo, onFeedback, user?.rolesOrPermissions, withAdminLink, withFeedbackLink]);
202+
}, [user?.rolesOrPermissions, withAdminLink]);
195203

196204
const menuEntries = useMemo(() => {
197-
return [
205+
const baseEntries: ContextMenuEntry[] = [
198206
{
199207
title: (user && (getPrimaryEmail(user) || user?.name)) || "User",
200208
customFontStyle: "text-gray-400",
@@ -215,15 +223,27 @@ const UserMenu: FC<UserMenuProps> = ({ user, className, withAdminLink, withFeedb
215223
href: "https://www.gitpod.io/support/",
216224
target: "_blank",
217225
rel: "noreferrer",
218-
separator: true,
219-
},
220-
...extraSection,
221-
{
222-
title: "Log out",
223-
href: gitpodHostUrl.asApiLogout().toString(),
226+
separator: !isGitpodIo,
224227
},
225228
];
226-
}, [extraSection, user]);
229+
230+
if (isGitpodIo) {
231+
baseEntries.push({
232+
title: "Feedback",
233+
onClick: onFeedback,
234+
separator: true,
235+
});
236+
}
237+
238+
baseEntries.push(...extraSection);
239+
240+
baseEntries.push({
241+
title: "Log out",
242+
href: gitpodHostUrl.asApiLogout().toString(),
243+
});
244+
245+
return baseEntries;
246+
}, [extraSection, user, isGitpodIo, onFeedback]);
227247

228248
return (
229249
<div
@@ -243,5 +263,5 @@ const UserMenu: FC<UserMenuProps> = ({ user, className, withAdminLink, withFeedb
243263
function isSelected(entry: Entry, location: Location<any>) {
244264
const all = [entry.link, ...(entry.alternatives || [])].map((l) => l.toLowerCase());
245265
const path = location.pathname.toLowerCase();
246-
return all.some((n) => n === path || n + "/" === path);
266+
return all.some((n) => n === path || n + "/" === path || path.startsWith(n + "/"));
247267
}

components/dashboard/src/start/StartPage.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { VerifyModal } from "./VerifyModal";
1414
import { useWorkspaceDefaultImageQuery } from "../data/workspaces/default-workspace-image-query";
1515
import { GetWorkspaceDefaultImageResponse_Source } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
1616
import { ProductLogo } from "../components/ProductLogo";
17+
import { useIsDataOps } from "../data/featureflag-query";
1718

1819
export enum StartPhase {
1920
Checking = 0,
@@ -96,6 +97,8 @@ export function StartPage(props: StartPageProps) {
9697
const { phase, error, workspaceId } = props;
9798
let title = props.title || getPhaseTitle(phase, error);
9899
useDocumentTitle("Starting");
100+
const isDataOps = useIsDataOps();
101+
99102
return (
100103
<div className="w-screen h-screen align-middle">
101104
<div className="flex flex-col mx-auto items-center text-center h-screen">
@@ -105,6 +108,7 @@ export function StartPage(props: StartPageProps) {
105108
error || phase === StartPhase.Stopped || phase === StartPhase.IdeReady ? "" : "animate-bounce"
106109
}`}
107110
/>
111+
{!isDataOps && <span className="block mt-2 text-gray-600 dark:text-gray-400">Gitpod Classic</span>}
108112
<Heading2 className="mt-8">{title}</Heading2>
109113
{typeof phase === "number" && phase < StartPhase.IdeReady && (
110114
<ProgressBar phase={phase} error={!!error} />

0 commit comments

Comments
 (0)