Skip to content
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

Web: connections page redesign #352

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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