Skip to content

Commit

Permalink
change: empty view design
Browse files Browse the repository at this point in the history
  • Loading branch information
macjuul committed May 2, 2024
1 parent 6efdfa4 commit e17a123
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/assets/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,6 @@ input::-ms-clear {

:root[data-mantine-color-scheme="dark"] {
--surrealist-divider-color: var(--mantine-color-slate-9);
--surrealist-glow: 0 6px 25px -4px rgba(186, 0, 171, 1), 0 3px 15px rgba(186, 0, 171, 0.5);
--surrealist-glow: 0 5px 20px -4px rgba(186, 0, 171, 1), 0 3px 15px rgba(186, 0, 171, 0.5);
--mantine-color-body: var(--mantine-color-slate-8);
}
15 changes: 10 additions & 5 deletions src/components/CodePreview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import classes from "./style.module.scss";
import clsx from "clsx";
import dedent from "dedent";
import { surrealql } from "codemirror-surrealql";
import { Compartment, EditorState, Extension } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { ActionIcon, Box, CopyButton, Paper, PaperProps, Text } from "@mantine/core";
import { ReactNode, useEffect, useRef } from "react";
import { ReactNode, useEffect, useMemo, useRef } from "react";
import { useIsLight } from "~/hooks/theme";
import { colorTheme } from "~/util/editor/extensions";
import { Icon } from "../Icon";
Expand Down Expand Up @@ -36,12 +37,16 @@ export function CodePreview({
const editorRef = useRef<EditorRef>();
const ref = useRef<HTMLDivElement | null>(null);

const code = useMemo(() => {
return dedent(value);
}, [value]);

useEffect(() => {
const config = new Compartment();
const configExt = config.of(extensions || surrealql());

const initialState = EditorState.create({
doc: value,
doc: code,
extensions: [
configExt,
colorTheme(),
Expand All @@ -68,20 +73,20 @@ export function CodePreview({
useEffect(() => {
const { editor } = editorRef.current!;

if (value == editor.state.doc.toString()) {
if (code == editor.state.doc.toString()) {
return;
}

const transaction = editor.state.update({
changes: {
from: 0,
to: editor.state.doc.length,
insert: value
insert: code
}
});

editor.dispatch(transaction);
}, [value]);
}, [code]);

useEffect(() => {
const { editor, config } = editorRef.current!;
Expand Down
10 changes: 8 additions & 2 deletions src/components/CodePreview/style.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.root :global(.cm-editor) {
outline: none;
.root {
:global(.cm-editor) {
outline: none;
}

:global(.cm-line) {
padding-left: 0;
}
}
52 changes: 52 additions & 0 deletions src/components/Introduction/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Center, Paper, Stack, Title, Text, Group } from "@mantine/core";
import { CodePreview } from "../CodePreview";
import { PropsWithChildren } from "react";
import { Icon } from "../Icon";

export interface IntroductionProps {
title: string;
icon: string;
snippet?: string;
}

export function Introduction({
title,
icon,
snippet,
children
}: PropsWithChildren<IntroductionProps>) {
return (
<Center h="100%" flex={1}>
<Paper
w={450}
style={{ overflow: "hidden" }}
>
<Stack p="xl" gap="xl">
<Group>
<Icon path={icon} size={1.35} />
<Title c="bright">
{title}
</Title>
</Group>
{children}
</Stack>
{snippet && (
<Paper
p="xl"
bg="slate.7"
radius={0}
>
<Text c="bright" fz={18} fw={600} mb="md">
Using the CLI
</Text>
<CodePreview
bg="transparent"
p={0}
value={snippet}
/>
</Paper>
)}
</Paper>
</Center>
);
}
3 changes: 1 addition & 2 deletions src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function Sidebar({
const items = row.flatMap((id) => {
const info = VIEW_MODES[id];

return (!info || !info.hidden?.(flags) !== true) ? [] : [info];
return (!info || !info.disabled?.(flags) !== true) ? [] : [info];
});

return items.length > 0 ? [items] : [];
Expand Down Expand Up @@ -128,7 +128,6 @@ export function Sidebar({
icon={info.anim || info.icon}
withTooltip={!expandable}
onClick={() => setViewMode(info.id)}
disabled={info.disabled?.(flags)}
onMouseEnter={expandedHandle.open}
/>
</Group>
Expand Down
10 changes: 2 additions & 8 deletions src/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import queryIcon from "~/assets/animation/query.json";
import explorerIcon from "~/assets/animation/explorer.json";
import designerIcon from "~/assets/animation/designer.json";
import authIcon from "~/assets/animation/auth.json";
import { getConnection } from "./util/connection";

import {
AuthMode,
Expand Down Expand Up @@ -139,19 +138,14 @@ export const VIEW_MODES: Record<ViewMode, ViewInfo> = {
name: "Models",
icon: iconModel,
desc: "Upload and manage machine learning models",
hidden: (flags) => flags.models_view === false,
disabled: (flags) => {
const protocol = getConnection()?.connection?.protocol;

return flags.models_view !== "force" && (!protocol || !ML_SUPPORTED.has(protocol));
},
disabled: (flags) => !flags.models_view,
},
documentation: {
id: "documentation",
name: "API Docs",
icon: iconAPI,
desc: "View the database schema and documentation",
hidden: (flags) => !flags.apidocs_view,
disabled: (flags) => !flags.apidocs_view,
},
};

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/panels.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { useLayoutEffect, useRef, useState } from "react";

/**
* Compute a minimum panel width based on a fixed pixel size.
Expand All @@ -10,7 +10,7 @@ export function usePanelMinSize(minSizePx: number) {
const groupRef = useRef<HTMLDivElement|null>(null);
const [minSize, setMinSize] = useState(0);

useEffect(() => {
useLayoutEffect(() => {
const panelGroup = groupRef.current;

if (!panelGroup) {
Expand Down
2 changes: 1 addition & 1 deletion src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export interface ViewInfo {
icon: string;
anim?: any;
desc: string;
hidden?: FeatureCondition;
disabled?: FeatureCondition;

Check failure on line 323 in src/types.tsx

View workflow job for this annotation

GitHub Actions / check_and_test

Duplicate identifier 'disabled'.

Check failure on line 323 in src/types.tsx

View workflow job for this annotation

GitHub Actions / Build Web (18)

Duplicate identifier 'disabled'.
disabled?: FeatureCondition;

Check failure on line 324 in src/types.tsx

View workflow job for this annotation

GitHub Actions / check_and_test

Duplicate identifier 'disabled'.

Check failure on line 324 in src/types.tsx

View workflow job for this annotation

GitHub Actions / Build Web (18)

Duplicate identifier 'disabled'.
}

Expand Down
57 changes: 37 additions & 20 deletions src/views/explorer/ExplorerView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import { useState } from "react";
import { TablesPane } from "../TablesPane";
import { CreatorDrawer } from "../CreatorDrawer";
import { useDisclosure } from "@mantine/hooks";
import { Box, Button, Center, Group, Stack } from "@mantine/core";
import { Box, Button, Group, Text } from "@mantine/core";
import { DisconnectedEvent } from "~/util/global-events";
import { useEventSubscription } from "~/hooks/event";
import { useStable } from "~/hooks/stable";
import { useIntent } from "~/hooks/url";
import { Icon } from "~/components/Icon";
import { iconExplorer, iconPlus } from "~/util/icons";
import { iconExplorer, iconOpen, iconPlus } from "~/util/icons";
import { useInterfaceStore } from "~/stores/interface";
import { useViewEffect } from "~/hooks/view";
import { syncDatabaseSchema } from "~/util/schema";
import { Panel, PanelGroup } from "react-resizable-panels";
import { PanelDragger } from "~/components/Pane/dragger";
import { usePanelMinSize } from "~/hooks/panels";
import { Introduction } from "~/components/Introduction";
import { adapter } from "~/adapter";

export function ExplorerView() {
const { openTableCreator } = useInterfaceStore.getState();
Expand Down Expand Up @@ -66,24 +68,39 @@ export function ExplorerView() {
onCreateRecord={openCreator}
/>
) : (
<Center h="100%">
<Stack
align="center"
justify="center"
>
<Icon path={iconExplorer} size={2.5} />
Select a table to view or edit
<Group>
<Button
variant="light"
leftSection={<Icon path={iconPlus} />}
onClick={openTableCreator}
>
Create table
</Button>
</Group>
</Stack>
</Center>
<Introduction
title="Explorer"
icon={iconExplorer}
snippet={`
-- Declare a new table
DEFINE TABLE person;
-- Fetch table records
SELECT * FROM person;
`}
>
<Text>
The explorer view provides an easy way to browse your tables and records without writing any queries.
</Text>
<Group>
<Button
flex={1}
variant="gradient"
leftSection={<Icon path={iconPlus} />}
onClick={openTableCreator}
>
Create table
</Button>
<Button
flex={1}
color="slate"
rightSection={<Icon path={iconOpen} />}
onClick={() => adapter.openUrl("https://surrealdb.com/docs/surrealdb/surrealql/statements/define/table")}
>
Learn more
</Button>
</Group>
</Introduction>
)}
</Panel>
</PanelGroup>
Expand Down
60 changes: 40 additions & 20 deletions src/views/functions/FunctionsView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Box, Button, Center, Group, Modal, Stack, Text, TextInput } from "@mantine/core";
import { Box, Button, Group, Modal, Stack, Text, TextInput } from "@mantine/core";
import { FunctionsPanel } from "../FunctionsPanel";
import { EditorPanel } from "../EditorPanel";
import { ChangeEvent, useRef, useState } from "react";
import { Icon } from "~/components/Icon";
import { iconChevronRight, iconFunction, iconPlus } from "~/util/icons";
import { iconChevronRight, iconFunction, iconOpen, iconPlus } from "~/util/icons";
import { useStable } from "~/hooks/stable";
import { useDisclosure } from "@mantine/hooks";
import { ModalTitle } from "~/components/ModalTitle";
Expand All @@ -19,6 +19,8 @@ import { executeQuery } from "~/connection";
import { Panel, PanelGroup } from "react-resizable-panels";
import { PanelDragger } from "~/components/Pane/dragger";
import { usePanelMinSize } from "~/hooks/panels";
import { adapter } from "~/adapter";
import { Introduction } from "~/components/Introduction";

export function FunctionsView() {
const functions = useSchema()?.functions ?? [];
Expand Down Expand Up @@ -141,24 +143,42 @@ export function FunctionsView() {
onDelete={removeFunction}
/>
) : (
<Center h="100%">
<Stack
align="center"
justify="center"
>
<Icon path={iconFunction} size={2.5} />
Select a function to view or edit
<Group>
<Button
variant="light"
leftSection={<Icon path={iconPlus} />}
onClick={openCreator}
>
Create function
</Button>
</Group>
</Stack>
</Center>
<Introduction
title="Functions"
icon={iconFunction}
snippet={`
-- Define your functions with ease
DEFINE FUNCTION fn::greet($name: string) {
RETURN "Hello, " + $name + "!";
};
-- And invoke them from any query
RETURN fn::greet("Tobie");
`}
>
<Text>
Schema functions allow you to define stored procedures that can be reused throughout your queries.
This view allows you to effortlessly create and manage your functions.
</Text>
<Group>
<Button
flex={1}
variant="gradient"
leftSection={<Icon path={iconPlus} />}
onClick={openCreator}
>
Create function
</Button>
<Button
flex={1}
color="slate"
rightSection={<Icon path={iconOpen} />}
onClick={() => adapter.openUrl("https://surrealdb.com/docs/surrealdb/surrealql/statements/define/function")}
>
Learn more
</Button>
</Group>
</Introduction>
)}
</Panel>
</PanelGroup>
Expand Down
Loading

0 comments on commit e17a123

Please sign in to comment.