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: added connections and databases selector, changed theme color #302

Merged
merged 44 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c5fd504
Merge branch 'liuliu/add-custom-title-bar' into liuliu/web-nav-dropdown
liuliu-dev Nov 20, 2024
0c61823
wip
liuliu-dev Nov 20, 2024
8a51cbb
conn and db list, todo: ui on click, reset, default on open
liuliu-dev Nov 21, 2024
d8272a2
use current as default, reset db
liuliu-dev Nov 22, 2024
e10306e
remove breadcrumbs for app, todo:fix lint
liuliu-dev Nov 22, 2024
bb7938e
mobile, gradient, ui fixes
liuliu-dev Nov 22, 2024
b1b57c5
show connections link before database page
liuliu-dev Nov 22, 2024
68696d9
feedback wip
liuliu-dev Nov 25, 2024
f65f9d9
move to middle, fix long name, same db name issues
liuliu-dev Nov 26, 2024
74024a1
click outside works
liuliu-dev Nov 27, 2024
b20259b
color, weight, top
liuliu-dev Nov 27, 2024
bd50529
wip
liuliu-dev Dec 6, 2024
a30dc4a
web and app top nav
liuliu-dev Dec 6, 2024
c0625dc
dropdown wip
liuliu-dev Dec 6, 2024
dce6e2e
Merge remote-tracking branch 'origin/main' into liuliu/web-nav-dropdown
liuliu-dev Dec 11, 2024
65411ec
popup ui
liuliu-dev Dec 11, 2024
4d108ba
mobile wip
liuliu-dev Dec 11, 2024
9f5d54a
plus icon
liuliu-dev Dec 12, 2024
cbb0254
views, definitions
liuliu-dev Dec 12, 2024
498749d
colors
liuliu-dev Dec 12, 2024
9c5b32f
label
liuliu-dev Dec 16, 2024
e3196ff
Merge branch 'liuliu/web-nav-dropdown' into liuliu/left-nav-ui
liuliu-dev Dec 16, 2024
7d08936
table, view, definition list
liuliu-dev Dec 16, 2024
55d76a3
hide icons, bottom, scroll
liuliu-dev Dec 17, 2024
488af3f
conflict
liuliu-dev Dec 30, 2024
76bb6d3
add min window size, web app nav
liuliu-dev Dec 30, 2024
bfc9566
ci
liuliu-dev Dec 30, 2024
2b7418b
mobile fix
liuliu-dev Dec 30, 2024
c522458
Merge branch 'liuliu/web-nav-dropdown' into liuliu/left-nav-ui
liuliu-dev Dec 31, 2024
7a8dbc1
selectors
liuliu-dev Dec 31, 2024
2ba37df
buttons ui
liuliu-dev Jan 2, 2025
af12a83
viewing
liuliu-dev Jan 2, 2025
c4362ea
Merge branch 'liuliu/web-nav-dropdown' into liuliu/left-nav-ui
liuliu-dev Jan 2, 2025
eadfde7
dropdown updates
liuliu-dev Jan 3, 2025
a1ca0ad
Merge remote-tracking branch 'origin/main' into liuliu/web-nav-dropdown
liuliu-dev Jan 3, 2025
7fbe51b
Merge branch 'liuliu/web-nav-dropdown' into liuliu/left-nav-ui
liuliu-dev Jan 3, 2025
1a5c3b0
Merge pull request #317 from dolthub/liuliu/left-nav-ui
liuliu-dev Jan 3, 2025
c5abb76
color
liuliu-dev Jan 3, 2025
6f92205
refresh
liuliu-dev Jan 3, 2025
f4b758e
active, font size, lowercase
liuliu-dev Jan 3, 2025
26af6ad
url
liuliu-dev Jan 3, 2025
8d84e7c
branch label fixes in mysql and postgres, reset button tooltip, conne…
liuliu-dev Jan 15, 2025
50d72fb
ci fix, nodrag
liuliu-dev Jan 15, 2025
977d422
showlabel for all non-dolt, clearstore,selected conn
liuliu-dev Jan 15, 2025
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
10 changes: 10 additions & 0 deletions web/README.desktop-app.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
## Run the desktop app in dev mode:

1. Rebuild `graphql-server` (if changes were made):

```bash
# in graphql-server
yarn build
```

2.Start the desktop app:

```bash
# in web
yarn dev:app
```

