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

feat: zustand state management ✨♻️ #78

Merged
merged 6 commits into from
Aug 5, 2024
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
5 changes: 5 additions & 0 deletions .changeset/few-eggs-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tablex/core": patch
---

Use zustand for managing dialogs/sheets state, hence decoupling code.
3 changes: 2 additions & 1 deletion apps/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"react-resizable-panels": "^2.0.19",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.22.4"
"zod": "^3.22.4",
"zustand": "^4.5.4"
},
"devDependencies": {
"@tanstack/router-devtools": "^1.34.7",
Expand Down
12 changes: 2 additions & 10 deletions apps/core/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ use tauri_specta::{collect_commands, collect_events, StaticCollection};
use tx_keybindings::{
ensure_keybindings_file_exist, get_keybindings_file_path, Keybinding, KEYBINDINGS_FILE_NAME,
};
use tx_lib::events::{
CommandPaletteOpen, ConnectionsChanged, MetaXDialogOpen, SQLDialogOpen, TableContentsChanged,
};
use tx_lib::events::{ConnectionsChanged, TableContentsChanged};
use tx_settings::{
ensure_settings_file_exist, get_settings_file_path, Settings, SETTINGS_FILE_NAME,
};
Expand Down Expand Up @@ -90,13 +88,7 @@ fn main() {
update_row,
get_fk_relations
])
.events(collect_events![
ConnectionsChanged,
TableContentsChanged,
CommandPaletteOpen,
MetaXDialogOpen,
SQLDialogOpen,
])
.events(collect_events![ConnectionsChanged, TableContentsChanged])
.header("// @ts-nocheck\n");

