Skip to content

Commit

Permalink
Merge pull request #352 from dolthub/liuliu/connections-pages
Browse files Browse the repository at this point in the history
Web: connections page redesign
  • Loading branch information
liuliu-dev authored Jan 23, 2025
2 parents 46e4cdf + 8df872e commit 27ab2db
Show file tree
Hide file tree
Showing 16 changed files with 341 additions and 224 deletions.
3 changes: 1 addition & 2 deletions web/renderer/components/CreateDatabase/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
import useMutation from "@hooks/useMutation";
import { database } from "@lib/urls";
import { AiOutlinePlusCircle } from "@react-icons/all-files/ai/AiOutlinePlusCircle";
import { AiOutlinePlus } from "@react-icons/all-files/ai/AiOutlinePlus";
import cx from "classnames";
import { useRouter } from "next/router";
import { SyntheticEvent, useState } from "react";
Expand Down Expand Up @@ -56,7 +55,7 @@ export default function CreateDatabase(props: Props) {
onClick={() => setIsOpen(true)}
className={cx(css.createDB, props.buttonClassName)}
>
{props.showText ? <AiOutlinePlus /> : <AiOutlinePlusCircle />}
{!props.showText && <AiOutlinePlusCircle />}
{props.showText && <span className={css.text}>Create database</span>}
</Button.Link>
<ModalOuter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,62 @@ import { getDatabaseType } from "@components/DatabaseTypeLabel";
import { Button, ErrorMsg, Loader } from "@dolthub/react-components";
import { DatabaseConnectionFragment } from "@gen/graphql-types";
import { IoMdClose } from "@react-icons/all-files/io/IoMdClose";
import Image from "next/legacy/image";
import cx from "classnames";
import { DatabaseTypeLabel } from "@components/ConnectionsAndDatabases/DatabaseTypeLabel";
import useAddConnection from "./useAddConnection";
import css from "./index.module.css";

type Props = {
conn: DatabaseConnectionFragment;
onDeleteClicked?: (n: string) => void;
onDeleteClicked: (n: string) => void;
borderClassName: string;
shorterLine: boolean;
};

export default function Item({ conn, onDeleteClicked }: Props) {
export default function Item({
conn,
onDeleteClicked,
borderClassName,
shorterLine,
}: Props) {
const { onAdd, err, loading } = useAddConnection(conn);

const type = getDatabaseType(conn.type ?? undefined, !!conn.isDolt);
return (
<>
<li key={conn.name} className={css.connection}>
<Button.Link onClick={onAdd}>{conn.name}</Button.Link>
<span className={css.right}>
<DatabaseTypeLabel conn={conn} />
{onDeleteClicked && (
<Button.Link onClick={() => onDeleteClicked(conn.name)}>
<li key={conn.name} className={css.connectionContainer}>
<div
className={cx(css.line, css[borderClassName], {
[css.shorterLine]: shorterLine,
})}
/>
<div className={css.connection}>
<div className={cx(css.left, css[type.toLowerCase()])}>
<Image
src="/images/database-icon.png"
alt="DatabaseIcon"
height={51}
width={51}
/>
</div>
<div className={css.right}>
<Button.Link
onClick={() => onDeleteClicked(conn.name)}
className={css.delete}
>
<IoMdClose />
</Button.Link>
)}
</span>
<div className={css.typeAndName}>
<DatabaseTypeLabel conn={conn} />
<Button.Link onClick={onAdd} className={css.name}>
{conn.name}
</Button.Link>
</div>
</div>
</div>
</li>
<Loader loaded={!loading} />
<ErrorMsg err={err} className={css.err} />
</>
);
}

type LabelProps = {
conn: DatabaseConnectionFragment;
};

export function DatabaseTypeLabel({ conn }: LabelProps) {
const type = getDatabaseType(conn.type ?? undefined, !!conn.isDolt);
return <span className={cx(css.label, css[type.toLowerCase()])}>{type}</span>;
}
Original file line number Diff line number Diff line change
@@ -1,55 +1,145 @@
.whiteContainer {
@apply max-w-xl w-full border rounded-lg py-10 px-16 bg-white mx-auto;
.outer {
@apply max-w-5xl mt-16 mb-10 flex items-center relative w-fit;
}

.options {
@apply my-6;

ul {
@apply mb-8;
.text {
@apply absolute top-0 left-0;
h1 {
@apply text-left;
}
p {
@apply max-w-md text-lg my-4;
}
a {
@apply text-[#FF8964];
}
a:hover {
@apply text-coral-400;
}
}

.connections {
@apply flex items-center;
}

.outerEllipse {
background: radial-gradient(
circle,
rgba(239, 242, 243, 0.3) 0%,
rgba(25, 46, 61, 0.12) 100%
);
@apply w-32 h-32 rounded-full z-10 flex justify-center items-center flex-shrink-0;
}

.innerEllipse {
background: radial-gradient(
circle,
rgba(239, 242, 243, 0.6) 0%,
rgba(25, 46, 61, 0.24) 100%
);
@apply w-24 h-24 rounded-full z-20 flex justify-center items-center;
}

.dLogo {
@apply w-16 h-16 z-30;
}

.dLogo::after {
content: "";
@apply w-[46%] border-t border-stone-100 inline-block align-middle relative;
}

.connectionContainer {
@apply flex relative;
}

.line {
@apply w-16 h-32 absolute;
}

.shorterLine {
@apply h-20;
}

.roundedTop {
@apply border-l-2 border-t-2 border-white rounded-tl-[2rem] top-14;
}

.roundedBottom {
@apply border-l-2 border-b-2 border-white rounded-bl-[2rem] bottom-14;
}

.straightLine {
@apply border-b-2 border-white;
bottom: calc(3.75rem - 1px);
}

.connection {
@apply my-3 border rounded py-1.5 px-3 flex justify-between;
@apply my-3 border rounded flex w-80 h-24 ml-16;

button {
@apply text-base;
}
}

.left {
@apply w-24 flex justify-center items-center rounded-l;
}

.dolt {
background: linear-gradient(#0dc1a0 0%, #29e3c1 100%);
}

.mysql {
background: linear-gradient(#084550 0%, #00758f 100%);
}

.doltgresql {
background: linear-gradient(#d34f26 0%, #ff8964 100%);
}

.postgresql {
background: linear-gradient(#286288 0%, #367faf 100%);
}

.right {
@apply flex;
@apply relative w-56 bg-white rounded-r;
}

.err {
@apply text-center;
.delete {
@apply absolute top-2 right-2 text-coral-400;
}

.newConnection {
@apply flex items-center px-4;
.delete:hover {
@apply text-[#FF8964];
}

svg {
@apply mr-2;
}
.err {
@apply text-center;
}

.label {
@apply text-sm w-24 rounded-full flex items-center justify-center mr-5;
.leftLine {
@apply w-36 border-t-2 border-white absolute left-24;
}

.mysql {
@apply text-[#00758f] bg-[#00758f]/20;
.rightLine {
@apply w-28 border-t-2 border-white;
}

.dolt {
@apply bg-mint-50 text-green-500;
.newConnection {
@apply flex items-center px-8 h-10 bg-coral-400 ml-28 min-w-40;
&:hover {
@apply bg-[#FF8964];
}
}

.doltgresql {
@apply bg-orange-50 text-orange-500;
.typeAndName {
@apply pl-2 h-full flex flex-col justify-center items-start;
}

.postgresql {
@apply bg-[#0064a5]/20 text-[#0064a5];
.name {
@apply pl-4 pt-2 text-sky-400;
}
.label {
@apply text-sm;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
useRemoveConnectionMutation,
} from "@gen/graphql-types";
import { useRouter } from "next/router";
import { AiOutlinePlus } from "@react-icons/all-files/ai/AiOutlinePlus";
import DoltLink from "@components/links/DoltLink";
import DoltgresLink from "@components/links/DoltgresLink";
import { useState } from "react";
import { newConnection } from "@lib/urls";
import Item from "./Item";
Expand All @@ -31,34 +32,73 @@ export default function ExistingConnections(props: Props) {
router.push(href, as).catch(console.error);
};

const halfHeight = Math.floor(props.connections.length / 2) * 5;
const marginTop = halfHeight < 10 ? `${12 - halfHeight}rem` : "0";

return (
<div className={css.whiteContainer}>
<h3>Connections</h3>
<div className={css.options}>
<div className={css.outer}>
<div className={css.text}>
<h1>Connections</h1>
<p>
Connect the workbench to any MySQL or PostgreSQL compatible database.
Use <DoltLink /> or <DoltgresLink /> to unlock version control
features.
</p>
</div>
<div className={css.connections} style={{ marginTop }}>
<div className={css.outerEllipse}>
<div className={css.innerEllipse}>
<img
src="/images/d-large-logo.png"
alt="Dolt Logo"
className={css.dLogo}
/>
<div className={css.leftLine} />
</div>
</div>
<Button className={css.newConnection} onClick={onClick}>
Add connection
</Button>
<div className={css.rightLine} />
<ul>
{props.connections.map(conn => (
{props.connections.map((conn, i) => (
<Item
conn={conn}
key={conn.name}
onDeleteClicked={onDeleteClicked}
borderClassName={getBorderLineClassName(
props.connections.length,
i,
)}
shorterLine={props.connections.length === 2}
/>
))}
</ul>
<DeleteModal
isOpen={deleteModalOpen}
setIsOpen={setDeleteModalOpen}
asset="connection"
assetId={connectionNameToDelete}
mutationProps={{
hook: useRemoveConnectionMutation,
variables: { name: connectionNameToDelete },
refetchQueries: [{ query: StoredConnectionsDocument }],
}}
/>
<Button className={css.newConnection} onClick={onClick}>
<AiOutlinePlus /> New connection
</Button>
</div>
<DeleteModal
isOpen={deleteModalOpen}
setIsOpen={setDeleteModalOpen}
asset="connection"
assetId={connectionNameToDelete}
mutationProps={{
hook: useRemoveConnectionMutation,
variables: { name: connectionNameToDelete },
refetchQueries: [{ query: StoredConnectionsDocument }],
}}
/>
</div>
);
}

function getBorderLineClassName(n: number, ind: number): string {
if (n % 2 === 0) {
return ind < n / 2 ? "roundedTop" : "roundedBottom";
}
if (ind < Math.floor(n / 2)) {
return "roundedTop";
}
if (ind > Math.floor(n / 2)) {
return "roundedBottom";
}
return "straightLine";
}
Loading

0 comments on commit 27ab2db

Please sign in to comment.