Skip to content

Commit

Permalink
feat: add table schema tab content
Browse files Browse the repository at this point in the history
  • Loading branch information
itsmadhusudhan committed Mar 2, 2024
1 parent 5d45d17 commit e93adb6
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 80 deletions.
19 changes: 10 additions & 9 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
'react-refresh/only-export-components': [
'warn',
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/no-explicit-any": "off",
},
}
};
2 changes: 1 addition & 1 deletion src/modules/editor/QueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useRef } from "react";
import { EditorView, basicSetup } from "codemirror";
import { sql } from "@codemirror/lang-sql";

import { resultStore } from "./data/store";
import { resultStore } from "./data/resultStore";

const QueryEditor = () => {
const editorRef = useRef<HTMLDivElement>(null);
Expand Down
4 changes: 2 additions & 2 deletions src/modules/editor/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TableRow,
} from "@/components/table";

import { useResultStore } from "./data/store";
import { useResultStore } from "./data/resultStore";

const Results = () => {
const [state] = useResultStore();
Expand All @@ -18,7 +18,7 @@ const Results = () => {
if (state.isLoading) {
return (
<div className="flex items-center justify-center h-[calc(100%-3rem)]">
<Loader2 />
<Loader2 className="animate-spin" />
</div>
);
}
Expand Down
39 changes: 10 additions & 29 deletions src/modules/editor/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/tabs";

import { useSetResultStore, useSqlStore } from "./data/store";
import SavedQueries from "./tabs/SavedQueries";
import SchemaTable from "./tabs/SchemaTable";

const Sidebar = () => {
const { state } = useSqlStore();
const setResultState = useSetResultStore();

return (
<div className="w-64 min-w-16 border-r overflow-hidden h-full select-none hidden md:block">
<div className="p-5">SQL Editor</div>
<Tabs defaultValue="saved" className="h-calc(100%-64px)">
<Tabs defaultValue="saved" className="h-[calc(100%-64px)]">
<div className="p-5 flex justify-center border-b">
<TabsList className="w-full">
<TabsTrigger value="saved">Saved</TabsTrigger>
Expand All @@ -20,31 +18,14 @@ const Sidebar = () => {
value="saved"
className="h-[calc(100%-85px)] overflow-y-auto"
>
{state.saved.map((query) => (
<div
key={query.id}
className=" px-4 py-4 border-b cursor-pointer hover:bg-muted last:border-b-0"
onClick={() => {
setResultState({
pendingQuery: query.query,
queryName: query.name,
});

const event = new CustomEvent("query", {
detail: {
pendingQuery: query.query,
queryName: query.name,
},
});

window.dispatchEvent(event);
}}
>
{query.name}
</div>
))}
<SavedQueries />
</TabsContent>
<TabsContent
value="tables"
className="h-[calc(100%-85px)] overflow-y-auto"
>
<SchemaTable />
</TabsContent>
<TabsContent value="password">Change your password here.</TabsContent>
</Tabs>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/modules/editor/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import memoize from "memoize";
import { Button } from "@/components/button";

import { respository } from "@/db/respository";
import { ResultState, resultStore, useResultStore } from "../data/store";
import { ResultState, resultStore, useResultStore } from "../data/resultStore";

const counter = (state: ResultState) => {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,5 @@
import { useSyncExternalStore } from "react";

import { createStore, useStore } from "@/core/store";

export const sqlStore = createStore({
saved: [
{
id: "1",
name: "Select Books",
query: "SELECT * FROM books;",
},
{
id: "2",
name: "Select Authors",
query: "SELECT * FROM authors;",
},
{
id: "3",
name: "Insert Authors",
query: "Insert into authors (first_name,last_name) values ('Madhu','R');",
},
],
});

export const useSqlStore = () => {
const state = useSyncExternalStore(
(cb) => {
return sqlStore.subscribe(cb);
},
() => sqlStore.getState()
);

return {
state,
setState: sqlStore.setState,
};
};

export type ResultState = {
data: Record<string, unknown>[] | string;
isLoading: boolean;
Expand Down
33 changes: 33 additions & 0 deletions src/modules/editor/data/sqlStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createStore, useStore } from "@/core/store";

export type SqlState = {
saved: {
id: string;
name: string;
query: string;
}[];
};

export const sqlStore = createStore<SqlState>({
saved: [
{
id: "1",
name: "Select Books",
query: "SELECT * FROM books;",
},
{
id: "2",
name: "Select Authors",
query: "SELECT * FROM authors;",
},
{
id: "3",
name: "Insert Authors",
query: "Insert into authors (first_name,last_name) values ('Madhu','R');",
},
],
});

export const useSqlStore = () => {
return useStore<SqlState>(sqlStore);
};
25 changes: 25 additions & 0 deletions src/modules/editor/data/useSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import alasql from "alasql";

import { tableSchemas } from "@/db/seed";

type SchemaState = {
columns: {
columnid: string;
dbtypeid: string;
}[];
table: {
tableid: string;
};
};

type Result = ReturnType<typeof alasql.parse> & {
statements: SchemaState[];
};

export const useSchema = () => {
const result = alasql.parse(tableSchemas.create.join(";")) as Result;

const state = result.statements as SchemaState[];

return state;
};
14 changes: 12 additions & 2 deletions src/modules/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { lazy } from "react";
import { Suspense, lazy } from "react";
import { Loader2 } from "lucide-react";

import Results from "./Results";
import Sidebar from "./Sidebar";
import Header from "./components/Header";
Expand All @@ -12,7 +14,15 @@ const Layout = () => {
<Sidebar />
<div className="h-full overflow-hidden">
<Header />
<QueryEditor />
<Suspense
fallback={
<div className="flex h-full items-center justify-center">
<Loader2 className="animate-spin" />
</div>
}
>
<QueryEditor />
</Suspense>
</div>
</div>
<Results />
Expand Down
37 changes: 37 additions & 0 deletions src/modules/editor/tabs/SavedQueries.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useSetResultStore } from "../data/resultStore";
import { useSqlStore } from "../data/sqlStore";

const SavedQueries = () => {
const [state] = useSqlStore();
const setResultState = useSetResultStore();

return (
<div>
{state.saved.map((query) => (
<div
key={query.id}
className=" px-4 py-4 border-b cursor-pointer hover:bg-muted last:border-b-0"
onClick={() => {
setResultState({
pendingQuery: query.query,
queryName: query.name,
});

const event = new CustomEvent("query", {
detail: {
pendingQuery: query.query,
queryName: query.name,
},
});

window.dispatchEvent(event);
}}
>
{query.name}
</div>
))}
</div>
);
};

export default SavedQueries;
40 changes: 40 additions & 0 deletions src/modules/editor/tabs/SchemaTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useSchema } from "../data/useSchema";

const SchemaTable = () => {
const statements = useSchema();

return (
<div className="p-5">
{statements.map((statement) => {
return (
<div key={statement.table.tableid}>
<details className="mb-4">
<summary className="font-medium cursor-pointer">
{statement.table.tableid}
</summary>
<ul className="px-4">
{statement.columns.map((column) => {
return (
<li
key={column.columnid}
className="flex justify-between items-center"
>
<span className="text-neutral-500">
{column.columnid}
</span>
<span className="text-neutral-500">
{column.dbtypeid}
</span>
</li>
);
})}
</ul>
</details>
</div>
);
})}
</div>
);
};

export default SchemaTable;

0 comments on commit e93adb6

Please sign in to comment.