#[cfg(debug_assertions)]
Expand Down
13 changes: 2 additions & 11 deletions apps/core/src/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,10 @@ try {

export const events = __makeEvents__<{
connectionsChanged: ConnectionsChanged,
tableContentsChanged: TableContentsChanged,
commandPaletteOpen: CommandPaletteOpen,
metaXDialogOpen: MetaXDialogOpen,
sqlDialogOpen: SQLDialogOpen
tableContentsChanged: TableContentsChanged
}>({
connectionsChanged: "connections-changed",
tableContentsChanged: "table-contents-changed",
commandPaletteOpen: "command-palette-open",
metaXDialogOpen: "meta-x-dialog-open",
sqlDialogOpen: "sql-dialog-open"
tableContentsChanged: "table-contents-changed"
})

/** user-defined statics **/
Expand All @@ -162,7 +156,6 @@ export const SETTINGS_FILE_NAME = "settings.json" as const;
/** user-defined types **/

export type ColumnProps = { columnName: string; type: DataType; isNullable: boolean; defaultValue: JsonValue; isPK: boolean; hasFkRelations: boolean }
export type CommandPaletteOpen = null
export type ConfigFile = "settings" | "keybindings"
/**
* Connection Config Stored inside `connections.json` file.
Expand Down Expand Up @@ -203,9 +196,7 @@ export type JsonValue = null | boolean | number | string | JsonValue[] | { [key
*/
export type Keybinding = { shortcuts: string[]; command: KeybindingCommand }
export type KeybindingCommand = Sidebar | Table
export type MetaXDialogOpen = null
export type PaginatedRows = { data: { [key in string]: JsonValue }[]; pageCount: number }
export type SQLDialogOpen = null
/**
* Configuration for the SQL editor.
*/
Expand Down
9 changes: 4 additions & 5 deletions apps/core/src/commands/row.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { commands } from "@/bindings"
import { customToast } from "@/lib/utils"
import type { Row, Table } from "@tanstack/react-table"
import { Dispatch, SetStateAction } from "react"
import toast from "react-hot-toast"

export const createRowCmd = async (
tableName: string,
data: Record<string, any>,
setIsSheetOpen: Dispatch<SetStateAction<boolean>>
toggleSheet: (open: boolean) => void
) => {
const commandResult = await commands.createRow(tableName, data)

customToast(commandResult, () => setIsSheetOpen(false), "create_row")
customToast(commandResult, () => toggleSheet(false), "create_row")
}

export const deleteRowsCmd = async (
Expand Down Expand Up @@ -40,13 +39,13 @@ export const updateRowCmd = async (
pkColName: string,
pkColValue: string | number,
data: Record<string, any>,
setIsSheetOpen: Dispatch<SetStateAction<boolean>>
toggleSheet: (open: boolean) => void
) => {
const command = await commands.updateRow(
tableName,
pkColName,
pkColValue,
data
)
customToast(command, () => setIsSheetOpen(false), "update_row")
customToast(command, () => toggleSheet(false), "update_row")
}
48 changes: 25 additions & 23 deletions apps/core/src/components/dialogs/command-palette-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { commands, events } from "@/bindings"
import { commands } from "@/bindings"
import {
CommandDialog,
CommandEmpty,
Expand All @@ -7,24 +7,28 @@ import {
CommandItem,
CommandList
} from "@/components/ui/command"
import {
useCommandPaletteState,
useMetaXState,
useSqlEditorState
} from "@/state/dialogState"
import { useNavigate } from "@tanstack/react-router"
import hotkeys from "hotkeys-js"
import { FileJson2, FileText, Globe2, Link, Terminal } from "lucide-react"
import { type Dispatch, type SetStateAction, useState } from "react"

const CommandPalette = () => {
const [open, setOpen] = useState(false)
const { isOpen, toggleDialog } = useCommandPaletteState()

hotkeys("ctrl+k,command+k", () => setOpen(true))
hotkeys("ctrl+k,command+k", () => toggleDialog())

return (
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandDialog open={isOpen} onOpenChange={toggleDialog}>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<ConnectionsGroup />
<UtilitiesGroup setOpen={setOpen} />
<ConfigurationGroup setOpen={setOpen} />
<UtilitiesGroup />
<ConfigurationGroup />
</CommandList>
</CommandDialog>
)
Expand All @@ -48,26 +52,26 @@ const ConnectionsGroup = () => {
)
}

const UtilitiesGroup = ({
setOpen
}: {
setOpen: Dispatch<SetStateAction<boolean>>
}) => {
const UtilitiesGroup = () => {
const { toggleDialog: toggleCommandPalette } = useCommandPaletteState()
const { toggleDialog: toggleMetaXDialog } = useMetaXState()
const { toggleDialog: toggleSqlEditor } = useSqlEditorState()

return (
<CommandGroup heading="Utilities">
<CommandItem
onSelect={() => {
setOpen(false)
events.metaXDialogOpen.emit()
toggleCommandPalette()
toggleMetaXDialog()
}}
>
<FileText className="h-4 w-4" />
Show API Docs
</CommandItem>
<CommandItem
onSelect={() => {
setOpen(false)
events.sqlDialogOpen.emit()
toggleCommandPalette()
toggleSqlEditor()
}}
>
<Terminal className="h-4 w-4" />
Expand All @@ -77,17 +81,15 @@ const UtilitiesGroup = ({
)
}

const ConfigurationGroup = ({
setOpen
}: {
setOpen: Dispatch<SetStateAction<boolean>>
}) => {
const ConfigurationGroup = () => {
const { toggleDialog } = useCommandPaletteState()

return (
<CommandGroup heading="Configuration">
<CommandItem
onSelect={async () => {
commands.openInExternalEditor("settings")
setOpen(false)
toggleDialog()
}}
>
<FileJson2 className="h-4 w-4" />
Expand All @@ -96,7 +98,7 @@ const ConfigurationGroup = ({
<CommandItem
onSelect={async () => {
commands.openInExternalEditor("keybindings")
setOpen(false)
toggleDialog()
}}
>
<FileJson2 className="h-4 w-4" />
Expand Down
9 changes: 3 additions & 6 deletions apps/core/src/components/dialogs/metax-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import { events } from "@/bindings"
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle
} from "@/components/ui/dialog"
import { TooltipProvider } from "@/components/ui/tooltip"
import { useMetaXState } from "@/state/dialogState"
import { open as openInBrowser } from "@tauri-apps/plugin-shell"
import { Globe, PlayCircle } from "lucide-react"
import { useState } from "react"
import CustomTooltip from "../custom-tooltip"

const MetaXDialog = () => {
const [open, setOpen] = useState(false)

events.metaXDialogOpen.listen(() => setOpen(true))
const { isOpen, toggleDialog } = useMetaXState()

return (
<Dialog open={open} onOpenChange={setOpen}>
<Dialog open={isOpen} onOpenChange={toggleDialog}>
<DialogContent onOpenAutoFocus={(e) => e.preventDefault()}>
<DialogHeader>
<DialogTitle>Navigate to your liking</DialogTitle>
Expand Down
23 changes: 5 additions & 18 deletions apps/core/src/components/dialogs/sql-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { commands, events, JsonValue, Result } from "@/bindings"
import { commands, JsonValue, Result } from "@/bindings"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent } from "@/components/ui/dialog"
import {
Expand All @@ -17,21 +17,16 @@ import {
import { TooltipProvider } from "@/components/ui/tooltip"
import { useSettingsManager } from "@/settings/manager"

import { useSqlEditorState } from "@/state/dialogState"
import { Editor, type OnMount } from "@monaco-editor/react"
import {
type Dispatch,
type SetStateAction,
useEffect,
useRef,
useState
} from "react"
import { type Dispatch, type SetStateAction, useRef, useState } from "react"
import CustomTooltip from "../custom-tooltip"

type RawQueryResult = Result<{ [x: string]: JsonValue }[], string>
type MonakoEditor = Parameters<OnMount>[0]

const SQLDialog = () => {
const [open, setOpen] = useState(false)
const { isOpen, toggleDialog } = useSqlEditorState()
const [queryResult, setQueryResult] = useState<RawQueryResult>()
const [editorMounted, setEditorMounted] = useState(false)
const editorRef = useRef<MonakoEditor>()
Expand All @@ -44,16 +39,8 @@ const SQLDialog = () => {
editorRef.current = editor
}

useEffect(() => {
const unlisten = events.sqlDialogOpen.listen(() => setOpen(true))

return () => {
unlisten.then((f) => f())
}
})

return (
<Dialog open={open} onOpenChange={setOpen}>
<Dialog open={isOpen} onOpenChange={toggleDialog}>
<DialogContent className="h-5/6 w-5/6 max-w-full p-0">
<div className="flex flex-col overflow-auto">
<ResizablePanelGroup direction="vertical">
Expand Down
23 changes: 8 additions & 15 deletions apps/core/src/components/sheets/create-row-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import {
FormMessage
} from "@/components/ui/form"
import { useGetGeneralColsData } from "@/hooks/row"
import { useCreateRowSheetState } from "@/state/sheetState"
import { zodResolver } from "@hookform/resolvers/zod"
import { Plus } from "lucide-react"
import { useState, type Dispatch, type SetStateAction } from "react"
import { useForm } from "react-hook-form"
import toast from "react-hot-toast"
import { z } from "zod"
Expand All @@ -33,27 +33,24 @@ type AddRowBtnProps = {
}

const AddRowBtn = ({ tableName }: AddRowBtnProps) => {
const [open, setOpen] = useState(false)
const { isOpen, toggleSheet } = useCreateRowSheetState()
return (
<TooltipProvider>
<Sheet open={open} onOpenChange={setOpen}>
<Sheet open={isOpen} onOpenChange={toggleSheet}>
<SheetTrigger>
<CustomTooltip
className="absolute bottom-0 left-0 m-4 rounded-full bg-zinc-900 p-1"
side="right"
content="Add new row"
>
<Plus
className="h-3 w-3 lg:h-4 lg:w-4"
onClick={() => setOpen(true)}
/>
<Plus className="h-3 w-3 lg:h-4 lg:w-4" />
</CustomTooltip>
</SheetTrigger>
<SheetContent className="overflow-y-auto">
<SheetHeader className="mb-4">
<SheetTitle>Add new row</SheetTitle>
</SheetHeader>
<AddRowForm setOpenSheet={setOpen} tableName={tableName} />
<AddRowForm tableName={tableName} />
</SheetContent>
</Sheet>
</TooltipProvider>
Expand All @@ -62,12 +59,8 @@ const AddRowBtn = ({ tableName }: AddRowBtnProps) => {

export default AddRowBtn

type AddRowFormProps = {
setOpenSheet: Dispatch<SetStateAction<boolean>>
tableName: string
}

const AddRowForm = ({ setOpenSheet, tableName }: AddRowFormProps) => {
const AddRowForm = ({ tableName }: { tableName: string }) => {
const { toggleSheet } = useCreateRowSheetState()
const {
"0": {
data: zodSchema,
Expand Down Expand Up @@ -95,7 +88,7 @@ const AddRowForm = ({ setOpenSheet, tableName }: AddRowFormProps) => {
return toast.error(columnsPropsError!.message, { id: "get_zod_schema" })

const onSubmit = async (values: z.infer<typeof zodSchema>) => {
await createRowCmd(tableName, values, setOpenSheet)
await createRowCmd(tableName, values, toggleSheet)
}
return (
<Form {...form}>
Expand Down
Loading
Loading