Skip to content

Commit

Permalink
feat(console): improve console design (#3934)
Browse files Browse the repository at this point in the history
Improve Console design:
* Increase widget spacing
* Remove header
* Move theme toggle to the status bar
* Improve nodes design
* Make the map toolbar transparent


Before
<img width="1512" alt="image" src="https://github.com/winglang/wing/assets/5547636/ea41b3af-f254-481c-97c1-0a4072c90409">

After
<img width="1512" alt="image" src="https://github.com/winglang/wing/assets/5547636/f268b736-310b-4155-855f-cbe31c48aa23">
<img width="1512" alt="image" src="https://github.com/winglang/wing/assets/5547636/e5115c39-a430-4811-9eb5-b4cd45cc073c">

Closes #3921

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
  • Loading branch information
polamoros authored Aug 23, 2023
1 parent 116ee64 commit 19d8565
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const ToolbarButton = ({
return (
<button
className={classNames(
theme.bg2Hover,
theme.bg3Hover,
theme.text1,
theme.focusInput,
"text-xs",
Expand Down
9 changes: 2 additions & 7 deletions apps/wing-console/console/design-system/src/toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@ export const Toolbar = ({
}: PropsWithChildren<ToolbarProps>) => {
const { theme } = useTheme();
return (
<div
className={classNames(
"flex-shrink-0 flex items-center justify-between gap-2 px-2",
theme.bg3,
)}
>
<div className="flex-shrink-0 flex items-center justify-between gap-2 px-2">
{title && (
<div className="flex items-center min-w-0">
<span
className={classNames("text-sm truncate uppercase", theme.text2)}
className={classNames("text-sm truncate uppercase", theme.text1)}
>
{title}
</span>
Expand Down
7 changes: 3 additions & 4 deletions apps/wing-console/console/server/src/utils/createRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ export interface LayoutPanel {
}

export interface LayoutConfig {
header?: {
hide?: boolean;
showThemeToggle?: boolean;
};
leftPanel?: LayoutPanel;
bottomPanel?: LayoutPanel;
statusBar?: {
Expand All @@ -52,6 +48,9 @@ export interface LayoutConfig {
displayTitle?: boolean;
displayLinks?: boolean;
};
panels?: {
rounded?: boolean;
};
}

export type TestStatus = "pending" | "running" | "success" | "error";
Expand Down
41 changes: 28 additions & 13 deletions apps/wing-console/console/ui/src/features/map-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
USE_EXTERNAL_THEME_COLOR,
} from "@wingconsole/design-system";
import classNames from "classnames";
import { useState } from "react";

import { useMap } from "../services/use-map.js";
import { ContainerNode } from "../ui/elk-map-nodes.js";
Expand Down Expand Up @@ -31,22 +32,36 @@ export const MapView = ({
const { mapData } = useMap({ showTests: showTests ?? false });

const { theme } = useTheme();
const [hoverMapControls, setHoverMapControls] = useState(false);

return (
<ZoomPaneProvider>
<div className="h-full flex flex-col">
{showMapControls && (
<div className={classNames(USE_EXTERNAL_THEME_COLOR)}>
<MapControls />
</div>
)}
<div
className={classNames(
"grow relative border-t",
theme.bg4,
theme.border3,
"cursor-grab",
<div className={classNames("h-full flex flex-col", theme.bg4)}>
<div className="grow relative cursor-grab">
{showMapControls && (
<div className="right-0 absolute z-10">
<div
className={classNames(
"transition-opacity",
"absolute inset-0 rounded-bl",
theme.bg4,
(hoverMapControls && "opacity-80") || "opacity-60",
)}
/>
<div
className="relative group/map-controls"
onMouseEnter={() => {
setHoverMapControls(true);
}}
onMouseLeave={() => {
setHoverMapControls(false);
}}
>
<MapControls />
</div>
</div>
)}
>

<div className="absolute inset-0">
<ElkMap
nodes={mapData?.nodes ?? []}
Expand Down
151 changes: 90 additions & 61 deletions apps/wing-console/console/ui/src/layout/default-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { EdgeMetadata } from "../ui/edge-metadata.js";
import { Explorer } from "../ui/explorer.js";
import { ResourceMetadata } from "../ui/resource-metadata.js";

import { Header } from "./header.js";
import { StatusBar } from "./status-bar.js";
import { TermsAndConditionsModal } from "./terms-and-conditions-modal.js";
import { useLayout } from "./use-layout.js";
Expand All @@ -31,10 +30,6 @@ export interface LayoutProps {
}

const defaultLayoutConfig: LayoutConfig = {
header: {
hide: false,
showThemeToggle: true,
},
leftPanel: {
components: [
{
Expand All @@ -54,13 +49,16 @@ const defaultLayoutConfig: LayoutConfig = {
},
statusBar: {
hide: false,
showThemeToggle: false,
showThemeToggle: true,
},
errorScreen: {
position: "default",
displayTitle: true,
displayLinks: true,
},
panels: {
rounded: true,
},
};

export const DefaultLayout = ({
Expand Down Expand Up @@ -112,7 +110,7 @@ export const DefaultLayout = ({
return termsConfig.data.requireAcceptTerms && !termsConfig.data.accepted;
}, [termsConfig.data]);

const layout = useMemo(() => {
const layout: LayoutConfig = useMemo(() => {
return {
...defaultLayoutConfig,
...layoutConfig,
Expand Down Expand Up @@ -237,24 +235,20 @@ export const DefaultLayout = ({
license={termsConfig.data?.license ?? ""}
/>
)}

<div className={classNames(USE_EXTERNAL_THEME_COLOR, "fixed inset-0")}>
<div className={classNames("w-full h-full", theme.bg2)} />
</div>

<div
data-testid="default-layout"
className={classNames(
"h-full flex flex-col select-none",
theme.bg3,
theme.text2,
showTerms && "blur-sm",
"gap-1 pt-1",
)}
>
{!layout.header?.hide && (
<div className={classNames(USE_EXTERNAL_THEME_COLOR)}>
<Header
title={wingfile.data ?? ""}
showThemeToggle={layout.header?.showThemeToggle}
/>
</div>
)}

{cloudAppState === "error" &&
layout.errorScreen?.position === "default" && (
<div className="flex-1 flex relative">
Expand All @@ -269,7 +263,7 @@ export const DefaultLayout = ({

{renderApp && (
<>
<div className="flex-1 flex relative">
<div className="flex-1 flex relative gap-1">
{loading && (
<div
className={classNames(
Expand All @@ -288,39 +282,58 @@ export const DefaultLayout = ({
<RightResizableWidget
className={classNames(
USE_EXTERNAL_THEME_COLOR,
theme.border3,
"h-full flex flex-col w-80 min-w-[10rem] min-h-[10rem] border-r",
"h-full flex flex-col w-80 min-w-[10rem] min-h-[10rem] gap-1",
)}
>
{layout.leftPanel?.components.map(
(component: LayoutComponent, index: number) => {
const panelComponent = renderLayoutComponent(component);
const panelComponent = (
<div
className={classNames(
layout.panels?.rounded &&
"rounded-lg overflow-hidden",
index === 0 && "flex grow",
index > 0 && "h-full",
)}
>
{renderLayoutComponent(component)}
</div>
);

if (index > 0) {
return (
<TopResizableWidget
key={component.type}
className={classNames(
theme.border3,
"h-1/3 border-t",
)}
className="h-1/3"
>
{panelComponent}
</TopResizableWidget>
);
}
return panelComponent;
return (
<div
key={index}
className={classNames(
"flex grow",
layout.panels?.rounded &&
"rounded-lg overflow-hidden",
)}
>
{panelComponent}
</div>
);
},
)}
</RightResizableWidget>
)}

<div className="flex-1 flex flex-col">
<div className="flex-1 flex">
<div className="flex-1 flex gap-1">
<div
className={classNames(
"flex-1 flex flex-col",
USE_EXTERNAL_THEME_COLOR,
layout.panels?.rounded && "rounded-lg overflow-hidden",
)}
data-testid="map-view"
>
Expand All @@ -337,34 +350,41 @@ export const DefaultLayout = ({

<LeftResizableWidget
className={classNames(
USE_EXTERNAL_THEME_COLOR,
theme.border3,
"flex-shrink w-80 min-w-[10rem] border-l z-10",
theme.bg4,
theme.border4,
"flex-shrink w-80 min-w-[10rem] z-10",
)}
>
{metadata.data && (
<ResourceMetadata
node={metadata.data.node}
inbound={metadata.data.inbound}
outbound={metadata.data.outbound}
onConnectionNodeClick={(path) => {
expand(path);
setSelectedItems([path]);
}}
/>
)}
{selectedEdgeId && edgeMetadata.data && (
<EdgeMetadata
source={edgeMetadata.data.source}
target={edgeMetadata.data.target}
inflights={edgeMetadata.data.inflights}
onConnectionNodeClick={(path) => {
expand(path);
setSelectedItems([path]);
}}
/>
)}
<div
className={classNames(
"w-full h-full relative",
USE_EXTERNAL_THEME_COLOR,
theme.bg4,
layout.panels?.rounded && "rounded-lg overflow-hidden",
)}
>
{metadata.data && (
<ResourceMetadata
node={metadata.data.node}
inbound={metadata.data.inbound}
outbound={metadata.data.outbound}
onConnectionNodeClick={(path) => {
expand(path);
setSelectedItems([path]);
}}
/>
)}
{selectedEdgeId && edgeMetadata.data && (
<EdgeMetadata
source={edgeMetadata.data.source}
target={edgeMetadata.data.target}
inflights={edgeMetadata.data.inflights}
onConnectionNodeClick={(path) => {
expand(path);
setSelectedItems([path]);
}}
/>
)}
</div>
</LeftResizableWidget>
</div>
</div>
Expand All @@ -374,18 +394,28 @@ export const DefaultLayout = ({
<TopResizableWidget
className={classNames(
USE_EXTERNAL_THEME_COLOR,
theme.border3,
"border-t relative flex",
theme.bg3,
"relative flex",
theme.text2,
"min-h-[5rem]",
"gap-1",
(layout.bottomPanel?.size === "small" && "h-[8rem]") ||
"h-[15rem]",
)}
>
{layout.bottomPanel?.components?.map(
(component: LayoutComponent, index: number) => {
const panelComponent = renderLayoutComponent(component);
const panelComponent = (
<div
className={classNames(
layout.panels?.rounded &&
"rounded-lg overflow-hidden",
"flex grow",
)}
>
{renderLayoutComponent(component)}
</div>
);

if (
layout.bottomPanel?.components?.length &&
layout.bottomPanel.components.length > 1 &&
Expand All @@ -395,8 +425,7 @@ export const DefaultLayout = ({
<RightResizableWidget
key={component.type}
className={classNames(
theme.border3,
"h-full w-1/4 flex flex-col min-w-[10rem] min-h-[10rem] border-r",
"h-full w-1/4 flex flex-col min-w-[10rem] min-h-[10rem]",
)}
>
{panelComponent}
Expand All @@ -417,8 +446,8 @@ export const DefaultLayout = ({
<div className="fixed bottom-0 max-h-[80vh] w-full z-50">
<TopResizableWidget
className={classNames(
theme.border3,
"border-t absolute flex",
theme.border4,
"absolute flex",
theme.bg3,
theme.text2,
"min-h-[5rem] h-[30rem]",
Expand Down
Loading

0 comments on commit 19d8565

Please sign in to comment.