Expand Down
10 changes: 4 additions & 6 deletions web/main/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,9 @@ app.on("ready", async () => {
mainWindow = createWindow("main", {
width: 1400,
height: 900,
minHeight: 600,
minWidth: 600,
titleBarStyle: process.platform === "darwin" ? "hiddenInset" : undefined,
titleBarOverlay: process.platform === "darwin",
titleBarOverlay:
process.platform === "darwin" ? { height: HEADER_HEIGHT } : undefined,
trafficLightPosition: {
x: 20,
y: HEADER_HEIGHT / 2 - MACOS_TRAFFIC_LIGHTS_HEIGHT / 2,
Expand All @@ -142,9 +141,7 @@ app.on("ready", async () => {
Menu.setApplicationMenu(initMenu(mainWindow, isProd));
setupTitleBarClickMac();
createGraphqlSeverProcess();
mainWindow?.webContents.executeJavaScript(
` console.error('for mac nav:', ${process.env.NEXT_PUBLIC_FOR_MAC_NAV})`,
);

await waitForGraphQLServer("http://localhost:9002/graphql");

if (isProd) {
Expand All @@ -163,6 +160,7 @@ app.on("ready", async () => {

return { action: "deny" };
});
mainWindow.setMinimumSize(1080, 780);

// hit when clicking <a href/> with no target
// optionally redirect to browser
Expand Down
1 change: 0 additions & 1 deletion web/main/helpers/create-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export const createWindow = (
};

state = ensureVisibleOnSomeDisplay(restore());

const win = new BrowserWindow({
...state,
...options,
Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"autoprefixer": "^10.4.19",
"babel-jest": "^29.7.0",
"cssnano": "^7.0.6",
"electron": "^31.0.1",
"electron": "33.2.1",
"electron-builder": "^25.1.8",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
Expand Down
54 changes: 54 additions & 0 deletions web/renderer/components/ConnectionsAndDatabases/ConnectionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
DatabaseConnection,
DatabaseConnectionFragment,
} from "@gen/graphql-types";
import { MdRemoveRedEye } from "@react-icons/all-files/md/MdRemoveRedEye";
import { FaChevronRight } from "@react-icons/all-files/fa/FaChevronRight";
import { Button } from "@dolthub/react-components";
import { excerpt } from "@dolthub/web-utils";
import cx from "classnames";
import { StateType } from "./useSelectedConnection";
import { DatabaseTypeLabel } from "./DatabaseTypeLabel";
import css from "./index.module.css";

type Props = {
conn: DatabaseConnectionFragment;
state: StateType;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to pass the whole state? Seems like you only need connection (which could use a clearer name to distinguish from conn)?

onSelected: (conn: DatabaseConnection) => void;
currentConnection: DatabaseConnection;
};
export default function ConnectionItem({
conn,
state,
onSelected,
currentConnection,
}: Props) {
return (
<Button.Link
key={conn.name}
className={cx(css.connection, {
[css.selected]: state.connection.name === conn.name,
})}
onClick={async () => onSelected(conn)}
>
<div className={css.connectionTop}>
<div className={css.nameAndLabel}>
<span className={css.connectionName}>{excerpt(conn.name, 16)}</span>
<DatabaseTypeLabel conn={conn} />
{conn.name === currentConnection.name && (
<MdRemoveRedEye className={css.viewing} />
)}
</div>
<FaChevronRight className={css.arrow} />
</div>
<div className={css.connectionUrl}>
{excerpt(getHostAndPort(conn.connectionUrl), 42)}
</div>
</Button.Link>
);
}

function getHostAndPort(connectionString: string) {
const url = new URL(connectionString);
return `${url.hostname}:${url.port}`;
}
77 changes: 77 additions & 0 deletions web/renderer/components/ConnectionsAndDatabases/DatabaseItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Button, ErrorMsg, Loader } from "@dolthub/react-components";
import { MdRemoveRedEye } from "@react-icons/all-files/md/MdRemoveRedEye";
import {
DatabaseConnectionFragment,
DatabaseType,
useAddDatabaseConnectionMutation,
useResetDatabaseMutation,
} from "@gen/graphql-types";
import useMutation from "@hooks/useMutation";
import { useRouter } from "next/router";
import { maybeDatabase } from "@lib/urls";
import { excerpt } from "@dolthub/web-utils";
import cx from "classnames";
import css from "./index.module.css";

type Props = {
db: string;
conn: DatabaseConnectionFragment;
currentConnection: DatabaseConnectionFragment;
currentDatabase: string;
};

export default function DatabaseItem({
db,
conn,
currentConnection,
currentDatabase,
}: Props) {
const {
mutateFn: resetDB,
loading,
err,
} = useMutation({
hook: useResetDatabaseMutation,
});
const router = useRouter();
const [addDb, res] = useAddDatabaseConnectionMutation();

const onClick = async (databaseName: string) => {
const addedDb = await addDb({ variables: conn });
await res.client.clearStore();
if (!addedDb.data) {
return;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should clearStore only be called if addedDb.data exists?

if (conn.type === DatabaseType.Postgres) {
await resetDB({ variables: { newDatabase: databaseName } });
}
const { href, as } = maybeDatabase(databaseName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why maybeDatabase? Shouldn't databaseName always exist?

router.push(href, as).catch(console.error);
};

if (loading) {
return <Loader loaded={!loading} />;
}

if (err) {
return <ErrorMsg err={err} />;
}
const dbName = excerpt(db, 32);
if (db === currentDatabase && conn.name === currentConnection.name) {
return (
<span className={css.dbItem}>
{dbName}
<MdRemoveRedEye className={css.viewing} />
</span>
);
}
return (
<Button.Link
className={cx(css.dbItem, css.link)}
onClick={async () => onClick(db)}
>
{dbName}
</Button.Link>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { getDatabaseType } from "@components/DatabaseTypeLabel";
import { DatabaseConnectionFragment } from "@gen/graphql-types";
import css from "./index.module.css";

type Props = {
conn: DatabaseConnectionFragment;
};

export function DatabaseTypeLabel({ conn }: Props) {
const type = getDatabaseType(conn.type ?? undefined, !!conn.isDolt);
switch (type) {
case "Dolt":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is type not an enum?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it's a string returned from getDatabaseType

return (
<span className={css.label}>
<img src="/images/dolt-logo.png" alt="Dolt" />
</span>
);
case "MySQL":
return (
<span className={css.label}>
<img src="/images/mysql-logo.png" alt="MySQL" />
</span>
);
case "PostgreSQL":
return (
<span className={css.label}>
<img src="/images/postgres-logo.png" alt="PostgreSQL" />
</span>
);
case "DoltgreSQL":
return (
<span className={css.label}>
<img src="/images/doltgres-logo.png" alt="DoltgreSQL" />
</span>
);
default:
return <span className={css.label}>{type}</span>;
}
}
72 changes: 72 additions & 0 deletions web/renderer/components/ConnectionsAndDatabases/Popup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { DatabaseConnection, DatabaseType } from "@gen/graphql-types";
import { DatabaseParams } from "@lib/params";
import cx from "classnames";
import Link from "@components/links/Link";
import { ErrorMsg, SmallLoader } from "@dolthub/react-components";
import CreateDatabase from "@components/CreateDatabase";
import { FiTool } from "@react-icons/all-files/fi/FiTool";
import { StateType } from "./useSelectedConnection";
import DatabaseItem from "./DatabaseItem";
import css from "./index.module.css";
import ConnectionItem from "./ConnectionItem";

type Props = {
params: DatabaseParams;
currentConnection: DatabaseConnection;
onSelected: (conn: DatabaseConnection) => void;
storedConnections: DatabaseConnection[];
state: StateType;
};

export default function Popup({
params,
currentConnection,
onSelected,
storedConnections,
state,
}: Props) {
return (
<div className={css.container}>
<div className={css.top}>
<div className={cx(css.header, css.left)}>
<span>CONNECTIONS</span>
<Link href="/connections">
<FiTool className={css.wrench} />
</Link>
</div>
<div className={cx(css.header, css.right)}>
<span>DATABASES</span>
<CreateDatabase
isPostgres={currentConnection.type === DatabaseType.Postgres}
/>
</div>
</div>
<div className={css.middle}>
<div className={css.left}>
{storedConnections.map(conn => (
<ConnectionItem
key={conn.name}
conn={conn}
currentConnection={currentConnection}
onSelected={onSelected}
state={state}
/>
))}
</div>
<div className={css.right}>
{state.loading && <SmallLoader loaded={!state.loading} />}
{state.databases.map(db => (
<DatabaseItem
key={db}
db={db}
conn={state.connection}
currentConnection={currentConnection}
currentDatabase={params.databaseName}
/>
))}
<ErrorMsg err={state.err} />
</div>
</div>
</div>
);
}
Loading